1 /* $Id: teximage.c,v 1.95 2001/05/24 14:47:56 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"
44 #include "swrast/s_span.h" /* XXX SWRAST hack */
51 * Mesa's native texture datatype is GLchan. Native formats are
52 * GL_ALPHA, GL_LUMINANCE, GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, GL_RGBA,
54 * Device drivers are free to implement any internal format they want.
59 static void PrintTexture(const struct gl_texture_image
*img
)
62 const GLchan
*data
= (const GLchan
*) img
->Data
;
65 printf("No texture data\n");
69 switch (img
->Format
) {
76 case GL_LUMINANCE_ALPHA
:
86 _mesa_problem(NULL
, "error in PrintTexture\n");
90 for (i
= 0; i
< img
->Height
; i
++) {
91 for (j
= 0; j
< img
->Width
; j
++) {
93 printf("%02x ", data
[0]);
95 printf("%02x%02x ", data
[0], data
[1]);
97 printf("%02x%02x%02x ", data
[0], data
[1], data
[2]);
99 printf("%02x%02x%02x%02x ", data
[0], data
[1], data
[2], data
[3]);
110 * Compute log base 2 of n.
111 * If n isn't an exact power of two return -1.
112 * If n < 0 return -1.
139 * Given an internal texture format enum or 1, 2, 3, 4 return the
140 * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE,
141 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.
142 * Return -1 if invalid enum.
145 _mesa_base_tex_format( GLcontext
*ctx
, GLint format
)
148 * Ask the driver for the base format, if it doesn't
149 * know, it will return -1;
151 if (ctx
->Driver
.BaseCompressedTexFormat
) {
152 GLint ifmt
= (*ctx
->Driver
.BaseCompressedTexFormat
)(ctx
, format
);
172 case GL_LUMINANCE_ALPHA
:
173 case GL_LUMINANCE4_ALPHA4
:
174 case GL_LUMINANCE6_ALPHA2
:
175 case GL_LUMINANCE8_ALPHA8
:
176 case GL_LUMINANCE12_ALPHA4
:
177 case GL_LUMINANCE12_ALPHA12
:
178 case GL_LUMINANCE16_ALPHA16
:
179 return GL_LUMINANCE_ALPHA
;
207 case GL_COLOR_INDEX1_EXT
:
208 case GL_COLOR_INDEX2_EXT
:
209 case GL_COLOR_INDEX4_EXT
:
210 case GL_COLOR_INDEX8_EXT
:
211 case GL_COLOR_INDEX12_EXT
:
212 case GL_COLOR_INDEX16_EXT
:
213 return GL_COLOR_INDEX
;
214 case GL_DEPTH_COMPONENT
:
215 case GL_DEPTH_COMPONENT16_SGIX
:
216 case GL_DEPTH_COMPONENT24_SGIX
:
217 case GL_DEPTH_COMPONENT32_SGIX
:
218 if (ctx
->Extensions
.SGIX_depth_texture
)
219 return GL_DEPTH_COMPONENT
;
223 return -1; /* error */
229 * Test if the given image format is a color/rgba format. That is,
230 * not color index, depth, stencil, etc.
233 is_color_format(GLenum format
)
248 case GL_LUMINANCE_ALPHA
:
249 case GL_LUMINANCE4_ALPHA4
:
250 case GL_LUMINANCE6_ALPHA2
:
251 case GL_LUMINANCE8_ALPHA8
:
252 case GL_LUMINANCE12_ALPHA4
:
253 case GL_LUMINANCE12_ALPHA12
:
254 case GL_LUMINANCE16_ALPHA16
:
286 is_index_format(GLenum format
)
290 case GL_COLOR_INDEX1_EXT
:
291 case GL_COLOR_INDEX2_EXT
:
292 case GL_COLOR_INDEX4_EXT
:
293 case GL_COLOR_INDEX8_EXT
:
294 case GL_COLOR_INDEX12_EXT
:
295 case GL_COLOR_INDEX16_EXT
:
304 * Return GL_TRUE if internalFormat is a compressed format, return GL_FALSE
308 is_compressed_format(GLcontext
*ctx
, GLenum internalFormat
)
310 if (ctx
->Driver
.IsCompressedFormat
) {
311 return (*ctx
->Driver
.IsCompressedFormat
)(ctx
, internalFormat
);
319 * Store a gl_texture_image pointer in a gl_texture_object structure
320 * according to the target and level parameters.
321 * This was basically prompted by the introduction of cube maps.
324 _mesa_set_tex_image(struct gl_texture_object
*tObj
,
325 GLenum target
, GLint level
,
326 struct gl_texture_image
*texImage
)
334 tObj
->Image
[level
] = texImage
;
336 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
337 tObj
->Image
[level
] = texImage
;
339 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
340 tObj
->NegX
[level
] = texImage
;
342 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
343 tObj
->PosY
[level
] = texImage
;
345 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
346 tObj
->NegY
[level
] = texImage
;
348 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
349 tObj
->PosZ
[level
] = texImage
;
351 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
352 tObj
->NegZ
[level
] = texImage
;
355 _mesa_problem(NULL
, "bad target in _mesa_set_tex_image()");
363 * Return new gl_texture_image struct with all fields initialized to zero.
365 struct gl_texture_image
*
366 _mesa_alloc_texture_image( void )
368 return CALLOC_STRUCT(gl_texture_image
);
374 _mesa_free_texture_image( struct gl_texture_image
*teximage
)
376 if (teximage
->Data
) {
377 FREE( teximage
->Data
);
378 teximage
->Data
= NULL
;
385 * Return GL_TRUE if the target is a proxy target.
388 is_proxy_target(GLenum target
)
390 return (target
== GL_PROXY_TEXTURE_1D
||
391 target
== GL_PROXY_TEXTURE_2D
||
392 target
== GL_PROXY_TEXTURE_3D
||
393 target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
);
398 * Given a texture unit and a texture target, return the corresponding
401 struct gl_texture_object
*
402 _mesa_select_tex_object(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
407 return texUnit
->Current1D
;
408 case GL_PROXY_TEXTURE_1D
:
409 return ctx
->Texture
.Proxy1D
;
411 return texUnit
->Current2D
;
412 case GL_PROXY_TEXTURE_2D
:
413 return ctx
->Texture
.Proxy2D
;
415 return texUnit
->Current3D
;
416 case GL_PROXY_TEXTURE_3D
:
417 return ctx
->Texture
.Proxy3D
;
418 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
419 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
420 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
421 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
422 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
423 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
424 case GL_TEXTURE_CUBE_MAP_ARB
:
425 return ctx
->Extensions
.ARB_texture_cube_map
426 ? texUnit
->CurrentCubeMap
: NULL
;
427 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
428 return ctx
->Extensions
.ARB_texture_cube_map
429 ? ctx
->Texture
.ProxyCubeMap
: NULL
;
431 _mesa_problem(NULL
, "bad target in _mesa_select_tex_object()");
438 * Return the texture image struct which corresponds to target and level
439 * for the given texture unit.
441 struct gl_texture_image
*
442 _mesa_select_tex_image(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
443 GLenum target
, GLint level
)
448 return texUnit
->Current1D
->Image
[level
];
449 case GL_PROXY_TEXTURE_1D
:
450 return ctx
->Texture
.Proxy1D
->Image
[level
];
452 return texUnit
->Current2D
->Image
[level
];
453 case GL_PROXY_TEXTURE_2D
:
454 return ctx
->Texture
.Proxy2D
->Image
[level
];
456 return texUnit
->Current3D
->Image
[level
];
457 case GL_PROXY_TEXTURE_3D
:
458 return ctx
->Texture
.Proxy3D
->Image
[level
];
459 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
460 if (ctx
->Extensions
.ARB_texture_cube_map
)
461 return texUnit
->CurrentCubeMap
->Image
[level
];
464 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
465 if (ctx
->Extensions
.ARB_texture_cube_map
)
466 return texUnit
->CurrentCubeMap
->NegX
[level
];
469 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
470 if (ctx
->Extensions
.ARB_texture_cube_map
)
471 return texUnit
->CurrentCubeMap
->PosY
[level
];
474 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
475 if (ctx
->Extensions
.ARB_texture_cube_map
)
476 return texUnit
->CurrentCubeMap
->NegY
[level
];
479 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
480 if (ctx
->Extensions
.ARB_texture_cube_map
)
481 return texUnit
->CurrentCubeMap
->PosZ
[level
];
484 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
485 if (ctx
->Extensions
.ARB_texture_cube_map
)
486 return texUnit
->CurrentCubeMap
->NegZ
[level
];
489 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
490 if (ctx
->Extensions
.ARB_texture_cube_map
)
491 return ctx
->Texture
.ProxyCubeMap
->Image
[level
];
495 _mesa_problem(ctx
, "bad target in _mesa_select_tex_image()");
503 * glTexImage[123]D can accept a NULL image pointer. In this case we
504 * create a texture image with unspecified image contents per the OpenGL
508 make_null_texture(GLint width
, GLint height
, GLint depth
, GLenum format
)
510 const GLint components
= _mesa_components_in_format(format
);
511 const GLint numPixels
= width
* height
* depth
;
512 GLubyte
*data
= (GLubyte
*) MALLOC(numPixels
* components
* sizeof(GLubyte
));
515 * Let's see if anyone finds this. If glTexImage2D() is called with
516 * a NULL image pointer then load the texture image with something
517 * interesting instead of leaving it indeterminate.
520 static const char message
[8][32] = {
524 " X X XXXX XXX XXXXX ",
527 " X X XXXXX XXX X X ",
531 GLubyte
*imgPtr
= data
;
533 for (h
= 0; h
< depth
; h
++) {
534 for (i
= 0; i
< height
; i
++) {
535 GLint srcRow
= 7 - (i
% 8);
536 for (j
= 0; j
< width
; j
++) {
537 GLint srcCol
= j
% 32;
538 GLubyte texel
= (message
[srcRow
][srcCol
]=='X') ? 255 : 70;
539 for (k
= 0; k
< components
; k
++) {
553 * Reset the fields of a gl_texture_image struct to zero.
554 * This is called when a proxy texture test fails, we set all the
555 * image members (except DriverData) to zero.
556 * It's also used in glTexImage[123]D as a safeguard to be sure all
557 * required fields get initialized properly by the Driver.TexImage[123]D
561 clear_teximage_fields(struct gl_texture_image
*img
)
577 img
->TexFormat
= &_mesa_null_texformat
;
578 img
->FetchTexel
= NULL
;
579 img
->IsCompressed
= 0;
580 img
->CompressedSize
= 0;
585 * Initialize basic fields of the gl_texture_image struct.
588 _mesa_init_teximage_fields(GLcontext
*ctx
,
589 struct gl_texture_image
*img
,
590 GLsizei width
, GLsizei height
, GLsizei depth
,
591 GLint border
, GLenum internalFormat
)
594 img
->Format
= _mesa_base_tex_format( ctx
, internalFormat
);
595 img
->IntFormat
= internalFormat
;
596 img
->Border
= border
;
598 img
->Height
= height
;
600 img
->WidthLog2
= logbase2(width
- 2 * border
);
601 if (height
== 1) /* 1-D texture */
604 img
->HeightLog2
= logbase2(height
- 2 * border
);
605 if (depth
== 1) /* 2-D texture */
608 img
->DepthLog2
= logbase2(depth
- 2 * border
);
609 img
->Width2
= 1 << img
->WidthLog2
;
610 img
->Height2
= 1 << img
->HeightLog2
;
611 img
->Depth2
= 1 << img
->DepthLog2
;
612 img
->MaxLog2
= MAX2(img
->WidthLog2
, img
->HeightLog2
);
613 img
->IsCompressed
= is_compressed_format(ctx
, internalFormat
);
619 * Test glTexImage[123]D() parameters for errors.
621 * dimensions - must be 1 or 2 or 3
622 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
625 texture_error_check( GLcontext
*ctx
, GLenum target
,
626 GLint level
, GLint internalFormat
,
627 GLenum format
, GLenum type
,
629 GLint width
, GLint height
,
630 GLint depth
, GLint border
)
635 if (dimensions
== 1) {
636 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_1D
);
637 if (target
!= GL_TEXTURE_1D
&& !isProxy
) {
638 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
642 else if (dimensions
== 2) {
643 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_2D
||
644 target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
);
645 if (target
!= GL_TEXTURE_2D
&& !isProxy
&&
646 !(ctx
->Extensions
.ARB_texture_cube_map
&&
647 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
648 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
649 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
653 else if (dimensions
== 3) {
654 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_3D
);
655 if (target
!= GL_TEXTURE_3D
&& !isProxy
) {
656 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
661 _mesa_problem( ctx
, "bad dims in texture_error_check" );
666 if (border
!= 0 && border
!= 1) {
669 sprintf(message
, "glTexImage%dD(border=%d)", dimensions
, border
);
670 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
676 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
677 || logbase2( width
- 2 * border
) < 0) {
680 sprintf(message
, "glTexImage%dD(width=%d)", dimensions
, width
);
681 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
687 if (dimensions
>= 2) {
688 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
689 || logbase2( height
- 2 * border
) < 0) {
692 sprintf(message
, "glTexImage%dD(height=%d)", dimensions
, height
);
693 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
699 /* For cube map, width must equal height */
700 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
701 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
702 if (width
!= height
) {
704 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
711 if (dimensions
>= 3) {
712 if (depth
< 2 * border
|| depth
> 2 + ctx
->Const
.MaxTextureSize
713 || logbase2( depth
- 2 * border
) < 0) {
716 sprintf(message
, "glTexImage3D(depth=%d)", depth
);
717 _mesa_error( ctx
, GL_INVALID_VALUE
, message
);
724 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
727 sprintf(message
, "glTexImage%dD(level=%d)", dimensions
, level
);
728 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
733 /* For cube map, width must equal height */
734 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
735 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
736 if (width
!= height
) {
737 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
742 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
746 sprintf(message
, "glTexImage%dD(internalFormat=0x%x)", dimensions
,
748 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
753 if (!is_compressed_format( ctx
, internalFormat
) &&
754 !_mesa_is_legal_format_and_type( format
, type
)) {
755 /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
756 * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
760 sprintf(message
, "glTexImage%dD(format or type)", dimensions
);
761 _mesa_error(ctx
, GL_INVALID_OPERATION
, message
);
766 /* if we get here, the parameters are OK */
773 * Test glTexSubImage[123]D() parameters for errors.
775 * dimensions - must be 1 or 2 or 3
776 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
779 subtexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
780 GLenum target
, GLint level
,
781 GLint xoffset
, GLint yoffset
, GLint zoffset
,
782 GLint width
, GLint height
, GLint depth
,
783 GLenum format
, GLenum type
)
785 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
786 struct gl_texture_image
*destTex
;
788 if (dimensions
== 1) {
789 if (target
!= GL_TEXTURE_1D
) {
790 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(target)" );
794 else if (dimensions
== 2) {
795 if (ctx
->Extensions
.ARB_texture_cube_map
) {
796 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
797 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
798 target
!= GL_TEXTURE_2D
) {
799 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
803 else if (target
!= GL_TEXTURE_2D
) {
804 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
808 else if (dimensions
== 3) {
809 if (target
!= GL_TEXTURE_3D
) {
810 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3D(target)" );
815 _mesa_problem( ctx
, "bad dims in texture_error_check" );
819 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
821 sprintf(message
, "glTexSubImage2D(level=%d)", level
);
822 _mesa_error(ctx
, GL_INVALID_ENUM
, message
);
828 sprintf(message
, "glTexSubImage%dD(width=%d)", dimensions
, width
);
829 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
832 if (height
< 0 && dimensions
> 1) {
834 sprintf(message
, "glTexSubImage%dD(height=%d)", dimensions
, height
);
835 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
838 if (depth
< 0 && dimensions
> 2) {
840 sprintf(message
, "glTexSubImage%dD(depth=%d)", dimensions
, depth
);
841 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
845 destTex
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
848 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glTexSubImage2D");
852 if (xoffset
< -((GLint
)destTex
->Border
)) {
853 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset)");
856 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
857 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset+width)");
860 if (dimensions
> 1) {
861 if (yoffset
< -((GLint
)destTex
->Border
)) {
862 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset)");
865 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
866 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset+height)");
870 if (dimensions
> 2) {
871 if (zoffset
< -((GLint
)destTex
->Border
)) {
872 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset)");
875 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+ destTex
->Border
)) {
876 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset+depth)");
881 if (!is_compressed_format(ctx
, destTex
->IntFormat
) &&
882 !_mesa_is_legal_format_and_type(format
, type
)) {
884 sprintf(message
, "glTexSubImage%dD(format or type)", dimensions
);
885 _mesa_error(ctx
, GL_INVALID_ENUM
, message
);
894 * Test glCopyTexImage[12]D() parameters for errors.
895 * Input: dimensions - must be 1 or 2 or 3
896 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
899 copytexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
900 GLenum target
, GLint level
, GLint internalFormat
,
901 GLint width
, GLint height
, GLint border
)
905 if (dimensions
== 1) {
906 if (target
!= GL_TEXTURE_1D
) {
907 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
911 else if (dimensions
== 2) {
912 if (ctx
->Extensions
.ARB_texture_cube_map
) {
913 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
914 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
915 target
!= GL_TEXTURE_2D
) {
916 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
920 else if (target
!= GL_TEXTURE_2D
) {
921 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
927 if (border
!= 0 && border
!= 1) {
929 sprintf(message
, "glCopyTexImage%dD(border)", dimensions
);
930 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
935 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
936 || logbase2( width
- 2 * border
) < 0) {
938 sprintf(message
, "glCopyTexImage%dD(width=%d)", dimensions
, width
);
939 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
944 if (dimensions
>= 2) {
945 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
946 || logbase2( height
- 2 * border
) < 0) {
948 sprintf(message
, "glCopyTexImage%dD(height=%d)", dimensions
, height
);
949 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
954 /* For cube map, width must equal height */
955 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
956 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
957 if (width
!= height
) {
958 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(width != height)");
964 if (level
< 0 || level
>=ctx
->Const
.MaxTextureLevels
) {
966 sprintf(message
, "glCopyTexImage%dD(level=%d)", dimensions
, level
);
967 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
971 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
974 sprintf(message
, "glCopyTexImage%dD(internalFormat)", dimensions
);
975 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
979 /* if we get here, the parameters are OK */
985 copytexsubimage_error_check( GLcontext
*ctx
, GLuint dimensions
,
986 GLenum target
, GLint level
,
987 GLint xoffset
, GLint yoffset
, GLint zoffset
,
988 GLsizei width
, GLsizei height
)
990 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
991 struct gl_texture_image
*teximage
;
993 if (dimensions
== 1) {
994 if (target
!= GL_TEXTURE_1D
) {
995 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
999 else if (dimensions
== 2) {
1000 if (ctx
->Extensions
.ARB_texture_cube_map
) {
1001 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1002 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1003 target
!= GL_TEXTURE_2D
) {
1004 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1008 else if (target
!= GL_TEXTURE_2D
) {
1009 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1013 else if (dimensions
== 3) {
1014 if (target
!= GL_TEXTURE_3D
) {
1015 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3D(target)" );
1020 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1022 sprintf(message
, "glCopyTexSubImage%dD(level=%d)", dimensions
, level
);
1023 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1029 sprintf(message
, "glCopyTexSubImage%dD(width=%d)", dimensions
, width
);
1030 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1033 if (dimensions
> 1 && height
< 0) {
1035 sprintf(message
, "glCopyTexSubImage%dD(height=%d)", dimensions
, height
);
1036 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1040 teximage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1043 sprintf(message
, "glCopyTexSubImage%dD(undefined texture)", dimensions
);
1044 _mesa_error(ctx
, GL_INVALID_OPERATION
, message
);
1048 if (xoffset
< -((GLint
)teximage
->Border
)) {
1050 sprintf(message
, "glCopyTexSubImage%dD(xoffset=%d)", dimensions
, xoffset
);
1051 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1054 if (xoffset
+ width
> (GLint
) (teximage
->Width
+ teximage
->Border
)) {
1056 sprintf(message
, "glCopyTexSubImage%dD(xoffset+width)", dimensions
);
1057 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1060 if (dimensions
> 1) {
1061 if (yoffset
< -((GLint
)teximage
->Border
)) {
1063 sprintf(message
, "glCopyTexSubImage%dD(yoffset=%d)", dimensions
, yoffset
);
1064 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1067 /* NOTE: we're adding the border here, not subtracting! */
1068 if (yoffset
+ height
> (GLint
) (teximage
->Height
+ teximage
->Border
)) {
1070 sprintf(message
, "glCopyTexSubImage%dD(yoffset+height)", dimensions
);
1071 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1076 if (dimensions
> 2) {
1077 if (zoffset
< -((GLint
)teximage
->Border
)) {
1079 sprintf(message
, "glCopyTexSubImage%dD(zoffset)", dimensions
);
1080 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1083 if (zoffset
> (GLint
) (teximage
->Depth
+ teximage
->Border
)) {
1085 sprintf(message
, "glCopyTexSubImage%dD(zoffset+depth)", dimensions
);
1086 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1091 /* if we get here, the parameters are OK */
1098 _mesa_GetTexImage( GLenum target
, GLint level
, GLenum format
,
1099 GLenum type
, GLvoid
*pixels
)
1101 const struct gl_texture_unit
*texUnit
;
1102 const struct gl_texture_object
*texObj
;
1103 struct gl_texture_image
*texImage
;
1104 GET_CURRENT_CONTEXT(ctx
);
1105 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1107 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1108 _mesa_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
1112 if (_mesa_sizeof_type(type
) <= 0) {
1113 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
1117 if (_mesa_components_in_format(format
) <= 0 ||
1118 format
== GL_STENCIL_INDEX
) {
1119 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
1123 if (!ctx
->Extensions
.EXT_paletted_texture
&& is_index_format(format
)) {
1124 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1127 if (!ctx
->Extensions
.SGIX_depth_texture
&& format
== GL_DEPTH_COMPONENT
) {
1128 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1131 /* XXX what if format/type doesn't match texture format/type? */
1136 texUnit
= &(ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
]);
1137 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1138 if (!texObj
|| is_proxy_target(target
)) {
1139 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)");
1143 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1145 /* invalid mipmap level, not an error */
1149 if (!texImage
->Data
) {
1150 /* no image data, not an error */
1154 if (ctx
->NewState
& _NEW_PIXEL
)
1155 _mesa_update_state(ctx
);
1157 if (is_color_format(format
) &&
1158 ctx
->_ImageTransferState
& IMAGE_CONVOLUTION_BIT
) {
1159 /* convert texture image to GL_RGBA, GL_FLOAT */
1160 GLint width
= texImage
->Width
;
1161 GLint height
= texImage
->Height
;
1162 GLint depth
= texImage
->Depth
;
1164 GLfloat
*tmpImage
, *convImage
;
1165 tmpImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
1167 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
1170 convImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
1173 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
1177 for (img
= 0; img
< depth
; img
++) {
1178 GLint convWidth
, convHeight
;
1180 /* convert texture data to GLfloat/GL_RGBA */
1181 for (row
= 0; row
< height
; row
++) {
1182 GLchan texels
[1 << MAX_TEXTURE_LEVELS
][4];
1184 GLfloat
*dst
= tmpImage
+ row
* width
* 4;
1185 for (col
= 0; col
< width
; col
++) {
1186 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1189 _mesa_unpack_float_color_span(ctx
, width
, GL_RGBA
, dst
,
1190 GL_RGBA
, CHAN_TYPE
, texels
,
1191 &_mesa_native_packing
,
1192 ctx
->_ImageTransferState
& IMAGE_PRE_CONVOLUTION_BITS
,
1197 convHeight
= height
;
1200 if (target
== GL_TEXTURE_1D
) {
1201 if (ctx
->Pixel
.Convolution1DEnabled
) {
1202 _mesa_convolve_1d_image(ctx
, &convWidth
, tmpImage
, convImage
);
1206 if (ctx
->Pixel
.Convolution2DEnabled
) {
1207 _mesa_convolve_2d_image(ctx
, &convWidth
, &convHeight
,
1208 tmpImage
, convImage
);
1210 else if (ctx
->Pixel
.Separable2DEnabled
) {
1211 _mesa_convolve_sep_image(ctx
, &convWidth
, &convHeight
,
1212 tmpImage
, convImage
);
1216 /* pack convolved image */
1217 for (row
= 0; row
< convHeight
; row
++) {
1218 const GLfloat
*src
= convImage
+ row
* convWidth
* 4;
1219 GLvoid
*dest
= _mesa_image_address(&ctx
->Pack
, pixels
,
1220 convWidth
, convHeight
,
1221 format
, type
, img
, row
, 0);
1222 _mesa_pack_float_rgba_span(ctx
, convWidth
,
1223 (const GLfloat(*)[4]) src
,
1224 format
, type
, dest
, &ctx
->Pack
,
1225 ctx
->_ImageTransferState
& IMAGE_POST_CONVOLUTION_BITS
);
1233 /* no convolution, or non-rgba image */
1234 GLint width
= texImage
->Width
;
1235 GLint height
= texImage
->Height
;
1236 GLint depth
= texImage
->Depth
;
1238 for (img
= 0; img
< depth
; img
++) {
1239 for (row
= 0; row
< height
; row
++) {
1240 /* compute destination address in client memory */
1241 GLvoid
*dest
= _mesa_image_address( &ctx
->Unpack
, pixels
,
1242 width
, height
, format
, type
,
1246 if (format
== GL_COLOR_INDEX
) {
1247 GLuint indexRow
[MAX_WIDTH
];
1249 for (col
= 0; col
< width
; col
++) {
1250 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1251 (GLvoid
*) &indexRow
[col
]);
1253 _mesa_pack_index_span(ctx
, width
, type
, dest
,
1254 indexRow
, &ctx
->Pack
,
1255 ctx
->_ImageTransferState
);
1257 else if (format
== GL_DEPTH_COMPONENT
) {
1258 GLfloat depthRow
[MAX_WIDTH
];
1260 for (col
= 0; col
< width
; col
++) {
1261 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1262 (GLvoid
*) &depthRow
[col
]);
1264 _mesa_pack_depth_span(ctx
, width
, dest
, type
,
1265 depthRow
, &ctx
->Pack
);
1268 /* general case: convert row to RGBA format */
1269 GLchan rgba
[MAX_WIDTH
][4];
1271 for (col
= 0; col
< width
; col
++) {
1272 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1273 (GLvoid
*) rgba
[col
]);
1275 _mesa_pack_rgba_span(ctx
, width
, (const GLchan (*)[4])rgba
,
1276 format
, type
, dest
, &ctx
->Pack
,
1277 ctx
->_ImageTransferState
);
1287 * Called from the API. Note that width includes the border.
1290 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
1291 GLsizei width
, GLint border
, GLenum format
,
1292 GLenum type
, const GLvoid
*pixels
)
1294 GLsizei postConvWidth
= width
;
1295 GET_CURRENT_CONTEXT(ctx
);
1296 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1298 if (is_color_format(internalFormat
)) {
1299 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1302 if (target
== GL_TEXTURE_1D
) {
1303 struct gl_texture_unit
*texUnit
;
1304 struct gl_texture_object
*texObj
;
1305 struct gl_texture_image
*texImage
;
1307 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1308 format
, type
, 1, postConvWidth
, 1, 1, border
)) {
1309 return; /* error was recorded */
1312 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1313 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1314 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1317 texImage
= _mesa_alloc_texture_image();
1318 texObj
->Image
[level
] = texImage
;
1320 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
1324 else if (texImage
->Data
) {
1325 /* free the old texture data */
1326 FREE(texImage
->Data
);
1327 texImage
->Data
= NULL
;
1329 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1330 _mesa_init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1331 border
, internalFormat
);
1333 if (ctx
->NewState
& _NEW_PIXEL
)
1334 _mesa_update_state(ctx
);
1336 ASSERT(ctx
->Driver
.TexImage1D
);
1338 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1339 width
, border
, format
, type
, pixels
,
1340 &ctx
->Unpack
, texObj
, texImage
);
1343 GLubyte
*dummy
= make_null_texture(width
, 1, 1, format
);
1345 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1347 format
, GL_UNSIGNED_BYTE
, dummy
,
1348 &_mesa_native_packing
, texObj
, texImage
);
1353 ASSERT(texImage
->TexFormat
);
1354 if (!texImage
->FetchTexel
) {
1355 /* If driver didn't explicitly set this, use the default */
1356 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel1D
;
1358 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 _mesa_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 _mesa_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 _mesa_init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
,
1444 1, 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
);
1466 ASSERT(texImage
->TexFormat
);
1467 if (!texImage
->FetchTexel
) {
1468 /* If driver didn't explicitly set this, use the default */
1469 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel2D
;
1471 ASSERT(texImage
->FetchTexel
);
1474 texObj
->Complete
= GL_FALSE
;
1475 ctx
->NewState
|= _NEW_TEXTURE
;
1477 else if (target
== GL_PROXY_TEXTURE_2D
) {
1478 /* Proxy texture: check for errors and update proxy state */
1479 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1481 postConvWidth
, postConvHeight
, 1, border
);
1483 struct gl_texture_unit
*texUnit
;
1484 struct gl_texture_image
*texImage
;
1485 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1486 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1487 _mesa_init_teximage_fields(ctx
, texImage
, postConvWidth
,
1488 postConvHeight
, 1, border
, internalFormat
);
1489 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1490 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1491 internalFormat
, format
, type
,
1492 postConvWidth
, postConvHeight
, 1, border
);
1495 /* if error, clear all proxy texture image parameters */
1496 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1497 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
1502 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1509 * Called by the API or display list executor.
1510 * Note that width and height include the border.
1513 _mesa_TexImage3D( GLenum target
, GLint level
, GLenum internalFormat
,
1514 GLsizei width
, GLsizei height
, GLsizei depth
,
1515 GLint border
, GLenum format
, GLenum type
,
1516 const GLvoid
*pixels
)
1518 GET_CURRENT_CONTEXT(ctx
);
1519 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1521 if (target
== GL_TEXTURE_3D
) {
1522 struct gl_texture_unit
*texUnit
;
1523 struct gl_texture_object
*texObj
;
1524 struct gl_texture_image
*texImage
;
1526 if (texture_error_check(ctx
, target
, level
, (GLint
) internalFormat
,
1527 format
, type
, 3, width
, height
, depth
, border
)) {
1528 return; /* error was recorded */
1531 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1532 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1533 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1536 texImage
= _mesa_alloc_texture_image();
1537 texObj
->Image
[level
] = texImage
;
1539 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
1543 else if (texImage
->Data
) {
1544 FREE(texImage
->Data
);
1545 texImage
->Data
= NULL
;
1547 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1548 _mesa_init_teximage_fields(ctx
, texImage
, width
, height
, depth
, border
,
1551 if (ctx
->NewState
& _NEW_PIXEL
)
1552 _mesa_update_state(ctx
);
1554 ASSERT(ctx
->Driver
.TexImage3D
);
1556 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, (GLint
) internalFormat
,
1557 width
, height
, depth
, border
,
1558 format
, type
, pixels
,
1559 &ctx
->Unpack
, texObj
, texImage
);
1562 GLubyte
*dummy
= make_null_texture(width
, height
, depth
, format
);
1564 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
,
1565 (GLint
) internalFormat
,
1566 width
, height
, depth
, border
,
1567 format
, GL_UNSIGNED_BYTE
, dummy
,
1568 &_mesa_native_packing
, texObj
, texImage
);
1573 ASSERT(texImage
->TexFormat
);
1574 if (!texImage
->FetchTexel
) {
1575 /* If driver didn't explicitly set this, use the default */
1576 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel3D
;
1578 ASSERT(texImage
->FetchTexel
);
1581 texObj
->Complete
= GL_FALSE
;
1582 ctx
->NewState
|= _NEW_TEXTURE
;
1584 else if (target
== GL_PROXY_TEXTURE_3D
) {
1585 /* Proxy texture: check for errors and update proxy state */
1586 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1587 format
, type
, 3, width
, height
, depth
, border
);
1589 struct gl_texture_unit
*texUnit
;
1590 struct gl_texture_image
*texImage
;
1591 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1592 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1593 _mesa_init_teximage_fields(ctx
, texImage
, width
, height
, 1,
1594 border
, internalFormat
);
1595 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1596 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1597 internalFormat
, format
, type
,
1598 width
, height
, depth
, border
);
1601 /* if error, clear all proxy texture image parameters */
1602 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1603 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
1608 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1615 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
1616 GLsizei width
, GLsizei height
, GLsizei depth
,
1617 GLint border
, GLenum format
, GLenum type
,
1618 const GLvoid
*pixels
)
1620 _mesa_TexImage3D(target
, level
, internalFormat
, width
, height
,
1621 depth
, border
, format
, type
, pixels
);
1627 _mesa_TexSubImage1D( GLenum target
, GLint level
,
1628 GLint xoffset
, GLsizei width
,
1629 GLenum format
, GLenum type
,
1630 const GLvoid
*pixels
)
1632 GLsizei postConvWidth
= width
;
1633 struct gl_texture_unit
*texUnit
;
1634 struct gl_texture_object
*texObj
;
1635 struct gl_texture_image
*texImage
;
1636 GET_CURRENT_CONTEXT(ctx
);
1637 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1639 if (ctx
->NewState
& _NEW_PIXEL
)
1640 _mesa_update_state(ctx
);
1642 /* XXX should test internal format */
1643 if (is_color_format(format
)) {
1644 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1647 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
1648 postConvWidth
, 1, 1, format
, type
)) {
1649 return; /* error was detected */
1652 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1653 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1654 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1657 if (width
== 0 || !pixels
)
1658 return; /* no-op, not an error */
1660 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1661 xoffset
+= texImage
->Border
;
1663 ASSERT(ctx
->Driver
.TexSubImage1D
);
1664 (*ctx
->Driver
.TexSubImage1D
)(ctx
, target
, level
, xoffset
, width
,
1665 format
, type
, pixels
, &ctx
->Unpack
,
1667 ctx
->NewState
|= _NEW_TEXTURE
;
1672 _mesa_TexSubImage2D( GLenum target
, GLint level
,
1673 GLint xoffset
, GLint yoffset
,
1674 GLsizei width
, GLsizei height
,
1675 GLenum format
, GLenum type
,
1676 const GLvoid
*pixels
)
1678 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1679 struct gl_texture_unit
*texUnit
;
1680 struct gl_texture_object
*texObj
;
1681 struct gl_texture_image
*texImage
;
1682 GET_CURRENT_CONTEXT(ctx
);
1683 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1685 if (ctx
->NewState
& _NEW_PIXEL
)
1686 _mesa_update_state(ctx
);
1688 /* XXX should test internal format */
1689 if (is_color_format(format
)) {
1690 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1694 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1695 postConvWidth
, postConvHeight
, 1, format
, type
)) {
1696 return; /* error was detected */
1699 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1700 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1701 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1704 if (width
== 0 || height
== 0 || !pixels
)
1705 return; /* no-op, not an error */
1707 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1708 xoffset
+= texImage
->Border
;
1709 yoffset
+= texImage
->Border
;
1711 ASSERT(ctx
->Driver
.TexSubImage2D
);
1712 (*ctx
->Driver
.TexSubImage2D
)(ctx
, target
, level
, xoffset
, yoffset
,
1713 width
, height
, format
, type
, pixels
,
1714 &ctx
->Unpack
, texObj
, texImage
);
1715 ctx
->NewState
|= _NEW_TEXTURE
;
1721 _mesa_TexSubImage3D( GLenum target
, GLint level
,
1722 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1723 GLsizei width
, GLsizei height
, GLsizei depth
,
1724 GLenum format
, GLenum type
,
1725 const GLvoid
*pixels
)
1727 struct gl_texture_unit
*texUnit
;
1728 struct gl_texture_object
*texObj
;
1729 struct gl_texture_image
*texImage
;
1730 GET_CURRENT_CONTEXT(ctx
);
1731 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1733 if (ctx
->NewState
& _NEW_PIXEL
)
1734 _mesa_update_state(ctx
);
1736 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
1737 width
, height
, depth
, format
, type
)) {
1738 return; /* error was detected */
1741 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1742 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1743 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1746 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
1747 return; /* no-op, not an error */
1749 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1750 xoffset
+= texImage
->Border
;
1751 yoffset
+= texImage
->Border
;
1752 zoffset
+= texImage
->Border
;
1754 ASSERT(ctx
->Driver
.TexSubImage3D
);
1755 (*ctx
->Driver
.TexSubImage3D
)(ctx
, target
, level
,
1756 xoffset
, yoffset
, zoffset
,
1757 width
, height
, depth
,
1758 format
, type
, pixels
,
1759 &ctx
->Unpack
, texObj
, texImage
);
1760 ctx
->NewState
|= _NEW_TEXTURE
;
1766 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
1767 GLenum internalFormat
,
1769 GLsizei width
, GLint border
)
1771 struct gl_texture_unit
*texUnit
;
1772 struct gl_texture_object
*texObj
;
1773 struct gl_texture_image
*texImage
;
1774 GLsizei postConvWidth
= width
;
1775 GET_CURRENT_CONTEXT(ctx
);
1776 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1778 if (ctx
->NewState
& _NEW_PIXEL
)
1779 _mesa_update_state(ctx
);
1781 if (is_color_format(internalFormat
)) {
1782 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1785 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
1786 postConvWidth
, 1, border
))
1789 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1790 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1791 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1793 texImage
= _mesa_alloc_texture_image();
1794 _mesa_set_tex_image(texObj
, target
, level
, texImage
);
1796 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D");
1800 else if (texImage
->Data
) {
1801 /* free the old texture data */
1802 FREE(texImage
->Data
);
1803 texImage
->Data
= NULL
;
1806 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1807 _mesa_init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1808 border
, internalFormat
);
1811 ASSERT(ctx
->Driver
.CopyTexImage1D
);
1812 (*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
, internalFormat
,
1813 x
, y
, width
, border
);
1815 ASSERT(texImage
->TexFormat
);
1816 if (!texImage
->FetchTexel
) {
1817 /* If driver didn't explicitly set this, use the default */
1818 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel1D
;
1820 ASSERT(texImage
->FetchTexel
);
1823 texObj
->Complete
= GL_FALSE
;
1824 ctx
->NewState
|= _NEW_TEXTURE
;
1830 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
1831 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1834 struct gl_texture_unit
*texUnit
;
1835 struct gl_texture_object
*texObj
;
1836 struct gl_texture_image
*texImage
;
1837 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1838 GET_CURRENT_CONTEXT(ctx
);
1839 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1841 if (ctx
->NewState
& _NEW_PIXEL
)
1842 _mesa_update_state(ctx
);
1844 if (is_color_format(internalFormat
)) {
1845 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1849 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
1850 postConvWidth
, postConvHeight
, border
))
1853 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1854 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1855 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1857 texImage
= _mesa_alloc_texture_image();
1858 _mesa_set_tex_image(texObj
, target
, level
, texImage
);
1860 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D");
1864 else if (texImage
->Data
) {
1865 /* free the old texture data */
1866 FREE(texImage
->Data
);
1867 texImage
->Data
= NULL
;
1870 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1871 _mesa_init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
, 1,
1872 border
, internalFormat
);
1874 ASSERT(ctx
->Driver
.CopyTexImage2D
);
1875 (*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
, internalFormat
,
1876 x
, y
, width
, height
, border
);
1878 ASSERT(texImage
->TexFormat
);
1879 if (!texImage
->FetchTexel
) {
1880 /* If driver didn't explicitly set this, use the default */
1881 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel2D
;
1883 ASSERT(texImage
->FetchTexel
);
1886 texObj
->Complete
= GL_FALSE
;
1887 ctx
->NewState
|= _NEW_TEXTURE
;
1893 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
1894 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
1896 struct gl_texture_unit
*texUnit
;
1897 struct gl_texture_object
*texObj
;
1898 struct gl_texture_image
*texImage
;
1899 GLsizei postConvWidth
= width
;
1900 GET_CURRENT_CONTEXT(ctx
);
1901 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1903 if (ctx
->NewState
& _NEW_PIXEL
)
1904 _mesa_update_state(ctx
);
1906 /* XXX should test internal format */
1907 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1909 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
1910 xoffset
, 0, 0, postConvWidth
, 1))
1913 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1914 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1915 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1917 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1918 xoffset
+= texImage
->Border
;
1920 ASSERT(ctx
->Driver
.CopyTexSubImage1D
);
1921 (*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
, xoffset
, x
, y
, width
);
1922 ctx
->NewState
|= _NEW_TEXTURE
;
1928 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
1929 GLint xoffset
, GLint yoffset
,
1930 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1932 struct gl_texture_unit
*texUnit
;
1933 struct gl_texture_object
*texObj
;
1934 struct gl_texture_image
*texImage
;
1935 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1936 GET_CURRENT_CONTEXT(ctx
);
1937 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1939 if (ctx
->NewState
& _NEW_PIXEL
)
1940 _mesa_update_state(ctx
);
1942 /* XXX should test internal format */
1943 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
1945 if (copytexsubimage_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1946 postConvWidth
, postConvHeight
))
1949 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1950 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1951 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1953 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1954 xoffset
+= texImage
->Border
;
1955 yoffset
+= texImage
->Border
;
1957 ASSERT(ctx
->Driver
.CopyTexSubImage2D
);
1958 (*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
1959 xoffset
, yoffset
, x
, y
, width
, height
);
1960 ctx
->NewState
|= _NEW_TEXTURE
;
1966 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
1967 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1968 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1970 struct gl_texture_unit
*texUnit
;
1971 struct gl_texture_object
*texObj
;
1972 struct gl_texture_image
*texImage
;
1973 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1974 GET_CURRENT_CONTEXT(ctx
);
1975 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1977 if (ctx
->NewState
& _NEW_PIXEL
)
1978 _mesa_update_state(ctx
);
1980 /* XXX should test internal format */
1981 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
1983 if (copytexsubimage_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
,
1984 zoffset
, postConvWidth
, postConvHeight
))
1987 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1988 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1989 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1991 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1992 xoffset
+= texImage
->Border
;
1993 yoffset
+= texImage
->Border
;
1994 zoffset
+= texImage
->Border
;
1996 ASSERT(ctx
->Driver
.CopyTexSubImage3D
);
1997 (*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
1998 xoffset
, yoffset
, zoffset
,
1999 x
, y
, width
, height
);
2000 ctx
->NewState
|= _NEW_TEXTURE
;
2006 _mesa_CompressedTexImage1DARB(GLenum target
, GLint level
,
2007 GLenum internalFormat
, GLsizei width
,
2008 GLint border
, GLsizei imageSize
,
2011 GET_CURRENT_CONTEXT(ctx
);
2012 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2014 switch (internalFormat
) {
2015 case GL_COMPRESSED_ALPHA_ARB
:
2016 case GL_COMPRESSED_LUMINANCE_ARB
:
2017 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2018 case GL_COMPRESSED_INTENSITY_ARB
:
2019 case GL_COMPRESSED_RGB_ARB
:
2020 case GL_COMPRESSED_RGBA_ARB
:
2021 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB");
2024 /* silence compiler warning */
2028 if (target
== GL_TEXTURE_1D
) {
2029 struct gl_texture_unit
*texUnit
;
2030 struct gl_texture_object
*texObj
;
2031 struct gl_texture_image
*texImage
;
2033 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2034 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
2035 return; /* error in texture image was detected */
2038 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2039 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2040 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2043 texImage
= _mesa_alloc_texture_image();
2044 texObj
->Image
[level
] = texImage
;
2046 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage1DARB");
2050 else if (texImage
->Data
) {
2051 FREE(texImage
->Data
);
2052 texImage
->Data
= NULL
;
2055 _mesa_init_teximage_fields(ctx
, texImage
, width
, 1, 1,
2056 border
, internalFormat
);
2058 if (ctx
->Extensions
.ARB_texture_compression
) {
2059 ASSERT(ctx
->Driver
.CompressedTexImage1D
);
2060 (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
,
2061 internalFormat
, width
, border
,
2064 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2068 texObj
->Complete
= GL_FALSE
;
2069 ctx
->NewState
|= _NEW_TEXTURE
;
2071 else if (target
== GL_PROXY_TEXTURE_1D
) {
2072 /* Proxy texture: check for errors and update proxy state */
2073 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2074 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
);
2076 struct gl_texture_unit
*texUnit
;
2077 struct gl_texture_image
*texImage
;
2078 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2079 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2080 _mesa_init_teximage_fields(ctx
, texImage
, width
, 1, 1,
2081 border
, internalFormat
);
2082 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2083 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2084 internalFormat
, GL_NONE
, GL_NONE
,
2085 width
, 1, 1, border
);
2088 /* if error, clear all proxy texture image parameters */
2089 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2090 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
2095 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB(target)" );
2102 _mesa_CompressedTexImage2DARB(GLenum target
, GLint level
,
2103 GLenum internalFormat
, GLsizei width
,
2104 GLsizei height
, GLint border
, GLsizei imageSize
,
2107 GET_CURRENT_CONTEXT(ctx
);
2108 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2110 switch (internalFormat
) {
2111 case GL_COMPRESSED_ALPHA_ARB
:
2112 case GL_COMPRESSED_LUMINANCE_ARB
:
2113 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2114 case GL_COMPRESSED_INTENSITY_ARB
:
2115 case GL_COMPRESSED_RGB_ARB
:
2116 case GL_COMPRESSED_RGBA_ARB
:
2117 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB");
2120 /* silence compiler warning */
2124 if (target
== GL_TEXTURE_2D
||
2125 (ctx
->Extensions
.ARB_texture_cube_map
&&
2126 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2127 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
2128 struct gl_texture_unit
*texUnit
;
2129 struct gl_texture_object
*texObj
;
2130 struct gl_texture_image
*texImage
;
2132 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2133 GL_NONE
, GL_NONE
, 1, width
, height
, 1, border
)) {
2134 return; /* error in texture image was detected */
2137 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2138 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2139 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2142 texImage
= _mesa_alloc_texture_image();
2143 texObj
->Image
[level
] = texImage
;
2145 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
2149 else if (texImage
->Data
) {
2150 FREE(texImage
->Data
);
2151 texImage
->Data
= NULL
;
2154 _mesa_init_teximage_fields(ctx
, texImage
, width
, height
, 1, border
,
2157 if (ctx
->Extensions
.ARB_texture_compression
) {
2158 ASSERT(ctx
->Driver
.CompressedTexImage2D
);
2159 (*ctx
->Driver
.CompressedTexImage2D
)(ctx
, target
, level
,
2160 internalFormat
, width
, height
,
2161 border
, imageSize
, data
,
2163 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2167 texObj
->Complete
= GL_FALSE
;
2168 ctx
->NewState
|= _NEW_TEXTURE
;
2170 else if (target
== GL_PROXY_TEXTURE_2D
) {
2171 /* Proxy texture: check for errors and update proxy state */
2172 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2173 GL_NONE
, GL_NONE
, 2, width
, height
, 1, border
);
2175 struct gl_texture_unit
*texUnit
;
2176 struct gl_texture_image
*texImage
;
2177 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2178 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2179 _mesa_init_teximage_fields(ctx
, texImage
, width
, height
, 1,
2180 border
, internalFormat
);
2181 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2182 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2183 internalFormat
, GL_NONE
, GL_NONE
,
2184 width
, height
, 1, border
);
2187 /* if error, clear all proxy texture image parameters */
2188 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2189 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
2194 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB(target)" );
2201 _mesa_CompressedTexImage3DARB(GLenum target
, GLint level
,
2202 GLenum internalFormat
, GLsizei width
,
2203 GLsizei height
, GLsizei depth
, GLint border
,
2204 GLsizei imageSize
, const GLvoid
*data
)
2206 GET_CURRENT_CONTEXT(ctx
);
2207 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2209 switch (internalFormat
) {
2210 case GL_COMPRESSED_ALPHA_ARB
:
2211 case GL_COMPRESSED_LUMINANCE_ARB
:
2212 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2213 case GL_COMPRESSED_INTENSITY_ARB
:
2214 case GL_COMPRESSED_RGB_ARB
:
2215 case GL_COMPRESSED_RGBA_ARB
:
2216 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB");
2219 /* silence compiler warning */
2223 if (target
== GL_TEXTURE_3D
) {
2224 struct gl_texture_unit
*texUnit
;
2225 struct gl_texture_object
*texObj
;
2226 struct gl_texture_image
*texImage
;
2228 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2229 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
)) {
2230 return; /* error in texture image was detected */
2233 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2234 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2235 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2238 texImage
= _mesa_alloc_texture_image();
2239 texObj
->Image
[level
] = texImage
;
2241 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage3DARB");
2245 else if (texImage
->Data
) {
2246 FREE(texImage
->Data
);
2247 texImage
->Data
= NULL
;
2250 _mesa_init_teximage_fields(ctx
, texImage
, width
, height
, depth
, border
,
2253 if (ctx
->Extensions
.ARB_texture_compression
) {
2254 ASSERT(ctx
->Driver
.CompressedTexImage3D
);
2255 (*ctx
->Driver
.CompressedTexImage3D
)(ctx
, target
, level
,
2257 width
, height
, depth
,
2258 border
, imageSize
, data
,
2260 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2264 texObj
->Complete
= GL_FALSE
;
2265 ctx
->NewState
|= _NEW_TEXTURE
;
2267 else if (target
== GL_PROXY_TEXTURE_3D
) {
2268 /* Proxy texture: check for errors and update proxy state */
2269 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2270 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
);
2272 struct gl_texture_unit
*texUnit
;
2273 struct gl_texture_image
*texImage
;
2274 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2275 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2276 _mesa_init_teximage_fields(ctx
, texImage
, width
, height
, depth
,
2277 border
, internalFormat
);
2278 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2279 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2280 internalFormat
, GL_NONE
, GL_NONE
,
2281 width
, height
, depth
, border
);
2284 /* if error, clear all proxy texture image parameters */
2285 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2286 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
2291 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB(target)" );
2298 _mesa_CompressedTexSubImage1DARB(GLenum target
, GLint level
, GLint xoffset
,
2299 GLsizei width
, GLenum format
,
2300 GLsizei imageSize
, const GLvoid
*data
)
2302 struct gl_texture_unit
*texUnit
;
2303 struct gl_texture_object
*texObj
;
2304 struct gl_texture_image
*texImage
;
2305 GET_CURRENT_CONTEXT(ctx
);
2306 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2308 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
2309 width
, 1, 1, format
, GL_NONE
)) {
2310 return; /* error was detected */
2313 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2314 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2315 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2318 if (width
== 0 || !data
)
2319 return; /* no-op, not an error */
2321 if (ctx
->Driver
.CompressedTexSubImage1D
) {
2322 (*ctx
->Driver
.CompressedTexSubImage1D
)(ctx
, target
, level
,
2324 format
, imageSize
, data
,
2327 ctx
->NewState
|= _NEW_TEXTURE
;
2332 _mesa_CompressedTexSubImage2DARB(GLenum target
, GLint level
, GLint xoffset
,
2333 GLint yoffset
, GLsizei width
, GLsizei height
,
2334 GLenum format
, GLsizei imageSize
,
2337 struct gl_texture_unit
*texUnit
;
2338 struct gl_texture_object
*texObj
;
2339 struct gl_texture_image
*texImage
;
2340 GET_CURRENT_CONTEXT(ctx
);
2341 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2343 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2344 width
, height
, 1, format
, GL_NONE
)) {
2345 return; /* error was detected */
2348 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2349 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2350 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2353 if (width
== 0 || height
== 0 || !data
)
2354 return; /* no-op, not an error */
2356 if (ctx
->Driver
.CompressedTexSubImage2D
) {
2357 (*ctx
->Driver
.CompressedTexSubImage2D
)(ctx
, target
, level
,
2358 xoffset
, yoffset
, width
, height
,
2359 format
, imageSize
, data
,
2362 ctx
->NewState
|= _NEW_TEXTURE
;
2367 _mesa_CompressedTexSubImage3DARB(GLenum target
, GLint level
, GLint xoffset
,
2368 GLint yoffset
, GLint zoffset
, GLsizei width
,
2369 GLsizei height
, GLsizei depth
, GLenum format
,
2370 GLsizei imageSize
, const GLvoid
*data
)
2372 struct gl_texture_unit
*texUnit
;
2373 struct gl_texture_object
*texObj
;
2374 struct gl_texture_image
*texImage
;
2375 GET_CURRENT_CONTEXT(ctx
);
2376 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2378 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2379 width
, height
, depth
, format
, GL_NONE
)) {
2380 return; /* error was detected */
2383 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2384 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2385 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2388 if (width
== 0 || height
== 0 || depth
== 0 || !data
)
2389 return; /* no-op, not an error */
2391 if (ctx
->Driver
.CompressedTexSubImage3D
) {
2392 (*ctx
->Driver
.CompressedTexSubImage3D
)(ctx
, target
, level
,
2393 xoffset
, yoffset
, zoffset
,
2394 width
, height
, depth
,
2395 format
, imageSize
, data
,
2398 ctx
->NewState
|= _NEW_TEXTURE
;
2403 _mesa_GetCompressedTexImageARB(GLenum target
, GLint level
, GLvoid
*img
)
2405 const struct gl_texture_unit
*texUnit
;
2406 const struct gl_texture_object
*texObj
;
2407 struct gl_texture_image
*texImage
;
2408 GET_CURRENT_CONTEXT(ctx
);
2409 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2411 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
2412 _mesa_error( ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)" );
2416 if (is_proxy_target(target
)) {
2417 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB(target)");
2421 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2422 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2423 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2426 /* invalid mipmap level */
2427 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
2431 if (!texImage
->IsCompressed
) {
2432 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetCompressedTexImageARB");
2439 if (ctx
->Extensions
.ARB_texture_compression
) {
2440 ASSERT(ctx
->Driver
.GetCompressedTexImage
);
2441 (*ctx
->Driver
.GetCompressedTexImage
)(ctx
, target
, level
, img
, texObj
,