1 /* $Id: teximage.c,v 1.94 2001/05/21 16:41:03 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
)
332 tObj
->Image
[level
] = texImage
;
334 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
335 tObj
->Image
[level
] = texImage
;
337 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
338 tObj
->NegX
[level
] = texImage
;
340 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
341 tObj
->PosY
[level
] = texImage
;
343 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
344 tObj
->NegY
[level
] = texImage
;
346 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
347 tObj
->PosZ
[level
] = texImage
;
349 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
350 tObj
->NegZ
[level
] = texImage
;
353 _mesa_problem(NULL
, "bad target in _mesa_set_tex_image()");
361 * Return new gl_texture_image struct with all fields initialized to zero.
363 struct gl_texture_image
*
364 _mesa_alloc_texture_image( void )
366 return CALLOC_STRUCT(gl_texture_image
);
372 _mesa_free_texture_image( struct gl_texture_image
*teximage
)
374 if (teximage
->Data
) {
375 FREE( teximage
->Data
);
376 teximage
->Data
= NULL
;
383 * Return GL_TRUE if the target is a proxy target.
386 is_proxy_target(GLenum target
)
388 return (target
== GL_PROXY_TEXTURE_1D
||
389 target
== GL_PROXY_TEXTURE_2D
||
390 target
== GL_PROXY_TEXTURE_3D
||
391 target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
);
396 * Given a texture unit and a texture target, return the corresponding
399 struct gl_texture_object
*
400 _mesa_select_tex_object(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
405 return texUnit
->Current1D
;
406 case GL_PROXY_TEXTURE_1D
:
407 return ctx
->Texture
.Proxy1D
;
409 return texUnit
->Current2D
;
410 case GL_PROXY_TEXTURE_2D
:
411 return ctx
->Texture
.Proxy2D
;
413 return texUnit
->Current3D
;
414 case GL_PROXY_TEXTURE_3D
:
415 return ctx
->Texture
.Proxy3D
;
416 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
417 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
418 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
419 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
420 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
421 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
422 case GL_TEXTURE_CUBE_MAP_ARB
:
423 return ctx
->Extensions
.ARB_texture_cube_map
424 ? texUnit
->CurrentCubeMap
: NULL
;
425 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
426 return ctx
->Extensions
.ARB_texture_cube_map
427 ? ctx
->Texture
.ProxyCubeMap
: NULL
;
429 _mesa_problem(NULL
, "bad target in _mesa_select_tex_object()");
436 * Return the texture image struct which corresponds to target and level
437 * for the given texture unit.
439 struct gl_texture_image
*
440 _mesa_select_tex_image(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
441 GLenum target
, GLint level
)
446 return texUnit
->Current1D
->Image
[level
];
447 case GL_PROXY_TEXTURE_1D
:
448 return ctx
->Texture
.Proxy1D
->Image
[level
];
450 return texUnit
->Current2D
->Image
[level
];
451 case GL_PROXY_TEXTURE_2D
:
452 return ctx
->Texture
.Proxy2D
->Image
[level
];
454 return texUnit
->Current3D
->Image
[level
];
455 case GL_PROXY_TEXTURE_3D
:
456 return ctx
->Texture
.Proxy3D
->Image
[level
];
457 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
458 if (ctx
->Extensions
.ARB_texture_cube_map
)
459 return texUnit
->CurrentCubeMap
->Image
[level
];
462 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
463 if (ctx
->Extensions
.ARB_texture_cube_map
)
464 return texUnit
->CurrentCubeMap
->NegX
[level
];
467 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
468 if (ctx
->Extensions
.ARB_texture_cube_map
)
469 return texUnit
->CurrentCubeMap
->PosY
[level
];
472 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
473 if (ctx
->Extensions
.ARB_texture_cube_map
)
474 return texUnit
->CurrentCubeMap
->NegY
[level
];
477 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
478 if (ctx
->Extensions
.ARB_texture_cube_map
)
479 return texUnit
->CurrentCubeMap
->PosZ
[level
];
482 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
483 if (ctx
->Extensions
.ARB_texture_cube_map
)
484 return texUnit
->CurrentCubeMap
->NegZ
[level
];
487 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
488 if (ctx
->Extensions
.ARB_texture_cube_map
)
489 return ctx
->Texture
.ProxyCubeMap
->Image
[level
];
493 _mesa_problem(ctx
, "bad target in _mesa_select_tex_image()");
501 * glTexImage[123]D can accept a NULL image pointer. In this case we
502 * create a texture image with unspecified image contents per the OpenGL
506 make_null_texture(GLint width
, GLint height
, GLint depth
, GLenum format
)
508 const GLint components
= _mesa_components_in_format(format
);
509 const GLint numPixels
= width
* height
* depth
;
510 GLubyte
*data
= (GLubyte
*) MALLOC(numPixels
* components
* sizeof(GLubyte
));
513 * Let's see if anyone finds this. If glTexImage2D() is called with
514 * a NULL image pointer then load the texture image with something
515 * interesting instead of leaving it indeterminate.
518 static const char message
[8][32] = {
522 " X X XXXX XXX XXXXX ",
525 " X X XXXXX XXX X X ",
529 GLubyte
*imgPtr
= data
;
531 for (h
= 0; h
< depth
; h
++) {
532 for (i
= 0; i
< height
; i
++) {
533 GLint srcRow
= 7 - (i
% 8);
534 for (j
= 0; j
< width
; j
++) {
535 GLint srcCol
= j
% 32;
536 GLubyte texel
= (message
[srcRow
][srcCol
]=='X') ? 255 : 70;
537 for (k
= 0; k
< components
; k
++) {
551 * Reset the fields of a gl_texture_image struct to zero.
552 * This is called when a proxy texture test fails, we set all the
553 * image members (except DriverData) to zero.
554 * It's also used in glTexImage[123]D as a safeguard to be sure all
555 * required fields get initialized properly by the Driver.TexImage[123]D
559 clear_teximage_fields(struct gl_texture_image
*img
)
575 img
->TexFormat
= &_mesa_null_texformat
;
576 img
->FetchTexel
= NULL
;
577 img
->IsCompressed
= 0;
578 img
->CompressedSize
= 0;
583 * Initialize basic fields of the gl_texture_image struct.
586 _mesa_init_teximage_fields(GLcontext
*ctx
,
587 struct gl_texture_image
*img
,
588 GLsizei width
, GLsizei height
, GLsizei depth
,
589 GLint border
, GLenum internalFormat
)
592 img
->Format
= _mesa_base_tex_format( ctx
, internalFormat
);
593 img
->IntFormat
= internalFormat
;
594 img
->Border
= border
;
596 img
->Height
= height
;
598 img
->WidthLog2
= logbase2(width
- 2 * border
);
599 if (height
== 1) /* 1-D texture */
602 img
->HeightLog2
= logbase2(height
- 2 * border
);
603 if (depth
== 1) /* 2-D texture */
606 img
->DepthLog2
= logbase2(depth
- 2 * border
);
607 img
->Width2
= 1 << img
->WidthLog2
;
608 img
->Height2
= 1 << img
->HeightLog2
;
609 img
->Depth2
= 1 << img
->DepthLog2
;
610 img
->MaxLog2
= MAX2(img
->WidthLog2
, img
->HeightLog2
);
611 img
->IsCompressed
= is_compressed_format(ctx
, internalFormat
);
617 * Test glTexImage[123]D() parameters for errors.
619 * dimensions - must be 1 or 2 or 3
620 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
623 texture_error_check( GLcontext
*ctx
, GLenum target
,
624 GLint level
, GLint internalFormat
,
625 GLenum format
, GLenum type
,
627 GLint width
, GLint height
,
628 GLint depth
, GLint border
)
633 if (dimensions
== 1) {
634 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_1D
);
635 if (target
!= GL_TEXTURE_1D
&& !isProxy
) {
636 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
640 else if (dimensions
== 2) {
641 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_2D
||
642 target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
);
643 if (target
!= GL_TEXTURE_2D
&& !isProxy
&&
644 !(ctx
->Extensions
.ARB_texture_cube_map
&&
645 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
646 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
647 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
651 else if (dimensions
== 3) {
652 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_3D
);
653 if (target
!= GL_TEXTURE_3D
&& !isProxy
) {
654 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
659 _mesa_problem( ctx
, "bad dims in texture_error_check" );
664 if (border
!= 0 && border
!= 1) {
667 sprintf(message
, "glTexImage%dD(border=%d)", dimensions
, border
);
668 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
674 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
675 || logbase2( width
- 2 * border
) < 0) {
678 sprintf(message
, "glTexImage%dD(width=%d)", dimensions
, width
);
679 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
685 if (dimensions
>= 2) {
686 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
687 || logbase2( height
- 2 * border
) < 0) {
690 sprintf(message
, "glTexImage%dD(height=%d)", dimensions
, height
);
691 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
697 /* For cube map, width must equal height */
698 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
699 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
700 if (width
!= height
) {
702 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
709 if (dimensions
>= 3) {
710 if (depth
< 2 * border
|| depth
> 2 + ctx
->Const
.MaxTextureSize
711 || logbase2( depth
- 2 * border
) < 0) {
714 sprintf(message
, "glTexImage3D(depth=%d)", depth
);
715 _mesa_error( ctx
, GL_INVALID_VALUE
, message
);
722 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
725 sprintf(message
, "glTexImage%dD(level=%d)", dimensions
, level
);
726 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
731 /* For cube map, width must equal height */
732 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
733 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
734 if (width
!= height
) {
735 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
740 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
744 sprintf(message
, "glTexImage%dD(internalFormat=0x%x)", dimensions
,
746 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
751 if (!is_compressed_format( ctx
, internalFormat
) &&
752 !_mesa_is_legal_format_and_type( format
, type
)) {
753 /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
754 * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
758 sprintf(message
, "glTexImage%dD(format or type)", dimensions
);
759 _mesa_error(ctx
, GL_INVALID_OPERATION
, message
);
764 /* if we get here, the parameters are OK */
771 * Test glTexSubImage[123]D() parameters for errors.
773 * dimensions - must be 1 or 2 or 3
774 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
777 subtexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
778 GLenum target
, GLint level
,
779 GLint xoffset
, GLint yoffset
, GLint zoffset
,
780 GLint width
, GLint height
, GLint depth
,
781 GLenum format
, GLenum type
)
783 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
784 struct gl_texture_image
*destTex
;
786 if (dimensions
== 1) {
787 if (target
!= GL_TEXTURE_1D
) {
788 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(target)" );
792 else if (dimensions
== 2) {
793 if (ctx
->Extensions
.ARB_texture_cube_map
) {
794 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
795 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
796 target
!= GL_TEXTURE_2D
) {
797 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
801 else if (target
!= GL_TEXTURE_2D
) {
802 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
806 else if (dimensions
== 3) {
807 if (target
!= GL_TEXTURE_3D
) {
808 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3D(target)" );
813 _mesa_problem( ctx
, "bad dims in texture_error_check" );
817 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
819 sprintf(message
, "glTexSubImage2D(level=%d)", level
);
820 _mesa_error(ctx
, GL_INVALID_ENUM
, message
);
826 sprintf(message
, "glTexSubImage%dD(width=%d)", dimensions
, width
);
827 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
830 if (height
< 0 && dimensions
> 1) {
832 sprintf(message
, "glTexSubImage%dD(height=%d)", dimensions
, height
);
833 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
836 if (depth
< 0 && dimensions
> 2) {
838 sprintf(message
, "glTexSubImage%dD(depth=%d)", dimensions
, depth
);
839 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
843 destTex
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
846 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glTexSubImage2D");
850 if (xoffset
< -((GLint
)destTex
->Border
)) {
851 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset)");
854 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
855 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset+width)");
858 if (dimensions
> 1) {
859 if (yoffset
< -((GLint
)destTex
->Border
)) {
860 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset)");
863 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
864 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset+height)");
868 if (dimensions
> 2) {
869 if (zoffset
< -((GLint
)destTex
->Border
)) {
870 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset)");
873 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+ destTex
->Border
)) {
874 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset+depth)");
879 if (!is_compressed_format(ctx
, destTex
->IntFormat
) &&
880 !_mesa_is_legal_format_and_type(format
, type
)) {
882 sprintf(message
, "glTexSubImage%dD(format or type)", dimensions
);
883 _mesa_error(ctx
, GL_INVALID_ENUM
, message
);
892 * Test glCopyTexImage[12]D() parameters for errors.
893 * Input: dimensions - must be 1 or 2 or 3
894 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
897 copytexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
898 GLenum target
, GLint level
, GLint internalFormat
,
899 GLint width
, GLint height
, GLint border
)
903 if (dimensions
== 1) {
904 if (target
!= GL_TEXTURE_1D
) {
905 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
909 else if (dimensions
== 2) {
910 if (ctx
->Extensions
.ARB_texture_cube_map
) {
911 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
912 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
913 target
!= GL_TEXTURE_2D
) {
914 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
918 else if (target
!= GL_TEXTURE_2D
) {
919 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
925 if (border
!= 0 && border
!= 1) {
927 sprintf(message
, "glCopyTexImage%dD(border)", dimensions
);
928 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
933 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
934 || logbase2( width
- 2 * border
) < 0) {
936 sprintf(message
, "glCopyTexImage%dD(width=%d)", dimensions
, width
);
937 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
942 if (dimensions
>= 2) {
943 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
944 || logbase2( height
- 2 * border
) < 0) {
946 sprintf(message
, "glCopyTexImage%dD(height=%d)", dimensions
, height
);
947 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
952 /* For cube map, width must equal height */
953 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
954 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
955 if (width
!= height
) {
956 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(width != height)");
962 if (level
< 0 || level
>=ctx
->Const
.MaxTextureLevels
) {
964 sprintf(message
, "glCopyTexImage%dD(level=%d)", dimensions
, level
);
965 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
969 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
972 sprintf(message
, "glCopyTexImage%dD(internalFormat)", dimensions
);
973 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
977 /* if we get here, the parameters are OK */
983 copytexsubimage_error_check( GLcontext
*ctx
, GLuint dimensions
,
984 GLenum target
, GLint level
,
985 GLint xoffset
, GLint yoffset
, GLint zoffset
,
986 GLsizei width
, GLsizei height
)
988 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
989 struct gl_texture_image
*teximage
;
991 if (dimensions
== 1) {
992 if (target
!= GL_TEXTURE_1D
) {
993 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
997 else if (dimensions
== 2) {
998 if (ctx
->Extensions
.ARB_texture_cube_map
) {
999 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1000 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1001 target
!= GL_TEXTURE_2D
) {
1002 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1006 else if (target
!= GL_TEXTURE_2D
) {
1007 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1011 else if (dimensions
== 3) {
1012 if (target
!= GL_TEXTURE_3D
) {
1013 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3D(target)" );
1018 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1020 sprintf(message
, "glCopyTexSubImage%dD(level=%d)", dimensions
, level
);
1021 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1027 sprintf(message
, "glCopyTexSubImage%dD(width=%d)", dimensions
, width
);
1028 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1031 if (dimensions
> 1 && height
< 0) {
1033 sprintf(message
, "glCopyTexSubImage%dD(height=%d)", dimensions
, height
);
1034 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1038 teximage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1041 sprintf(message
, "glCopyTexSubImage%dD(undefined texture)", dimensions
);
1042 _mesa_error(ctx
, GL_INVALID_OPERATION
, message
);
1046 if (xoffset
< -((GLint
)teximage
->Border
)) {
1048 sprintf(message
, "glCopyTexSubImage%dD(xoffset=%d)", dimensions
, xoffset
);
1049 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1052 if (xoffset
+ width
> (GLint
) (teximage
->Width
+ teximage
->Border
)) {
1054 sprintf(message
, "glCopyTexSubImage%dD(xoffset+width)", dimensions
);
1055 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1058 if (dimensions
> 1) {
1059 if (yoffset
< -((GLint
)teximage
->Border
)) {
1061 sprintf(message
, "glCopyTexSubImage%dD(yoffset=%d)", dimensions
, yoffset
);
1062 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1065 /* NOTE: we're adding the border here, not subtracting! */
1066 if (yoffset
+ height
> (GLint
) (teximage
->Height
+ teximage
->Border
)) {
1068 sprintf(message
, "glCopyTexSubImage%dD(yoffset+height)", dimensions
);
1069 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1074 if (dimensions
> 2) {
1075 if (zoffset
< -((GLint
)teximage
->Border
)) {
1077 sprintf(message
, "glCopyTexSubImage%dD(zoffset)", dimensions
);
1078 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1081 if (zoffset
> (GLint
) (teximage
->Depth
+ teximage
->Border
)) {
1083 sprintf(message
, "glCopyTexSubImage%dD(zoffset+depth)", dimensions
);
1084 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1089 /* if we get here, the parameters are OK */
1096 _mesa_GetTexImage( GLenum target
, GLint level
, GLenum format
,
1097 GLenum type
, GLvoid
*pixels
)
1099 const struct gl_texture_unit
*texUnit
;
1100 const struct gl_texture_object
*texObj
;
1101 struct gl_texture_image
*texImage
;
1102 GET_CURRENT_CONTEXT(ctx
);
1103 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1105 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1106 _mesa_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
1110 if (_mesa_sizeof_type(type
) <= 0) {
1111 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
1115 if (_mesa_components_in_format(format
) <= 0 ||
1116 format
== GL_STENCIL_INDEX
) {
1117 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
1121 if (!ctx
->Extensions
.EXT_paletted_texture
&& is_index_format(format
)) {
1122 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1125 if (!ctx
->Extensions
.SGIX_depth_texture
&& format
== GL_DEPTH_COMPONENT
) {
1126 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1129 /* XXX what if format/type doesn't match texture format/type? */
1134 texUnit
= &(ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
]);
1135 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1136 if (!texObj
|| is_proxy_target(target
)) {
1137 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)");
1141 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1143 /* invalid mipmap level, not an error */
1147 if (!texImage
->Data
) {
1148 /* no image data, not an error */
1152 if (ctx
->NewState
& _NEW_PIXEL
)
1153 _mesa_update_state(ctx
);
1155 if (is_color_format(format
) &&
1156 ctx
->_ImageTransferState
& IMAGE_CONVOLUTION_BIT
) {
1157 /* convert texture image to GL_RGBA, GL_FLOAT */
1158 GLint width
= texImage
->Width
;
1159 GLint height
= texImage
->Height
;
1160 GLint depth
= texImage
->Depth
;
1162 GLfloat
*tmpImage
, *convImage
;
1163 tmpImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
1165 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
1168 convImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
1171 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
1175 for (img
= 0; img
< depth
; img
++) {
1176 GLint convWidth
, convHeight
;
1178 /* convert texture data to GLfloat/GL_RGBA */
1179 for (row
= 0; row
< height
; row
++) {
1180 GLchan texels
[1 << MAX_TEXTURE_LEVELS
][4];
1182 GLfloat
*dst
= tmpImage
+ row
* width
* 4;
1183 for (col
= 0; col
< width
; col
++) {
1184 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1187 _mesa_unpack_float_color_span(ctx
, width
, GL_RGBA
, dst
,
1188 GL_RGBA
, CHAN_TYPE
, texels
,
1189 &_mesa_native_packing
,
1190 ctx
->_ImageTransferState
& IMAGE_PRE_CONVOLUTION_BITS
,
1195 convHeight
= height
;
1198 if (target
== GL_TEXTURE_1D
) {
1199 if (ctx
->Pixel
.Convolution1DEnabled
) {
1200 _mesa_convolve_1d_image(ctx
, &convWidth
, tmpImage
, convImage
);
1204 if (ctx
->Pixel
.Convolution2DEnabled
) {
1205 _mesa_convolve_2d_image(ctx
, &convWidth
, &convHeight
,
1206 tmpImage
, convImage
);
1208 else if (ctx
->Pixel
.Separable2DEnabled
) {
1209 _mesa_convolve_sep_image(ctx
, &convWidth
, &convHeight
,
1210 tmpImage
, convImage
);
1214 /* pack convolved image */
1215 for (row
= 0; row
< convHeight
; row
++) {
1216 const GLfloat
*src
= convImage
+ row
* convWidth
* 4;
1217 GLvoid
*dest
= _mesa_image_address(&ctx
->Pack
, pixels
,
1218 convWidth
, convHeight
,
1219 format
, type
, img
, row
, 0);
1220 _mesa_pack_float_rgba_span(ctx
, convWidth
,
1221 (const GLfloat(*)[4]) src
,
1222 format
, type
, dest
, &ctx
->Pack
,
1223 ctx
->_ImageTransferState
& IMAGE_POST_CONVOLUTION_BITS
);
1231 /* no convolution, or non-rgba image */
1232 GLint width
= texImage
->Width
;
1233 GLint height
= texImage
->Height
;
1234 GLint depth
= texImage
->Depth
;
1236 for (img
= 0; img
< depth
; img
++) {
1237 for (row
= 0; row
< height
; row
++) {
1238 /* compute destination address in client memory */
1239 GLvoid
*dest
= _mesa_image_address( &ctx
->Unpack
, pixels
,
1240 width
, height
, format
, type
,
1244 if (format
== GL_COLOR_INDEX
) {
1245 GLuint indexRow
[MAX_WIDTH
];
1247 for (col
= 0; col
< width
; col
++) {
1248 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1249 (GLvoid
*) &indexRow
[col
]);
1251 _mesa_pack_index_span(ctx
, width
, type
, dest
,
1252 indexRow
, &ctx
->Pack
,
1253 ctx
->_ImageTransferState
);
1255 else if (format
== GL_DEPTH_COMPONENT
) {
1256 GLfloat depthRow
[MAX_WIDTH
];
1258 for (col
= 0; col
< width
; col
++) {
1259 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1260 (GLvoid
*) &depthRow
[col
]);
1262 _mesa_pack_depth_span(ctx
, width
, dest
, type
,
1263 depthRow
, &ctx
->Pack
);
1266 /* general case: convert row to RGBA format */
1267 GLchan rgba
[MAX_WIDTH
][4];
1269 for (col
= 0; col
< width
; col
++) {
1270 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1271 (GLvoid
*) rgba
[col
]);
1273 _mesa_pack_rgba_span(ctx
, width
, (const GLchan (*)[4])rgba
,
1274 format
, type
, dest
, &ctx
->Pack
,
1275 ctx
->_ImageTransferState
);
1285 * Called from the API. Note that width includes the border.
1288 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
1289 GLsizei width
, GLint border
, GLenum format
,
1290 GLenum type
, const GLvoid
*pixels
)
1292 GLsizei postConvWidth
= width
;
1293 GET_CURRENT_CONTEXT(ctx
);
1294 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1296 if (is_color_format(internalFormat
)) {
1297 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1300 if (target
== GL_TEXTURE_1D
) {
1301 struct gl_texture_unit
*texUnit
;
1302 struct gl_texture_object
*texObj
;
1303 struct gl_texture_image
*texImage
;
1305 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1306 format
, type
, 1, postConvWidth
, 1, 1, border
)) {
1307 return; /* error was recorded */
1310 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1311 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1312 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1315 texImage
= _mesa_alloc_texture_image();
1316 texObj
->Image
[level
] = texImage
;
1318 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
1322 else if (texImage
->Data
) {
1323 /* free the old texture data */
1324 FREE(texImage
->Data
);
1325 texImage
->Data
= NULL
;
1327 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1328 _mesa_init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1329 border
, internalFormat
);
1331 if (ctx
->NewState
& _NEW_PIXEL
)
1332 _mesa_update_state(ctx
);
1334 ASSERT(ctx
->Driver
.TexImage1D
);
1336 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1337 width
, border
, format
, type
, pixels
,
1338 &ctx
->Unpack
, texObj
, texImage
);
1341 GLubyte
*dummy
= make_null_texture(width
, 1, 1, format
);
1343 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1345 format
, GL_UNSIGNED_BYTE
, dummy
,
1346 &_mesa_native_packing
, texObj
, texImage
);
1351 ASSERT(texImage
->TexFormat
);
1352 if (!texImage
->FetchTexel
) {
1353 /* If driver didn't explicitly set this, use the default */
1354 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel1D
;
1356 ASSERT(texImage
->FetchTexel
);
1359 texObj
->Complete
= GL_FALSE
;
1360 ctx
->NewState
|= _NEW_TEXTURE
;
1362 else if (target
== GL_PROXY_TEXTURE_1D
) {
1363 /* Proxy texture: check for errors and update proxy state */
1364 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1366 postConvWidth
, 1, 1, border
);
1368 struct gl_texture_unit
*texUnit
;
1369 struct gl_texture_image
*texImage
;
1370 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1371 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1372 _mesa_init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1373 border
, internalFormat
);
1374 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1375 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1376 internalFormat
, format
, type
,
1377 postConvWidth
, 1, 1, border
);
1380 /* if error, clear all proxy texture image parameters */
1381 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1382 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
1387 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1394 _mesa_TexImage2D( GLenum target
, GLint level
, GLint internalFormat
,
1395 GLsizei width
, GLsizei height
, GLint border
,
1396 GLenum format
, GLenum type
,
1397 const GLvoid
*pixels
)
1399 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1400 GET_CURRENT_CONTEXT(ctx
);
1401 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1403 if (is_color_format(internalFormat
)) {
1404 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1408 if (target
== GL_TEXTURE_2D
||
1409 (ctx
->Extensions
.ARB_texture_cube_map
&&
1410 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1411 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
1412 /* non-proxy target */
1413 struct gl_texture_unit
*texUnit
;
1414 struct gl_texture_object
*texObj
;
1415 struct gl_texture_image
*texImage
;
1417 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1418 format
, type
, 2, postConvWidth
, postConvHeight
,
1420 return; /* error was recorded */
1423 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1424 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1425 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1428 texImage
= _mesa_alloc_texture_image();
1429 _mesa_set_tex_image(texObj
, target
, level
, texImage
);
1431 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1435 else if (texImage
->Data
) {
1436 /* free the old texture data */
1437 FREE(texImage
->Data
);
1438 texImage
->Data
= NULL
;
1440 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1441 _mesa_init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
,
1442 1, border
, internalFormat
);
1444 if (ctx
->NewState
& _NEW_PIXEL
)
1445 _mesa_update_state(ctx
);
1447 ASSERT(ctx
->Driver
.TexImage2D
);
1449 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1450 width
, height
, border
, format
, type
, pixels
,
1451 &ctx
->Unpack
, texObj
, texImage
);
1454 GLubyte
*dummy
= make_null_texture(width
, height
, 1, format
);
1456 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1457 width
, height
, border
,
1458 format
, GL_UNSIGNED_BYTE
, dummy
,
1459 &_mesa_native_packing
, texObj
, texImage
);
1464 ASSERT(texImage
->TexFormat
);
1465 if (!texImage
->FetchTexel
) {
1466 /* If driver didn't explicitly set this, use the default */
1467 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel2D
;
1469 ASSERT(texImage
->FetchTexel
);
1472 texObj
->Complete
= GL_FALSE
;
1473 ctx
->NewState
|= _NEW_TEXTURE
;
1475 else if (target
== GL_PROXY_TEXTURE_2D
) {
1476 /* Proxy texture: check for errors and update proxy state */
1477 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1479 postConvWidth
, postConvHeight
, 1, border
);
1481 struct gl_texture_unit
*texUnit
;
1482 struct gl_texture_image
*texImage
;
1483 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1484 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1485 _mesa_init_teximage_fields(ctx
, texImage
, postConvWidth
,
1486 postConvHeight
, 1, border
, internalFormat
);
1487 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1488 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1489 internalFormat
, format
, type
,
1490 postConvWidth
, postConvHeight
, 1, border
);
1493 /* if error, clear all proxy texture image parameters */
1494 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1495 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
1500 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1507 * Called by the API or display list executor.
1508 * Note that width and height include the border.
1511 _mesa_TexImage3D( GLenum target
, GLint level
, GLenum internalFormat
,
1512 GLsizei width
, GLsizei height
, GLsizei depth
,
1513 GLint border
, GLenum format
, GLenum type
,
1514 const GLvoid
*pixels
)
1516 GET_CURRENT_CONTEXT(ctx
);
1517 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1519 if (target
== GL_TEXTURE_3D
) {
1520 struct gl_texture_unit
*texUnit
;
1521 struct gl_texture_object
*texObj
;
1522 struct gl_texture_image
*texImage
;
1524 if (texture_error_check(ctx
, target
, level
, (GLint
) internalFormat
,
1525 format
, type
, 3, width
, height
, depth
, border
)) {
1526 return; /* error was recorded */
1529 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1530 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1531 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1534 texImage
= _mesa_alloc_texture_image();
1535 texObj
->Image
[level
] = texImage
;
1537 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
1541 else if (texImage
->Data
) {
1542 FREE(texImage
->Data
);
1543 texImage
->Data
= NULL
;
1545 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1546 _mesa_init_teximage_fields(ctx
, texImage
, width
, height
, depth
, border
,
1549 if (ctx
->NewState
& _NEW_PIXEL
)
1550 _mesa_update_state(ctx
);
1552 ASSERT(ctx
->Driver
.TexImage3D
);
1554 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, (GLint
) internalFormat
,
1555 width
, height
, depth
, border
,
1556 format
, type
, pixels
,
1557 &ctx
->Unpack
, texObj
, texImage
);
1560 GLubyte
*dummy
= make_null_texture(width
, height
, depth
, format
);
1562 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
,
1563 (GLint
) internalFormat
,
1564 width
, height
, depth
, border
,
1565 format
, GL_UNSIGNED_BYTE
, dummy
,
1566 &_mesa_native_packing
, texObj
, texImage
);
1571 ASSERT(texImage
->TexFormat
);
1572 if (!texImage
->FetchTexel
) {
1573 /* If driver didn't explicitly set this, use the default */
1574 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel3D
;
1576 ASSERT(texImage
->FetchTexel
);
1579 texObj
->Complete
= GL_FALSE
;
1580 ctx
->NewState
|= _NEW_TEXTURE
;
1582 else if (target
== GL_PROXY_TEXTURE_3D
) {
1583 /* Proxy texture: check for errors and update proxy state */
1584 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1585 format
, type
, 3, width
, height
, depth
, border
);
1587 struct gl_texture_unit
*texUnit
;
1588 struct gl_texture_image
*texImage
;
1589 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1590 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1591 _mesa_init_teximage_fields(ctx
, texImage
, width
, height
, 1,
1592 border
, internalFormat
);
1593 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1594 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1595 internalFormat
, format
, type
,
1596 width
, height
, depth
, border
);
1599 /* if error, clear all proxy texture image parameters */
1600 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1601 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
1606 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1613 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
1614 GLsizei width
, GLsizei height
, GLsizei depth
,
1615 GLint border
, GLenum format
, GLenum type
,
1616 const GLvoid
*pixels
)
1618 _mesa_TexImage3D(target
, level
, internalFormat
, width
, height
,
1619 depth
, border
, format
, type
, pixels
);
1625 _mesa_TexSubImage1D( GLenum target
, GLint level
,
1626 GLint xoffset
, GLsizei width
,
1627 GLenum format
, GLenum type
,
1628 const GLvoid
*pixels
)
1630 GLsizei postConvWidth
= width
;
1631 struct gl_texture_unit
*texUnit
;
1632 struct gl_texture_object
*texObj
;
1633 struct gl_texture_image
*texImage
;
1634 GET_CURRENT_CONTEXT(ctx
);
1635 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1637 if (ctx
->NewState
& _NEW_PIXEL
)
1638 _mesa_update_state(ctx
);
1640 /* XXX should test internal format */
1641 if (is_color_format(format
)) {
1642 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1645 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
1646 postConvWidth
, 1, 1, format
, type
)) {
1647 return; /* error was detected */
1650 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1651 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1652 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1655 if (width
== 0 || !pixels
)
1656 return; /* no-op, not an error */
1658 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1659 xoffset
+= texImage
->Border
;
1661 ASSERT(ctx
->Driver
.TexSubImage1D
);
1662 (*ctx
->Driver
.TexSubImage1D
)(ctx
, target
, level
, xoffset
, width
,
1663 format
, type
, pixels
, &ctx
->Unpack
,
1665 ctx
->NewState
|= _NEW_TEXTURE
;
1670 _mesa_TexSubImage2D( GLenum target
, GLint level
,
1671 GLint xoffset
, GLint yoffset
,
1672 GLsizei width
, GLsizei height
,
1673 GLenum format
, GLenum type
,
1674 const GLvoid
*pixels
)
1676 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1677 struct gl_texture_unit
*texUnit
;
1678 struct gl_texture_object
*texObj
;
1679 struct gl_texture_image
*texImage
;
1680 GET_CURRENT_CONTEXT(ctx
);
1681 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1683 if (ctx
->NewState
& _NEW_PIXEL
)
1684 _mesa_update_state(ctx
);
1686 /* XXX should test internal format */
1687 if (is_color_format(format
)) {
1688 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1692 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1693 postConvWidth
, postConvHeight
, 1, format
, type
)) {
1694 return; /* error was detected */
1697 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1698 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1699 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1702 if (width
== 0 || height
== 0 || !pixels
)
1703 return; /* no-op, not an error */
1705 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1706 xoffset
+= texImage
->Border
;
1707 yoffset
+= texImage
->Border
;
1709 ASSERT(ctx
->Driver
.TexSubImage2D
);
1710 (*ctx
->Driver
.TexSubImage2D
)(ctx
, target
, level
, xoffset
, yoffset
,
1711 width
, height
, format
, type
, pixels
,
1712 &ctx
->Unpack
, texObj
, texImage
);
1713 ctx
->NewState
|= _NEW_TEXTURE
;
1719 _mesa_TexSubImage3D( GLenum target
, GLint level
,
1720 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1721 GLsizei width
, GLsizei height
, GLsizei depth
,
1722 GLenum format
, GLenum type
,
1723 const GLvoid
*pixels
)
1725 struct gl_texture_unit
*texUnit
;
1726 struct gl_texture_object
*texObj
;
1727 struct gl_texture_image
*texImage
;
1728 GET_CURRENT_CONTEXT(ctx
);
1729 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1731 if (ctx
->NewState
& _NEW_PIXEL
)
1732 _mesa_update_state(ctx
);
1734 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
1735 width
, height
, depth
, format
, type
)) {
1736 return; /* error was detected */
1739 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1740 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1741 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1744 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
1745 return; /* no-op, not an error */
1747 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1748 xoffset
+= texImage
->Border
;
1749 yoffset
+= texImage
->Border
;
1750 zoffset
+= texImage
->Border
;
1752 ASSERT(ctx
->Driver
.TexSubImage3D
);
1753 (*ctx
->Driver
.TexSubImage3D
)(ctx
, target
, level
,
1754 xoffset
, yoffset
, zoffset
,
1755 width
, height
, depth
,
1756 format
, type
, pixels
,
1757 &ctx
->Unpack
, texObj
, texImage
);
1758 ctx
->NewState
|= _NEW_TEXTURE
;
1764 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
1765 GLenum internalFormat
,
1767 GLsizei width
, GLint border
)
1769 struct gl_texture_unit
*texUnit
;
1770 struct gl_texture_object
*texObj
;
1771 struct gl_texture_image
*texImage
;
1772 GLsizei postConvWidth
= width
;
1773 GET_CURRENT_CONTEXT(ctx
);
1774 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1776 if (ctx
->NewState
& _NEW_PIXEL
)
1777 _mesa_update_state(ctx
);
1779 if (is_color_format(internalFormat
)) {
1780 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1783 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
1784 postConvWidth
, 1, border
))
1787 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1788 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1789 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1791 texImage
= _mesa_alloc_texture_image();
1792 _mesa_set_tex_image(texObj
, target
, level
, texImage
);
1794 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D");
1798 else if (texImage
->Data
) {
1799 /* free the old texture data */
1800 FREE(texImage
->Data
);
1801 texImage
->Data
= NULL
;
1804 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1805 _mesa_init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1806 border
, internalFormat
);
1809 ASSERT(ctx
->Driver
.CopyTexImage1D
);
1810 (*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
, internalFormat
,
1811 x
, y
, width
, border
);
1813 ASSERT(texImage
->TexFormat
);
1814 if (!texImage
->FetchTexel
) {
1815 /* If driver didn't explicitly set this, use the default */
1816 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel1D
;
1818 ASSERT(texImage
->FetchTexel
);
1821 texObj
->Complete
= GL_FALSE
;
1822 ctx
->NewState
|= _NEW_TEXTURE
;
1828 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
1829 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1832 struct gl_texture_unit
*texUnit
;
1833 struct gl_texture_object
*texObj
;
1834 struct gl_texture_image
*texImage
;
1835 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1836 GET_CURRENT_CONTEXT(ctx
);
1837 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1839 if (ctx
->NewState
& _NEW_PIXEL
)
1840 _mesa_update_state(ctx
);
1842 if (is_color_format(internalFormat
)) {
1843 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1847 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
1848 postConvWidth
, postConvHeight
, border
))
1851 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1852 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1853 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1855 texImage
= _mesa_alloc_texture_image();
1856 _mesa_set_tex_image(texObj
, target
, level
, texImage
);
1858 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D");
1862 else if (texImage
->Data
) {
1863 /* free the old texture data */
1864 FREE(texImage
->Data
);
1865 texImage
->Data
= NULL
;
1868 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1869 _mesa_init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
, 1,
1870 border
, internalFormat
);
1872 ASSERT(ctx
->Driver
.CopyTexImage2D
);
1873 (*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
, internalFormat
,
1874 x
, y
, width
, height
, border
);
1876 ASSERT(texImage
->TexFormat
);
1877 if (!texImage
->FetchTexel
) {
1878 /* If driver didn't explicitly set this, use the default */
1879 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel2D
;
1881 ASSERT(texImage
->FetchTexel
);
1884 texObj
->Complete
= GL_FALSE
;
1885 ctx
->NewState
|= _NEW_TEXTURE
;
1891 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
1892 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
1894 struct gl_texture_unit
*texUnit
;
1895 struct gl_texture_object
*texObj
;
1896 struct gl_texture_image
*texImage
;
1897 GLsizei postConvWidth
= width
;
1898 GET_CURRENT_CONTEXT(ctx
);
1899 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1901 if (ctx
->NewState
& _NEW_PIXEL
)
1902 _mesa_update_state(ctx
);
1904 /* XXX should test internal format */
1905 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1907 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
1908 xoffset
, 0, 0, postConvWidth
, 1))
1911 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1912 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1913 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1915 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1916 xoffset
+= texImage
->Border
;
1918 ASSERT(ctx
->Driver
.CopyTexSubImage1D
);
1919 (*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
, xoffset
, x
, y
, width
);
1920 ctx
->NewState
|= _NEW_TEXTURE
;
1926 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
1927 GLint xoffset
, GLint yoffset
,
1928 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1930 struct gl_texture_unit
*texUnit
;
1931 struct gl_texture_object
*texObj
;
1932 struct gl_texture_image
*texImage
;
1933 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1934 GET_CURRENT_CONTEXT(ctx
);
1935 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1937 if (ctx
->NewState
& _NEW_PIXEL
)
1938 _mesa_update_state(ctx
);
1940 /* XXX should test internal format */
1941 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
1943 if (copytexsubimage_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1944 postConvWidth
, postConvHeight
))
1947 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1948 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1949 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1951 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1952 xoffset
+= texImage
->Border
;
1953 yoffset
+= texImage
->Border
;
1955 ASSERT(ctx
->Driver
.CopyTexSubImage2D
);
1956 (*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
1957 xoffset
, yoffset
, x
, y
, width
, height
);
1958 ctx
->NewState
|= _NEW_TEXTURE
;
1964 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
1965 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1966 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1968 struct gl_texture_unit
*texUnit
;
1969 struct gl_texture_object
*texObj
;
1970 struct gl_texture_image
*texImage
;
1971 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1972 GET_CURRENT_CONTEXT(ctx
);
1973 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1975 if (ctx
->NewState
& _NEW_PIXEL
)
1976 _mesa_update_state(ctx
);
1978 /* XXX should test internal format */
1979 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
1981 if (copytexsubimage_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
,
1982 zoffset
, postConvWidth
, postConvHeight
))
1985 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1986 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1987 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1989 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1990 xoffset
+= texImage
->Border
;
1991 yoffset
+= texImage
->Border
;
1992 zoffset
+= texImage
->Border
;
1994 ASSERT(ctx
->Driver
.CopyTexSubImage3D
);
1995 (*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
1996 xoffset
, yoffset
, zoffset
,
1997 x
, y
, width
, height
);
1998 ctx
->NewState
|= _NEW_TEXTURE
;
2004 _mesa_CompressedTexImage1DARB(GLenum target
, GLint level
,
2005 GLenum internalFormat
, GLsizei width
,
2006 GLint border
, GLsizei imageSize
,
2009 GET_CURRENT_CONTEXT(ctx
);
2010 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2012 switch (internalFormat
) {
2013 case GL_COMPRESSED_ALPHA_ARB
:
2014 case GL_COMPRESSED_LUMINANCE_ARB
:
2015 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2016 case GL_COMPRESSED_INTENSITY_ARB
:
2017 case GL_COMPRESSED_RGB_ARB
:
2018 case GL_COMPRESSED_RGBA_ARB
:
2019 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB");
2022 /* silence compiler warning */
2026 if (target
== GL_TEXTURE_1D
) {
2027 struct gl_texture_unit
*texUnit
;
2028 struct gl_texture_object
*texObj
;
2029 struct gl_texture_image
*texImage
;
2031 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2032 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
2033 return; /* error in texture image was detected */
2036 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2037 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2038 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2041 texImage
= _mesa_alloc_texture_image();
2042 texObj
->Image
[level
] = texImage
;
2044 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage1DARB");
2048 else if (texImage
->Data
) {
2049 FREE(texImage
->Data
);
2050 texImage
->Data
= NULL
;
2053 _mesa_init_teximage_fields(ctx
, texImage
, width
, 1, 1,
2054 border
, internalFormat
);
2056 if (ctx
->Extensions
.ARB_texture_compression
) {
2057 ASSERT(ctx
->Driver
.CompressedTexImage1D
);
2058 (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
,
2059 internalFormat
, width
, border
,
2062 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2066 texObj
->Complete
= GL_FALSE
;
2067 ctx
->NewState
|= _NEW_TEXTURE
;
2069 else if (target
== GL_PROXY_TEXTURE_1D
) {
2070 /* Proxy texture: check for errors and update proxy state */
2071 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2072 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
);
2074 struct gl_texture_unit
*texUnit
;
2075 struct gl_texture_image
*texImage
;
2076 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2077 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2078 _mesa_init_teximage_fields(ctx
, texImage
, width
, 1, 1,
2079 border
, internalFormat
);
2080 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2081 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2082 internalFormat
, GL_NONE
, GL_NONE
,
2083 width
, 1, 1, border
);
2086 /* if error, clear all proxy texture image parameters */
2087 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2088 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
2093 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB(target)" );
2100 _mesa_CompressedTexImage2DARB(GLenum target
, GLint level
,
2101 GLenum internalFormat
, GLsizei width
,
2102 GLsizei height
, GLint border
, GLsizei imageSize
,
2105 GET_CURRENT_CONTEXT(ctx
);
2106 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2108 switch (internalFormat
) {
2109 case GL_COMPRESSED_ALPHA_ARB
:
2110 case GL_COMPRESSED_LUMINANCE_ARB
:
2111 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2112 case GL_COMPRESSED_INTENSITY_ARB
:
2113 case GL_COMPRESSED_RGB_ARB
:
2114 case GL_COMPRESSED_RGBA_ARB
:
2115 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB");
2118 /* silence compiler warning */
2122 if (target
== GL_TEXTURE_2D
||
2123 (ctx
->Extensions
.ARB_texture_cube_map
&&
2124 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2125 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
2126 struct gl_texture_unit
*texUnit
;
2127 struct gl_texture_object
*texObj
;
2128 struct gl_texture_image
*texImage
;
2130 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2131 GL_NONE
, GL_NONE
, 1, width
, height
, 1, border
)) {
2132 return; /* error in texture image was detected */
2135 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2136 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2137 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2140 texImage
= _mesa_alloc_texture_image();
2141 texObj
->Image
[level
] = texImage
;
2143 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
2147 else if (texImage
->Data
) {
2148 FREE(texImage
->Data
);
2149 texImage
->Data
= NULL
;
2152 _mesa_init_teximage_fields(ctx
, texImage
, width
, height
, 1, border
,
2155 if (ctx
->Extensions
.ARB_texture_compression
) {
2156 ASSERT(ctx
->Driver
.CompressedTexImage2D
);
2157 (*ctx
->Driver
.CompressedTexImage2D
)(ctx
, target
, level
,
2158 internalFormat
, width
, height
,
2159 border
, imageSize
, data
,
2161 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2165 texObj
->Complete
= GL_FALSE
;
2166 ctx
->NewState
|= _NEW_TEXTURE
;
2168 else if (target
== GL_PROXY_TEXTURE_2D
) {
2169 /* Proxy texture: check for errors and update proxy state */
2170 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2171 GL_NONE
, GL_NONE
, 2, width
, height
, 1, border
);
2173 struct gl_texture_unit
*texUnit
;
2174 struct gl_texture_image
*texImage
;
2175 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2176 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2177 _mesa_init_teximage_fields(ctx
, texImage
, width
, height
, 1,
2178 border
, internalFormat
);
2179 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2180 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2181 internalFormat
, GL_NONE
, GL_NONE
,
2182 width
, height
, 1, border
);
2185 /* if error, clear all proxy texture image parameters */
2186 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2187 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
2192 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB(target)" );
2199 _mesa_CompressedTexImage3DARB(GLenum target
, GLint level
,
2200 GLenum internalFormat
, GLsizei width
,
2201 GLsizei height
, GLsizei depth
, GLint border
,
2202 GLsizei imageSize
, const GLvoid
*data
)
2204 GET_CURRENT_CONTEXT(ctx
);
2205 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2207 switch (internalFormat
) {
2208 case GL_COMPRESSED_ALPHA_ARB
:
2209 case GL_COMPRESSED_LUMINANCE_ARB
:
2210 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2211 case GL_COMPRESSED_INTENSITY_ARB
:
2212 case GL_COMPRESSED_RGB_ARB
:
2213 case GL_COMPRESSED_RGBA_ARB
:
2214 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB");
2217 /* silence compiler warning */
2221 if (target
== GL_TEXTURE_3D
) {
2222 struct gl_texture_unit
*texUnit
;
2223 struct gl_texture_object
*texObj
;
2224 struct gl_texture_image
*texImage
;
2226 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2227 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
)) {
2228 return; /* error in texture image was detected */
2231 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2232 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2233 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2236 texImage
= _mesa_alloc_texture_image();
2237 texObj
->Image
[level
] = texImage
;
2239 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage3DARB");
2243 else if (texImage
->Data
) {
2244 FREE(texImage
->Data
);
2245 texImage
->Data
= NULL
;
2248 _mesa_init_teximage_fields(ctx
, texImage
, width
, height
, depth
, border
,
2251 if (ctx
->Extensions
.ARB_texture_compression
) {
2252 ASSERT(ctx
->Driver
.CompressedTexImage3D
);
2253 (*ctx
->Driver
.CompressedTexImage3D
)(ctx
, target
, level
,
2255 width
, height
, depth
,
2256 border
, imageSize
, data
,
2258 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2262 texObj
->Complete
= GL_FALSE
;
2263 ctx
->NewState
|= _NEW_TEXTURE
;
2265 else if (target
== GL_PROXY_TEXTURE_3D
) {
2266 /* Proxy texture: check for errors and update proxy state */
2267 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2268 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
);
2270 struct gl_texture_unit
*texUnit
;
2271 struct gl_texture_image
*texImage
;
2272 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2273 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2274 _mesa_init_teximage_fields(ctx
, texImage
, width
, height
, depth
,
2275 border
, internalFormat
);
2276 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2277 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2278 internalFormat
, GL_NONE
, GL_NONE
,
2279 width
, height
, depth
, border
);
2282 /* if error, clear all proxy texture image parameters */
2283 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2284 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
2289 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB(target)" );
2296 _mesa_CompressedTexSubImage1DARB(GLenum target
, GLint level
, GLint xoffset
,
2297 GLsizei width
, GLenum format
,
2298 GLsizei imageSize
, const GLvoid
*data
)
2300 struct gl_texture_unit
*texUnit
;
2301 struct gl_texture_object
*texObj
;
2302 struct gl_texture_image
*texImage
;
2303 GET_CURRENT_CONTEXT(ctx
);
2304 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2306 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
2307 width
, 1, 1, format
, GL_NONE
)) {
2308 return; /* error was detected */
2311 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2312 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2313 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2316 if (width
== 0 || !data
)
2317 return; /* no-op, not an error */
2319 if (ctx
->Driver
.CompressedTexSubImage1D
) {
2320 (*ctx
->Driver
.CompressedTexSubImage1D
)(ctx
, target
, level
,
2322 format
, imageSize
, data
,
2325 ctx
->NewState
|= _NEW_TEXTURE
;
2330 _mesa_CompressedTexSubImage2DARB(GLenum target
, GLint level
, GLint xoffset
,
2331 GLint yoffset
, GLsizei width
, GLsizei height
,
2332 GLenum format
, GLsizei imageSize
,
2335 struct gl_texture_unit
*texUnit
;
2336 struct gl_texture_object
*texObj
;
2337 struct gl_texture_image
*texImage
;
2338 GET_CURRENT_CONTEXT(ctx
);
2339 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2341 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2342 width
, height
, 1, format
, GL_NONE
)) {
2343 return; /* error was detected */
2346 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2347 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2348 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2351 if (width
== 0 || height
== 0 || !data
)
2352 return; /* no-op, not an error */
2354 if (ctx
->Driver
.CompressedTexSubImage2D
) {
2355 (*ctx
->Driver
.CompressedTexSubImage2D
)(ctx
, target
, level
,
2356 xoffset
, yoffset
, width
, height
,
2357 format
, imageSize
, data
,
2360 ctx
->NewState
|= _NEW_TEXTURE
;
2365 _mesa_CompressedTexSubImage3DARB(GLenum target
, GLint level
, GLint xoffset
,
2366 GLint yoffset
, GLint zoffset
, GLsizei width
,
2367 GLsizei height
, GLsizei depth
, GLenum format
,
2368 GLsizei imageSize
, const GLvoid
*data
)
2370 struct gl_texture_unit
*texUnit
;
2371 struct gl_texture_object
*texObj
;
2372 struct gl_texture_image
*texImage
;
2373 GET_CURRENT_CONTEXT(ctx
);
2374 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2376 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2377 width
, height
, depth
, format
, GL_NONE
)) {
2378 return; /* error was detected */
2381 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2382 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2383 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2386 if (width
== 0 || height
== 0 || depth
== 0 || !data
)
2387 return; /* no-op, not an error */
2389 if (ctx
->Driver
.CompressedTexSubImage3D
) {
2390 (*ctx
->Driver
.CompressedTexSubImage3D
)(ctx
, target
, level
,
2391 xoffset
, yoffset
, zoffset
,
2392 width
, height
, depth
,
2393 format
, imageSize
, data
,
2396 ctx
->NewState
|= _NEW_TEXTURE
;
2401 _mesa_GetCompressedTexImageARB(GLenum target
, GLint level
, GLvoid
*img
)
2403 const struct gl_texture_unit
*texUnit
;
2404 const struct gl_texture_object
*texObj
;
2405 struct gl_texture_image
*texImage
;
2406 GET_CURRENT_CONTEXT(ctx
);
2407 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2409 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
2410 _mesa_error( ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)" );
2414 if (is_proxy_target(target
)) {
2415 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB(target)");
2419 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2420 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2421 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2424 /* invalid mipmap level */
2425 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
2429 if (!texImage
->IsCompressed
) {
2430 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetCompressedTexImageARB");
2437 if (ctx
->Extensions
.ARB_texture_compression
) {
2438 ASSERT(ctx
->Driver
.GetCompressedTexImage
);
2439 (*ctx
->Driver
.GetCompressedTexImage
)(ctx
, target
, level
, img
, texObj
,