1 /* $Id: teximage.c,v 1.91 2001/03/30 21:12:15 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 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
)
573 img
->TexFormat
= &_mesa_null_texformat
;
574 img
->FetchTexel
= NULL
;
575 img
->IsCompressed
= 0;
576 img
->CompressedSize
= 0;
581 * Initialize basic fields of the gl_texture_image struct.
584 init_teximage_fields(GLcontext
*ctx
,
585 struct gl_texture_image
*img
,
586 GLsizei width
, GLsizei height
, GLsizei depth
,
587 GLint border
, GLenum internalFormat
)
590 img
->Format
= _mesa_base_tex_format( ctx
, internalFormat
);
591 img
->IntFormat
= internalFormat
;
592 img
->Border
= border
;
594 img
->Height
= height
;
596 img
->WidthLog2
= logbase2(width
- 2 * border
);
597 if (height
== 1) /* 1-D texture */
600 img
->HeightLog2
= logbase2(height
- 2 * border
);
601 if (depth
== 1) /* 2-D texture */
604 img
->DepthLog2
= logbase2(depth
- 2 * border
);
605 img
->Width2
= 1 << img
->WidthLog2
;
606 img
->Height2
= 1 << img
->HeightLog2
;
607 img
->Depth2
= 1 << img
->DepthLog2
;
608 img
->MaxLog2
= MAX2(img
->WidthLog2
, img
->HeightLog2
);
609 img
->IsCompressed
= is_compressed_format(ctx
, internalFormat
);
615 * Test glTexImage[123]D() parameters for errors.
617 * dimensions - must be 1 or 2 or 3
618 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
621 texture_error_check( GLcontext
*ctx
, GLenum target
,
622 GLint level
, GLint internalFormat
,
623 GLenum format
, GLenum type
,
625 GLint width
, GLint height
,
626 GLint depth
, GLint border
)
631 if (dimensions
== 1) {
632 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_1D
);
633 if (target
!= GL_TEXTURE_1D
&& !isProxy
) {
634 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
638 else if (dimensions
== 2) {
639 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_2D
||
640 target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
);
641 if (target
!= GL_TEXTURE_2D
&& !isProxy
&&
642 !(ctx
->Extensions
.ARB_texture_cube_map
&&
643 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
644 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
645 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
649 else if (dimensions
== 3) {
650 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_3D
);
651 if (target
!= GL_TEXTURE_3D
&& !isProxy
) {
652 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
657 _mesa_problem( ctx
, "bad dims in texture_error_check" );
662 if (border
!= 0 && border
!= 1) {
665 sprintf(message
, "glTexImage%dD(border=%d)", dimensions
, border
);
666 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
672 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
673 || logbase2( width
- 2 * border
) < 0) {
676 sprintf(message
, "glTexImage%dD(width=%d)", dimensions
, width
);
677 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
683 if (dimensions
>= 2) {
684 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
685 || logbase2( height
- 2 * border
) < 0) {
688 sprintf(message
, "glTexImage%dD(height=%d)", dimensions
, height
);
689 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
695 /* For cube map, width must equal height */
696 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
697 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
698 if (width
!= height
) {
700 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
707 if (dimensions
>= 3) {
708 if (depth
< 2 * border
|| depth
> 2 + ctx
->Const
.MaxTextureSize
709 || logbase2( depth
- 2 * border
) < 0) {
712 sprintf(message
, "glTexImage3D(depth=%d)", depth
);
713 _mesa_error( ctx
, GL_INVALID_VALUE
, message
);
720 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
723 sprintf(message
, "glTexImage%dD(level=%d)", dimensions
, level
);
724 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
729 /* For cube map, width must equal height */
730 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
731 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
732 if (width
!= height
) {
733 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
738 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
742 sprintf(message
, "glTexImage%dD(internalFormat=0x%x)", dimensions
,
744 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
749 if (!is_compressed_format( ctx
, internalFormat
) &&
750 !_mesa_is_legal_format_and_type( format
, type
)) {
751 /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
752 * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
756 sprintf(message
, "glTexImage%dD(format or type)", dimensions
);
757 _mesa_error(ctx
, GL_INVALID_OPERATION
, message
);
762 /* if we get here, the parameters are OK */
769 * Test glTexSubImage[123]D() parameters for errors.
771 * dimensions - must be 1 or 2 or 3
772 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
775 subtexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
776 GLenum target
, GLint level
,
777 GLint xoffset
, GLint yoffset
, GLint zoffset
,
778 GLint width
, GLint height
, GLint depth
,
779 GLenum format
, GLenum type
)
781 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
782 struct gl_texture_image
*destTex
;
784 if (dimensions
== 1) {
785 if (target
!= GL_TEXTURE_1D
) {
786 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(target)" );
790 else if (dimensions
== 2) {
791 if (ctx
->Extensions
.ARB_texture_cube_map
) {
792 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
793 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
794 target
!= GL_TEXTURE_2D
) {
795 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
799 else if (target
!= GL_TEXTURE_2D
) {
800 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
804 else if (dimensions
== 3) {
805 if (target
!= GL_TEXTURE_3D
) {
806 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3D(target)" );
811 _mesa_problem( ctx
, "bad dims in texture_error_check" );
815 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
817 sprintf(message
, "glTexSubImage2D(level=%d)", level
);
818 _mesa_error(ctx
, GL_INVALID_ENUM
, message
);
824 sprintf(message
, "glTexSubImage%dD(width=%d)", dimensions
, width
);
825 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
828 if (height
< 0 && dimensions
> 1) {
830 sprintf(message
, "glTexSubImage%dD(height=%d)", dimensions
, height
);
831 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
834 if (depth
< 0 && dimensions
> 2) {
836 sprintf(message
, "glTexSubImage%dD(depth=%d)", dimensions
, depth
);
837 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
841 destTex
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
844 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glTexSubImage2D");
848 if (xoffset
< -((GLint
)destTex
->Border
)) {
849 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset)");
852 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
853 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset+width)");
856 if (dimensions
> 1) {
857 if (yoffset
< -((GLint
)destTex
->Border
)) {
858 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset)");
861 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
862 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset+height)");
866 if (dimensions
> 2) {
867 if (zoffset
< -((GLint
)destTex
->Border
)) {
868 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset)");
871 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+ destTex
->Border
)) {
872 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset+depth)");
877 if (!is_compressed_format(ctx
, destTex
->IntFormat
) &&
878 !_mesa_is_legal_format_and_type(format
, type
)) {
880 sprintf(message
, "glTexSubImage%dD(format or type)", dimensions
);
881 _mesa_error(ctx
, GL_INVALID_ENUM
, message
);
890 * Test glCopyTexImage[12]D() parameters for errors.
891 * Input: dimensions - must be 1 or 2 or 3
892 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
895 copytexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
896 GLenum target
, GLint level
, GLint internalFormat
,
897 GLint width
, GLint height
, GLint border
)
901 if (dimensions
== 1) {
902 if (target
!= GL_TEXTURE_1D
) {
903 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
907 else if (dimensions
== 2) {
908 if (ctx
->Extensions
.ARB_texture_cube_map
) {
909 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
910 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
911 target
!= GL_TEXTURE_2D
) {
912 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
916 else if (target
!= GL_TEXTURE_2D
) {
917 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
923 if (border
!= 0 && border
!= 1) {
925 sprintf(message
, "glCopyTexImage%dD(border)", dimensions
);
926 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
931 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
932 || logbase2( width
- 2 * border
) < 0) {
934 sprintf(message
, "glCopyTexImage%dD(width=%d)", dimensions
, width
);
935 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
940 if (dimensions
>= 2) {
941 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
942 || logbase2( height
- 2 * border
) < 0) {
944 sprintf(message
, "glCopyTexImage%dD(height=%d)", dimensions
, height
);
945 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
950 /* For cube map, width must equal height */
951 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
952 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
953 if (width
!= height
) {
954 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(width != height)");
960 if (level
< 0 || level
>=ctx
->Const
.MaxTextureLevels
) {
962 sprintf(message
, "glCopyTexImage%dD(level=%d)", dimensions
, level
);
963 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
967 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
970 sprintf(message
, "glCopyTexImage%dD(internalFormat)", dimensions
);
971 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
975 /* if we get here, the parameters are OK */
981 copytexsubimage_error_check( GLcontext
*ctx
, GLuint dimensions
,
982 GLenum target
, GLint level
,
983 GLint xoffset
, GLint yoffset
, GLint zoffset
,
984 GLsizei width
, GLsizei height
)
986 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
987 struct gl_texture_image
*teximage
;
989 if (dimensions
== 1) {
990 if (target
!= GL_TEXTURE_1D
) {
991 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
995 else if (dimensions
== 2) {
996 if (ctx
->Extensions
.ARB_texture_cube_map
) {
997 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
998 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
999 target
!= GL_TEXTURE_2D
) {
1000 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1004 else if (target
!= GL_TEXTURE_2D
) {
1005 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1009 else if (dimensions
== 3) {
1010 if (target
!= GL_TEXTURE_3D
) {
1011 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3D(target)" );
1016 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1018 sprintf(message
, "glCopyTexSubImage%dD(level=%d)", dimensions
, level
);
1019 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1025 sprintf(message
, "glCopyTexSubImage%dD(width=%d)", dimensions
, width
);
1026 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1029 if (dimensions
> 1 && height
< 0) {
1031 sprintf(message
, "glCopyTexSubImage%dD(height=%d)", dimensions
, height
);
1032 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1036 teximage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1039 sprintf(message
, "glCopyTexSubImage%dD(undefined texture)", dimensions
);
1040 _mesa_error(ctx
, GL_INVALID_OPERATION
, message
);
1044 if (xoffset
< -((GLint
)teximage
->Border
)) {
1046 sprintf(message
, "glCopyTexSubImage%dD(xoffset=%d)", dimensions
, xoffset
);
1047 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1050 if (xoffset
+ width
> (GLint
) (teximage
->Width
+ teximage
->Border
)) {
1052 sprintf(message
, "glCopyTexSubImage%dD(xoffset+width)", dimensions
);
1053 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1056 if (dimensions
> 1) {
1057 if (yoffset
< -((GLint
)teximage
->Border
)) {
1059 sprintf(message
, "glCopyTexSubImage%dD(yoffset=%d)", dimensions
, yoffset
);
1060 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1063 /* NOTE: we're adding the border here, not subtracting! */
1064 if (yoffset
+ height
> (GLint
) (teximage
->Height
+ teximage
->Border
)) {
1066 sprintf(message
, "glCopyTexSubImage%dD(yoffset+height)", dimensions
);
1067 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1072 if (dimensions
> 2) {
1073 if (zoffset
< -((GLint
)teximage
->Border
)) {
1075 sprintf(message
, "glCopyTexSubImage%dD(zoffset)", dimensions
);
1076 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1079 if (zoffset
> (GLint
) (teximage
->Depth
+ teximage
->Border
)) {
1081 sprintf(message
, "glCopyTexSubImage%dD(zoffset+depth)", dimensions
);
1082 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1087 /* if we get here, the parameters are OK */
1094 _mesa_GetTexImage( GLenum target
, GLint level
, GLenum format
,
1095 GLenum type
, GLvoid
*pixels
)
1097 const struct gl_texture_unit
*texUnit
;
1098 const struct gl_texture_object
*texObj
;
1099 struct gl_texture_image
*texImage
;
1100 GET_CURRENT_CONTEXT(ctx
);
1101 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1103 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1104 _mesa_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
1108 if (_mesa_sizeof_type(type
) <= 0) {
1109 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
1113 if (_mesa_components_in_format(format
) <= 0 ||
1114 format
== GL_STENCIL_INDEX
) {
1115 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
1119 if (!ctx
->Extensions
.EXT_paletted_texture
&& is_index_format(format
)) {
1120 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1123 if (!ctx
->Extensions
.SGIX_depth_texture
&& format
== GL_DEPTH_COMPONENT
) {
1124 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1127 /* XXX what if format/type doesn't match texture format/type? */
1132 texUnit
= &(ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
]);
1133 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1134 if (!texObj
|| is_proxy_target(target
)) {
1135 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)");
1139 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1141 /* invalid mipmap level, not an error */
1145 if (!texImage
->Data
) {
1146 /* no image data, not an error */
1150 if (ctx
->NewState
& _NEW_PIXEL
)
1151 _mesa_update_state(ctx
);
1153 if (is_color_format(format
) &&
1154 ctx
->_ImageTransferState
& IMAGE_CONVOLUTION_BIT
) {
1155 /* convert texture image to GL_RGBA, GL_FLOAT */
1156 GLint width
= texImage
->Width
;
1157 GLint height
= texImage
->Height
;
1158 GLint depth
= texImage
->Depth
;
1160 GLfloat
*tmpImage
, *convImage
;
1161 tmpImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
1163 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
1166 convImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
1169 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
1173 for (img
= 0; img
< depth
; img
++) {
1174 GLint convWidth
, convHeight
;
1176 /* convert texture data to GLfloat/GL_RGBA */
1177 for (row
= 0; row
< height
; row
++) {
1178 GLchan texels
[1 << MAX_TEXTURE_LEVELS
][4];
1180 GLfloat
*dst
= tmpImage
+ row
* width
* 4;
1181 for (col
= 0; col
< width
; col
++) {
1182 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1185 _mesa_unpack_float_color_span(ctx
, width
, GL_RGBA
, dst
,
1186 GL_RGBA
, CHAN_TYPE
, texels
,
1187 &_mesa_native_packing
,
1188 ctx
->_ImageTransferState
& IMAGE_PRE_CONVOLUTION_BITS
,
1193 convHeight
= height
;
1196 if (target
== GL_TEXTURE_1D
) {
1197 if (ctx
->Pixel
.Convolution1DEnabled
) {
1198 _mesa_convolve_1d_image(ctx
, &convWidth
, tmpImage
, convImage
);
1202 if (ctx
->Pixel
.Convolution2DEnabled
) {
1203 _mesa_convolve_2d_image(ctx
, &convWidth
, &convHeight
,
1204 tmpImage
, convImage
);
1206 else if (ctx
->Pixel
.Separable2DEnabled
) {
1207 _mesa_convolve_sep_image(ctx
, &convWidth
, &convHeight
,
1208 tmpImage
, convImage
);
1212 /* pack convolved image */
1213 for (row
= 0; row
< convHeight
; row
++) {
1214 const GLfloat
*src
= convImage
+ row
* convWidth
* 4;
1215 GLvoid
*dest
= _mesa_image_address(&ctx
->Pack
, pixels
,
1216 convWidth
, convHeight
,
1217 format
, type
, img
, row
, 0);
1218 _mesa_pack_float_rgba_span(ctx
, convWidth
,
1219 (const GLfloat(*)[4]) src
,
1220 format
, type
, dest
, &ctx
->Pack
,
1221 ctx
->_ImageTransferState
& IMAGE_POST_CONVOLUTION_BITS
);
1229 /* no convolution, or non-rgba image */
1230 GLint width
= texImage
->Width
;
1231 GLint height
= texImage
->Height
;
1232 GLint depth
= texImage
->Depth
;
1234 for (img
= 0; img
< depth
; img
++) {
1235 for (row
= 0; row
< height
; row
++) {
1236 /* compute destination address in client memory */
1237 GLvoid
*dest
= _mesa_image_address( &ctx
->Unpack
, pixels
,
1238 width
, height
, format
, type
,
1242 if (format
== GL_COLOR_INDEX
) {
1243 GLuint indexRow
[MAX_WIDTH
];
1245 for (col
= 0; col
< width
; col
++) {
1246 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1247 (GLvoid
*) &indexRow
[col
]);
1249 _mesa_pack_index_span(ctx
, width
, type
, dest
,
1250 indexRow
, &ctx
->Pack
,
1251 ctx
->_ImageTransferState
);
1253 else if (format
== GL_DEPTH_COMPONENT
) {
1254 GLfloat depthRow
[MAX_WIDTH
];
1256 for (col
= 0; col
< width
; col
++) {
1257 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1258 (GLvoid
*) &depthRow
[col
]);
1260 _mesa_pack_depth_span(ctx
, width
, dest
, type
,
1261 depthRow
, &ctx
->Pack
);
1264 /* general case: convert row to RGBA format */
1265 GLchan rgba
[MAX_WIDTH
][4];
1267 for (col
= 0; col
< width
; col
++) {
1268 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1269 (GLvoid
*) rgba
[col
]);
1271 _mesa_pack_rgba_span(ctx
, width
, (const GLchan (*)[4])rgba
,
1272 format
, type
, dest
, &ctx
->Pack
,
1273 ctx
->_ImageTransferState
);
1283 * Called from the API. Note that width includes the border.
1286 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
1287 GLsizei width
, GLint border
, GLenum format
,
1288 GLenum type
, const GLvoid
*pixels
)
1290 GLsizei postConvWidth
= width
;
1291 GET_CURRENT_CONTEXT(ctx
);
1292 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1294 if (is_color_format(internalFormat
)) {
1295 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1298 if (target
== GL_TEXTURE_1D
) {
1299 struct gl_texture_unit
*texUnit
;
1300 struct gl_texture_object
*texObj
;
1301 struct gl_texture_image
*texImage
;
1303 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1304 format
, type
, 1, postConvWidth
, 1, 1, border
)) {
1305 return; /* error was recorded */
1308 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1309 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1310 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1313 texImage
= _mesa_alloc_texture_image();
1314 texObj
->Image
[level
] = texImage
;
1316 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
1320 else if (texImage
->Data
) {
1321 /* free the old texture data */
1322 FREE(texImage
->Data
);
1323 texImage
->Data
= NULL
;
1325 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1326 init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1327 border
, internalFormat
);
1329 if (ctx
->NewState
& _NEW_PIXEL
)
1330 _mesa_update_state(ctx
);
1332 ASSERT(ctx
->Driver
.TexImage1D
);
1334 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1335 width
, border
, format
, type
, pixels
,
1336 &ctx
->Unpack
, texObj
, texImage
);
1339 GLubyte
*dummy
= make_null_texture(width
, 1, 1, format
);
1341 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1343 format
, GL_UNSIGNED_BYTE
, dummy
,
1344 &_mesa_native_packing
, texObj
, texImage
);
1349 ASSERT(texImage
->TexFormat
);
1350 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel1D
;
1351 ASSERT(texImage
->FetchTexel
);
1354 texObj
->Complete
= GL_FALSE
;
1355 ctx
->NewState
|= _NEW_TEXTURE
;
1357 else if (target
== GL_PROXY_TEXTURE_1D
) {
1358 /* Proxy texture: check for errors and update proxy state */
1359 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1361 postConvWidth
, 1, 1, border
);
1363 struct gl_texture_unit
*texUnit
;
1364 struct gl_texture_image
*texImage
;
1365 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1366 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1367 init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1368 border
, internalFormat
);
1369 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1370 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1371 internalFormat
, format
, type
,
1372 postConvWidth
, 1, 1, border
);
1375 /* if error, clear all proxy texture image parameters */
1376 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1377 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
1382 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1389 _mesa_TexImage2D( GLenum target
, GLint level
, GLint internalFormat
,
1390 GLsizei width
, GLsizei height
, GLint border
,
1391 GLenum format
, GLenum type
,
1392 const GLvoid
*pixels
)
1394 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1395 GET_CURRENT_CONTEXT(ctx
);
1396 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1398 if (is_color_format(internalFormat
)) {
1399 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1403 if (target
== GL_TEXTURE_2D
||
1404 (ctx
->Extensions
.ARB_texture_cube_map
&&
1405 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1406 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
1407 /* non-proxy target */
1408 struct gl_texture_unit
*texUnit
;
1409 struct gl_texture_object
*texObj
;
1410 struct gl_texture_image
*texImage
;
1412 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1413 format
, type
, 2, postConvWidth
, postConvHeight
,
1415 return; /* error was recorded */
1418 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1419 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1420 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1423 texImage
= _mesa_alloc_texture_image();
1424 set_tex_image(texObj
, target
, level
, texImage
);
1426 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1430 else if (texImage
->Data
) {
1431 /* free the old texture data */
1432 FREE(texImage
->Data
);
1433 texImage
->Data
= NULL
;
1435 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1436 init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
, 1,
1437 border
, internalFormat
);
1439 if (ctx
->NewState
& _NEW_PIXEL
)
1440 _mesa_update_state(ctx
);
1442 ASSERT(ctx
->Driver
.TexImage2D
);
1444 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1445 width
, height
, border
, format
, type
, pixels
,
1446 &ctx
->Unpack
, texObj
, texImage
);
1449 GLubyte
*dummy
= make_null_texture(width
, height
, 1, format
);
1451 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1452 width
, height
, border
,
1453 format
, GL_UNSIGNED_BYTE
, dummy
,
1454 &_mesa_native_packing
, texObj
, texImage
);
1459 ASSERT(texImage
->TexFormat
);
1460 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel2D
;
1461 ASSERT(texImage
->FetchTexel
);
1464 texObj
->Complete
= GL_FALSE
;
1465 ctx
->NewState
|= _NEW_TEXTURE
;
1467 else if (target
== GL_PROXY_TEXTURE_2D
) {
1468 /* Proxy texture: check for errors and update proxy state */
1469 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1471 postConvWidth
, postConvHeight
, 1, border
);
1473 struct gl_texture_unit
*texUnit
;
1474 struct gl_texture_image
*texImage
;
1475 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1476 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1477 init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
, 1,
1478 border
, internalFormat
);
1479 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1480 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1481 internalFormat
, format
, type
,
1482 postConvWidth
, postConvHeight
, 1, border
);
1485 /* if error, clear all proxy texture image parameters */
1486 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1487 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
1492 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1499 * Called by the API or display list executor.
1500 * Note that width and height include the border.
1503 _mesa_TexImage3D( GLenum target
, GLint level
, GLenum internalFormat
,
1504 GLsizei width
, GLsizei height
, GLsizei depth
,
1505 GLint border
, GLenum format
, GLenum type
,
1506 const GLvoid
*pixels
)
1508 GET_CURRENT_CONTEXT(ctx
);
1509 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1511 if (target
== GL_TEXTURE_3D
) {
1512 struct gl_texture_unit
*texUnit
;
1513 struct gl_texture_object
*texObj
;
1514 struct gl_texture_image
*texImage
;
1516 if (texture_error_check(ctx
, target
, level
, (GLint
) internalFormat
,
1517 format
, type
, 3, width
, height
, depth
, border
)) {
1518 return; /* error was recorded */
1521 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1522 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1523 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1526 texImage
= _mesa_alloc_texture_image();
1527 texObj
->Image
[level
] = texImage
;
1529 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
1533 else if (texImage
->Data
) {
1534 FREE(texImage
->Data
);
1535 texImage
->Data
= NULL
;
1537 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1538 init_teximage_fields(ctx
, texImage
, width
, height
, depth
, border
,
1541 if (ctx
->NewState
& _NEW_PIXEL
)
1542 _mesa_update_state(ctx
);
1544 ASSERT(ctx
->Driver
.TexImage3D
);
1546 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, (GLint
) internalFormat
,
1547 width
, height
, depth
, border
,
1548 format
, type
, pixels
,
1549 &ctx
->Unpack
, texObj
, texImage
);
1552 GLubyte
*dummy
= make_null_texture(width
, height
, depth
, format
);
1554 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
,
1555 (GLint
) internalFormat
,
1556 width
, height
, depth
, border
,
1557 format
, GL_UNSIGNED_BYTE
, dummy
,
1558 &_mesa_native_packing
, texObj
, texImage
);
1563 ASSERT(texImage
->TexFormat
);
1564 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel3D
;
1565 ASSERT(texImage
->FetchTexel
);
1568 texObj
->Complete
= GL_FALSE
;
1569 ctx
->NewState
|= _NEW_TEXTURE
;
1571 else if (target
== GL_PROXY_TEXTURE_3D
) {
1572 /* Proxy texture: check for errors and update proxy state */
1573 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1574 format
, type
, 3, width
, height
, depth
, border
);
1576 struct gl_texture_unit
*texUnit
;
1577 struct gl_texture_image
*texImage
;
1578 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1579 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1580 init_teximage_fields(ctx
, texImage
, width
, height
, 1,
1581 border
, internalFormat
);
1582 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1583 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1584 internalFormat
, format
, type
,
1585 width
, height
, depth
, border
);
1588 /* if error, clear all proxy texture image parameters */
1589 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1590 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
1595 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1602 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
1603 GLsizei width
, GLsizei height
, GLsizei depth
,
1604 GLint border
, GLenum format
, GLenum type
,
1605 const GLvoid
*pixels
)
1607 _mesa_TexImage3D(target
, level
, internalFormat
, width
, height
,
1608 depth
, border
, format
, type
, pixels
);
1614 _mesa_TexSubImage1D( GLenum target
, GLint level
,
1615 GLint xoffset
, GLsizei width
,
1616 GLenum format
, GLenum type
,
1617 const GLvoid
*pixels
)
1619 GLsizei postConvWidth
= width
;
1620 struct gl_texture_unit
*texUnit
;
1621 struct gl_texture_object
*texObj
;
1622 struct gl_texture_image
*texImage
;
1623 GET_CURRENT_CONTEXT(ctx
);
1624 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1626 if (ctx
->NewState
& _NEW_PIXEL
)
1627 _mesa_update_state(ctx
);
1629 /* XXX should test internal format */
1630 if (is_color_format(format
)) {
1631 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1634 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
1635 postConvWidth
, 1, 1, format
, type
)) {
1636 return; /* error was detected */
1639 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1640 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1641 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1644 if (width
== 0 || !pixels
)
1645 return; /* no-op, not an error */
1647 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1648 xoffset
+= texImage
->Border
;
1650 ASSERT(ctx
->Driver
.TexSubImage1D
);
1651 (*ctx
->Driver
.TexSubImage1D
)(ctx
, target
, level
, xoffset
, width
,
1652 format
, type
, pixels
, &ctx
->Unpack
,
1654 ctx
->NewState
|= _NEW_TEXTURE
;
1659 _mesa_TexSubImage2D( GLenum target
, GLint level
,
1660 GLint xoffset
, GLint yoffset
,
1661 GLsizei width
, GLsizei height
,
1662 GLenum format
, GLenum type
,
1663 const GLvoid
*pixels
)
1665 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1666 struct gl_texture_unit
*texUnit
;
1667 struct gl_texture_object
*texObj
;
1668 struct gl_texture_image
*texImage
;
1669 GET_CURRENT_CONTEXT(ctx
);
1670 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1672 if (ctx
->NewState
& _NEW_PIXEL
)
1673 _mesa_update_state(ctx
);
1675 /* XXX should test internal format */
1676 if (is_color_format(format
)) {
1677 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1681 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1682 postConvWidth
, postConvHeight
, 1, format
, type
)) {
1683 return; /* error was detected */
1686 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1687 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1688 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1691 if (width
== 0 || height
== 0 || !pixels
)
1692 return; /* no-op, not an error */
1694 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1695 xoffset
+= texImage
->Border
;
1696 yoffset
+= texImage
->Border
;
1698 ASSERT(ctx
->Driver
.TexSubImage2D
);
1699 (*ctx
->Driver
.TexSubImage2D
)(ctx
, target
, level
, xoffset
, yoffset
,
1700 width
, height
, format
, type
, pixels
,
1701 &ctx
->Unpack
, texObj
, texImage
);
1702 ctx
->NewState
|= _NEW_TEXTURE
;
1708 _mesa_TexSubImage3D( GLenum target
, GLint level
,
1709 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1710 GLsizei width
, GLsizei height
, GLsizei depth
,
1711 GLenum format
, GLenum type
,
1712 const GLvoid
*pixels
)
1714 struct gl_texture_unit
*texUnit
;
1715 struct gl_texture_object
*texObj
;
1716 struct gl_texture_image
*texImage
;
1717 GET_CURRENT_CONTEXT(ctx
);
1718 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1720 if (ctx
->NewState
& _NEW_PIXEL
)
1721 _mesa_update_state(ctx
);
1723 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
1724 width
, height
, depth
, format
, type
)) {
1725 return; /* error was detected */
1728 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1729 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1730 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1733 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
1734 return; /* no-op, not an error */
1736 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1737 xoffset
+= texImage
->Border
;
1738 yoffset
+= texImage
->Border
;
1739 zoffset
+= texImage
->Border
;
1741 ASSERT(ctx
->Driver
.TexSubImage3D
);
1742 (*ctx
->Driver
.TexSubImage3D
)(ctx
, target
, level
,
1743 xoffset
, yoffset
, zoffset
,
1744 width
, height
, depth
,
1745 format
, type
, pixels
,
1746 &ctx
->Unpack
, texObj
, texImage
);
1747 ctx
->NewState
|= _NEW_TEXTURE
;
1753 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
1754 GLenum internalFormat
,
1756 GLsizei width
, GLint border
)
1758 struct gl_texture_unit
*texUnit
;
1759 struct gl_texture_object
*texObj
;
1760 struct gl_texture_image
*texImage
;
1761 GLsizei postConvWidth
= width
;
1762 GET_CURRENT_CONTEXT(ctx
);
1763 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1765 if (ctx
->NewState
& _NEW_PIXEL
)
1766 _mesa_update_state(ctx
);
1768 if (is_color_format(internalFormat
)) {
1769 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1772 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
1773 postConvWidth
, 1, border
))
1776 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1777 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1778 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1780 texImage
= _mesa_alloc_texture_image();
1781 set_tex_image(texObj
, target
, level
, texImage
);
1783 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D");
1787 else if (texImage
->Data
) {
1788 /* free the old texture data */
1789 FREE(texImage
->Data
);
1790 texImage
->Data
= NULL
;
1793 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1794 init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1795 border
, internalFormat
);
1798 ASSERT(ctx
->Driver
.CopyTexImage1D
);
1799 (*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
, internalFormat
,
1800 x
, y
, width
, border
);
1802 ASSERT(texImage
->TexFormat
);
1803 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel1D
;
1804 ASSERT(texImage
->FetchTexel
);
1807 texObj
->Complete
= GL_FALSE
;
1808 ctx
->NewState
|= _NEW_TEXTURE
;
1814 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
1815 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1818 struct gl_texture_unit
*texUnit
;
1819 struct gl_texture_object
*texObj
;
1820 struct gl_texture_image
*texImage
;
1821 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1822 GET_CURRENT_CONTEXT(ctx
);
1823 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1825 if (ctx
->NewState
& _NEW_PIXEL
)
1826 _mesa_update_state(ctx
);
1828 if (is_color_format(internalFormat
)) {
1829 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1833 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
1834 postConvWidth
, postConvHeight
, border
))
1837 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1838 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1839 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1841 texImage
= _mesa_alloc_texture_image();
1842 set_tex_image(texObj
, target
, level
, texImage
);
1844 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D");
1848 else if (texImage
->Data
) {
1849 /* free the old texture data */
1850 FREE(texImage
->Data
);
1851 texImage
->Data
= NULL
;
1854 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1855 init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
, 1,
1856 border
, internalFormat
);
1858 ASSERT(ctx
->Driver
.CopyTexImage2D
);
1859 (*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
, internalFormat
,
1860 x
, y
, width
, height
, border
);
1862 ASSERT(texImage
->TexFormat
);
1863 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel2D
;
1864 ASSERT(texImage
->FetchTexel
);
1867 texObj
->Complete
= GL_FALSE
;
1868 ctx
->NewState
|= _NEW_TEXTURE
;
1874 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
1875 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
1877 struct gl_texture_unit
*texUnit
;
1878 struct gl_texture_object
*texObj
;
1879 struct gl_texture_image
*texImage
;
1880 GLsizei postConvWidth
= width
;
1881 GET_CURRENT_CONTEXT(ctx
);
1882 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1884 if (ctx
->NewState
& _NEW_PIXEL
)
1885 _mesa_update_state(ctx
);
1887 /* XXX should test internal format */
1888 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1890 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
1891 xoffset
, 0, 0, postConvWidth
, 1))
1894 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1895 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1896 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1898 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1899 xoffset
+= texImage
->Border
;
1901 ASSERT(ctx
->Driver
.CopyTexSubImage1D
);
1902 (*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
, xoffset
, x
, y
, width
);
1903 ctx
->NewState
|= _NEW_TEXTURE
;
1909 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
1910 GLint xoffset
, GLint yoffset
,
1911 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1913 struct gl_texture_unit
*texUnit
;
1914 struct gl_texture_object
*texObj
;
1915 struct gl_texture_image
*texImage
;
1916 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1917 GET_CURRENT_CONTEXT(ctx
);
1918 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1920 if (ctx
->NewState
& _NEW_PIXEL
)
1921 _mesa_update_state(ctx
);
1923 /* XXX should test internal format */
1924 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
1926 if (copytexsubimage_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1927 postConvWidth
, postConvHeight
))
1930 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1931 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1932 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1934 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1935 xoffset
+= texImage
->Border
;
1936 yoffset
+= texImage
->Border
;
1938 ASSERT(ctx
->Driver
.CopyTexSubImage2D
);
1939 (*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
1940 xoffset
, yoffset
, x
, y
, width
, height
);
1941 ctx
->NewState
|= _NEW_TEXTURE
;
1947 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
1948 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1949 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1951 struct gl_texture_unit
*texUnit
;
1952 struct gl_texture_object
*texObj
;
1953 struct gl_texture_image
*texImage
;
1954 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1955 GET_CURRENT_CONTEXT(ctx
);
1956 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1958 if (ctx
->NewState
& _NEW_PIXEL
)
1959 _mesa_update_state(ctx
);
1961 /* XXX should test internal format */
1962 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
1964 if (copytexsubimage_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
,
1965 zoffset
, postConvWidth
, postConvHeight
))
1968 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1969 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1970 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1972 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1973 xoffset
+= texImage
->Border
;
1974 yoffset
+= texImage
->Border
;
1975 zoffset
+= texImage
->Border
;
1977 ASSERT(ctx
->Driver
.CopyTexSubImage3D
);
1978 (*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
1979 xoffset
, yoffset
, zoffset
,
1980 x
, y
, width
, height
);
1981 ctx
->NewState
|= _NEW_TEXTURE
;
1987 _mesa_CompressedTexImage1DARB(GLenum target
, GLint level
,
1988 GLenum internalFormat
, GLsizei width
,
1989 GLint border
, GLsizei imageSize
,
1992 GET_CURRENT_CONTEXT(ctx
);
1993 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1995 switch (internalFormat
) {
1996 case GL_COMPRESSED_ALPHA_ARB
:
1997 case GL_COMPRESSED_LUMINANCE_ARB
:
1998 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
1999 case GL_COMPRESSED_INTENSITY_ARB
:
2000 case GL_COMPRESSED_RGB_ARB
:
2001 case GL_COMPRESSED_RGBA_ARB
:
2002 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB");
2005 /* silence compiler warning */
2009 if (target
== GL_TEXTURE_1D
) {
2010 struct gl_texture_unit
*texUnit
;
2011 struct gl_texture_object
*texObj
;
2012 struct gl_texture_image
*texImage
;
2014 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2015 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
2016 return; /* error in texture image was detected */
2019 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2020 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2021 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2024 texImage
= _mesa_alloc_texture_image();
2025 texObj
->Image
[level
] = texImage
;
2027 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage1DARB");
2031 else if (texImage
->Data
) {
2032 FREE(texImage
->Data
);
2033 texImage
->Data
= NULL
;
2036 init_teximage_fields(ctx
, texImage
, width
, 1, 1, border
, internalFormat
);
2038 if (ctx
->Extensions
.ARB_texture_compression
) {
2039 ASSERT(ctx
->Driver
.CompressedTexImage1D
);
2040 (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
,
2041 internalFormat
, width
, border
,
2044 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2048 texObj
->Complete
= GL_FALSE
;
2049 ctx
->NewState
|= _NEW_TEXTURE
;
2051 else if (target
== GL_PROXY_TEXTURE_1D
) {
2052 /* Proxy texture: check for errors and update proxy state */
2053 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2054 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
);
2056 struct gl_texture_unit
*texUnit
;
2057 struct gl_texture_image
*texImage
;
2058 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2059 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2060 init_teximage_fields(ctx
, texImage
, width
, 1, 1,
2061 border
, internalFormat
);
2062 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2063 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2064 internalFormat
, GL_NONE
, GL_NONE
,
2065 width
, 1, 1, border
);
2068 /* if error, clear all proxy texture image parameters */
2069 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2070 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
2075 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB(target)" );
2082 _mesa_CompressedTexImage2DARB(GLenum target
, GLint level
,
2083 GLenum internalFormat
, GLsizei width
,
2084 GLsizei height
, GLint border
, GLsizei imageSize
,
2087 GET_CURRENT_CONTEXT(ctx
);
2088 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2090 switch (internalFormat
) {
2091 case GL_COMPRESSED_ALPHA_ARB
:
2092 case GL_COMPRESSED_LUMINANCE_ARB
:
2093 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2094 case GL_COMPRESSED_INTENSITY_ARB
:
2095 case GL_COMPRESSED_RGB_ARB
:
2096 case GL_COMPRESSED_RGBA_ARB
:
2097 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB");
2100 /* silence compiler warning */
2104 if (target
== GL_TEXTURE_2D
||
2105 (ctx
->Extensions
.ARB_texture_cube_map
&&
2106 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2107 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
2108 struct gl_texture_unit
*texUnit
;
2109 struct gl_texture_object
*texObj
;
2110 struct gl_texture_image
*texImage
;
2112 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2113 GL_NONE
, GL_NONE
, 1, width
, height
, 1, border
)) {
2114 return; /* error in texture image was detected */
2117 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2118 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2119 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2122 texImage
= _mesa_alloc_texture_image();
2123 texObj
->Image
[level
] = texImage
;
2125 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
2129 else if (texImage
->Data
) {
2130 FREE(texImage
->Data
);
2131 texImage
->Data
= NULL
;
2134 init_teximage_fields(ctx
, texImage
, width
, height
, 1, border
,
2137 if (ctx
->Extensions
.ARB_texture_compression
) {
2138 ASSERT(ctx
->Driver
.CompressedTexImage2D
);
2139 (*ctx
->Driver
.CompressedTexImage2D
)(ctx
, target
, level
,
2140 internalFormat
, width
, height
,
2141 border
, imageSize
, data
,
2143 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2147 texObj
->Complete
= GL_FALSE
;
2148 ctx
->NewState
|= _NEW_TEXTURE
;
2150 else if (target
== GL_PROXY_TEXTURE_2D
) {
2151 /* Proxy texture: check for errors and update proxy state */
2152 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2153 GL_NONE
, GL_NONE
, 2, width
, height
, 1, border
);
2155 struct gl_texture_unit
*texUnit
;
2156 struct gl_texture_image
*texImage
;
2157 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2158 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2159 init_teximage_fields(ctx
, texImage
, width
, height
, 1,
2160 border
, internalFormat
);
2161 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2162 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2163 internalFormat
, GL_NONE
, GL_NONE
,
2164 width
, height
, 1, border
);
2167 /* if error, clear all proxy texture image parameters */
2168 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2169 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
2174 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB(target)" );
2181 _mesa_CompressedTexImage3DARB(GLenum target
, GLint level
,
2182 GLenum internalFormat
, GLsizei width
,
2183 GLsizei height
, GLsizei depth
, GLint border
,
2184 GLsizei imageSize
, const GLvoid
*data
)
2186 GET_CURRENT_CONTEXT(ctx
);
2187 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2189 switch (internalFormat
) {
2190 case GL_COMPRESSED_ALPHA_ARB
:
2191 case GL_COMPRESSED_LUMINANCE_ARB
:
2192 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2193 case GL_COMPRESSED_INTENSITY_ARB
:
2194 case GL_COMPRESSED_RGB_ARB
:
2195 case GL_COMPRESSED_RGBA_ARB
:
2196 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB");
2199 /* silence compiler warning */
2203 if (target
== GL_TEXTURE_3D
) {
2204 struct gl_texture_unit
*texUnit
;
2205 struct gl_texture_object
*texObj
;
2206 struct gl_texture_image
*texImage
;
2208 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2209 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
)) {
2210 return; /* error in texture image was detected */
2213 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2214 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2215 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2218 texImage
= _mesa_alloc_texture_image();
2219 texObj
->Image
[level
] = texImage
;
2221 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage3DARB");
2225 else if (texImage
->Data
) {
2226 FREE(texImage
->Data
);
2227 texImage
->Data
= NULL
;
2230 init_teximage_fields(ctx
, texImage
, width
, height
, depth
, border
,
2233 if (ctx
->Extensions
.ARB_texture_compression
) {
2234 ASSERT(ctx
->Driver
.CompressedTexImage3D
);
2235 (*ctx
->Driver
.CompressedTexImage3D
)(ctx
, target
, level
,
2237 width
, height
, depth
,
2238 border
, imageSize
, data
,
2240 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2244 texObj
->Complete
= GL_FALSE
;
2245 ctx
->NewState
|= _NEW_TEXTURE
;
2247 else if (target
== GL_PROXY_TEXTURE_3D
) {
2248 /* Proxy texture: check for errors and update proxy state */
2249 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2250 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
);
2252 struct gl_texture_unit
*texUnit
;
2253 struct gl_texture_image
*texImage
;
2254 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2255 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2256 init_teximage_fields(ctx
, texImage
, width
, height
, depth
,
2257 border
, internalFormat
);
2258 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2259 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2260 internalFormat
, GL_NONE
, GL_NONE
,
2261 width
, height
, depth
, border
);
2264 /* if error, clear all proxy texture image parameters */
2265 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2266 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
2271 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB(target)" );
2278 _mesa_CompressedTexSubImage1DARB(GLenum target
, GLint level
, GLint xoffset
,
2279 GLsizei width
, GLenum format
,
2280 GLsizei imageSize
, const GLvoid
*data
)
2282 struct gl_texture_unit
*texUnit
;
2283 struct gl_texture_object
*texObj
;
2284 struct gl_texture_image
*texImage
;
2285 GET_CURRENT_CONTEXT(ctx
);
2286 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2288 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
2289 width
, 1, 1, format
, GL_NONE
)) {
2290 return; /* error was detected */
2293 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2294 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2295 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2298 if (width
== 0 || !data
)
2299 return; /* no-op, not an error */
2301 if (ctx
->Driver
.CompressedTexSubImage1D
) {
2302 (*ctx
->Driver
.CompressedTexSubImage1D
)(ctx
, target
, level
,
2304 format
, imageSize
, data
,
2307 ctx
->NewState
|= _NEW_TEXTURE
;
2312 _mesa_CompressedTexSubImage2DARB(GLenum target
, GLint level
, GLint xoffset
,
2313 GLint yoffset
, GLsizei width
, GLsizei height
,
2314 GLenum format
, GLsizei imageSize
,
2317 struct gl_texture_unit
*texUnit
;
2318 struct gl_texture_object
*texObj
;
2319 struct gl_texture_image
*texImage
;
2320 GET_CURRENT_CONTEXT(ctx
);
2321 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2323 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2324 width
, height
, 1, format
, GL_NONE
)) {
2325 return; /* error was detected */
2328 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2329 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2330 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2333 if (width
== 0 || height
== 0 || !data
)
2334 return; /* no-op, not an error */
2336 if (ctx
->Driver
.CompressedTexSubImage2D
) {
2337 (*ctx
->Driver
.CompressedTexSubImage2D
)(ctx
, target
, level
,
2338 xoffset
, yoffset
, width
, height
,
2339 format
, imageSize
, data
,
2342 ctx
->NewState
|= _NEW_TEXTURE
;
2347 _mesa_CompressedTexSubImage3DARB(GLenum target
, GLint level
, GLint xoffset
,
2348 GLint yoffset
, GLint zoffset
, GLsizei width
,
2349 GLsizei height
, GLsizei depth
, GLenum format
,
2350 GLsizei imageSize
, const GLvoid
*data
)
2352 struct gl_texture_unit
*texUnit
;
2353 struct gl_texture_object
*texObj
;
2354 struct gl_texture_image
*texImage
;
2355 GET_CURRENT_CONTEXT(ctx
);
2356 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2358 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2359 width
, height
, depth
, format
, GL_NONE
)) {
2360 return; /* error was detected */
2363 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2364 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2365 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2368 if (width
== 0 || height
== 0 || depth
== 0 || !data
)
2369 return; /* no-op, not an error */
2371 if (ctx
->Driver
.CompressedTexSubImage3D
) {
2372 (*ctx
->Driver
.CompressedTexSubImage3D
)(ctx
, target
, level
,
2373 xoffset
, yoffset
, zoffset
,
2374 width
, height
, depth
,
2375 format
, imageSize
, data
,
2378 ctx
->NewState
|= _NEW_TEXTURE
;
2383 _mesa_GetCompressedTexImageARB(GLenum target
, GLint level
, GLvoid
*img
)
2385 const struct gl_texture_unit
*texUnit
;
2386 const struct gl_texture_object
*texObj
;
2387 struct gl_texture_image
*texImage
;
2388 GET_CURRENT_CONTEXT(ctx
);
2389 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2391 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
2392 _mesa_error( ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)" );
2396 if (is_proxy_target(target
)) {
2397 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB(target)");
2401 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2402 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2403 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2406 /* invalid mipmap level */
2407 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
2411 if (!texImage
->IsCompressed
) {
2412 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetCompressedTexImageARB");
2419 if (ctx
->Extensions
.ARB_texture_compression
) {
2420 ASSERT(ctx
->Driver
.GetCompressedTexImage
);
2421 (*ctx
->Driver
.GetCompressedTexImage
)(ctx
, target
, level
, img
, texObj
,