1 /* $Id: teximage.c,v 1.96 2001/06/12 22:05:34 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 */
1155 const GLint width
= texImage
->Width
;
1156 const GLint height
= texImage
->Height
;
1157 const GLint depth
= texImage
->Depth
;
1159 for (img
= 0; img
< depth
; img
++) {
1160 for (row
= 0; row
< height
; row
++) {
1161 /* compute destination address in client memory */
1162 GLvoid
*dest
= _mesa_image_address( &ctx
->Unpack
, pixels
,
1163 width
, height
, format
, type
,
1167 if (format
== GL_COLOR_INDEX
) {
1168 GLuint indexRow
[MAX_WIDTH
];
1170 for (col
= 0; col
< width
; col
++) {
1171 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1172 (GLvoid
*) &indexRow
[col
]);
1174 _mesa_pack_index_span(ctx
, width
, type
, dest
,
1175 indexRow
, &ctx
->Pack
,
1176 ctx
->_ImageTransferState
);
1178 else if (format
== GL_DEPTH_COMPONENT
) {
1179 GLfloat depthRow
[MAX_WIDTH
];
1181 for (col
= 0; col
< width
; col
++) {
1182 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1183 (GLvoid
*) &depthRow
[col
]);
1185 _mesa_pack_depth_span(ctx
, width
, dest
, type
,
1186 depthRow
, &ctx
->Pack
);
1189 /* general case: convert row to RGBA format */
1190 GLchan rgba
[MAX_WIDTH
][4];
1192 for (col
= 0; col
< width
; col
++) {
1193 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1194 (GLvoid
*) rgba
[col
]);
1196 _mesa_pack_rgba_span(ctx
, width
, (const GLchan (*)[4])rgba
,
1197 format
, type
, dest
, &ctx
->Pack
,
1198 ctx
->_ImageTransferState
);
1208 * Called from the API. Note that width includes the border.
1211 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
1212 GLsizei width
, GLint border
, GLenum format
,
1213 GLenum type
, const GLvoid
*pixels
)
1215 GLsizei postConvWidth
= width
;
1216 GET_CURRENT_CONTEXT(ctx
);
1217 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1219 if (is_color_format(internalFormat
)) {
1220 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1223 if (target
== GL_TEXTURE_1D
) {
1224 struct gl_texture_unit
*texUnit
;
1225 struct gl_texture_object
*texObj
;
1226 struct gl_texture_image
*texImage
;
1228 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1229 format
, type
, 1, postConvWidth
, 1, 1, border
)) {
1230 return; /* error was recorded */
1233 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1234 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1235 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1238 texImage
= _mesa_alloc_texture_image();
1239 texObj
->Image
[level
] = texImage
;
1241 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
1245 else if (texImage
->Data
) {
1246 /* free the old texture data */
1247 FREE(texImage
->Data
);
1248 texImage
->Data
= NULL
;
1250 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1251 _mesa_init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1252 border
, internalFormat
);
1254 if (ctx
->NewState
& _NEW_PIXEL
)
1255 _mesa_update_state(ctx
);
1257 ASSERT(ctx
->Driver
.TexImage1D
);
1259 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1260 width
, border
, format
, type
, pixels
,
1261 &ctx
->Unpack
, texObj
, texImage
);
1264 GLubyte
*dummy
= make_null_texture(width
, 1, 1, format
);
1266 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1268 format
, GL_UNSIGNED_BYTE
, dummy
,
1269 &_mesa_native_packing
, texObj
, texImage
);
1274 ASSERT(texImage
->TexFormat
);
1275 if (!texImage
->FetchTexel
) {
1276 /* If driver didn't explicitly set this, use the default */
1277 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel1D
;
1279 ASSERT(texImage
->FetchTexel
);
1282 texObj
->Complete
= GL_FALSE
;
1283 ctx
->NewState
|= _NEW_TEXTURE
;
1285 else if (target
== GL_PROXY_TEXTURE_1D
) {
1286 /* Proxy texture: check for errors and update proxy state */
1287 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1289 postConvWidth
, 1, 1, border
);
1291 struct gl_texture_unit
*texUnit
;
1292 struct gl_texture_image
*texImage
;
1293 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1294 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1295 _mesa_init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1296 border
, internalFormat
);
1297 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1298 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1299 internalFormat
, format
, type
,
1300 postConvWidth
, 1, 1, border
);
1303 /* if error, clear all proxy texture image parameters */
1304 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1305 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
1310 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1317 _mesa_TexImage2D( GLenum target
, GLint level
, GLint internalFormat
,
1318 GLsizei width
, GLsizei height
, GLint border
,
1319 GLenum format
, GLenum type
,
1320 const GLvoid
*pixels
)
1322 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1323 GET_CURRENT_CONTEXT(ctx
);
1324 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1326 if (is_color_format(internalFormat
)) {
1327 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1331 if (target
== GL_TEXTURE_2D
||
1332 (ctx
->Extensions
.ARB_texture_cube_map
&&
1333 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1334 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
1335 /* non-proxy target */
1336 struct gl_texture_unit
*texUnit
;
1337 struct gl_texture_object
*texObj
;
1338 struct gl_texture_image
*texImage
;
1340 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1341 format
, type
, 2, postConvWidth
, postConvHeight
,
1343 return; /* error was recorded */
1346 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1347 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1348 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1351 texImage
= _mesa_alloc_texture_image();
1352 _mesa_set_tex_image(texObj
, target
, level
, texImage
);
1354 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1358 else if (texImage
->Data
) {
1359 /* free the old texture data */
1360 FREE(texImage
->Data
);
1361 texImage
->Data
= NULL
;
1363 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1364 _mesa_init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
,
1365 1, border
, internalFormat
);
1367 if (ctx
->NewState
& _NEW_PIXEL
)
1368 _mesa_update_state(ctx
);
1370 ASSERT(ctx
->Driver
.TexImage2D
);
1372 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1373 width
, height
, border
, format
, type
, pixels
,
1374 &ctx
->Unpack
, texObj
, texImage
);
1377 GLubyte
*dummy
= make_null_texture(width
, height
, 1, format
);
1379 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1380 width
, height
, border
,
1381 format
, GL_UNSIGNED_BYTE
, dummy
,
1382 &_mesa_native_packing
, texObj
, texImage
);
1387 ASSERT(texImage
->TexFormat
);
1388 if (!texImage
->FetchTexel
) {
1389 /* If driver didn't explicitly set this, use the default */
1390 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel2D
;
1392 ASSERT(texImage
->FetchTexel
);
1395 texObj
->Complete
= GL_FALSE
;
1396 ctx
->NewState
|= _NEW_TEXTURE
;
1398 else if (target
== GL_PROXY_TEXTURE_2D
) {
1399 /* Proxy texture: check for errors and update proxy state */
1400 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1402 postConvWidth
, postConvHeight
, 1, border
);
1404 struct gl_texture_unit
*texUnit
;
1405 struct gl_texture_image
*texImage
;
1406 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1407 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1408 _mesa_init_teximage_fields(ctx
, texImage
, postConvWidth
,
1409 postConvHeight
, 1, border
, internalFormat
);
1410 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1411 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1412 internalFormat
, format
, type
,
1413 postConvWidth
, postConvHeight
, 1, border
);
1416 /* if error, clear all proxy texture image parameters */
1417 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1418 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
1423 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1430 * Called by the API or display list executor.
1431 * Note that width and height include the border.
1434 _mesa_TexImage3D( GLenum target
, GLint level
, GLenum internalFormat
,
1435 GLsizei width
, GLsizei height
, GLsizei depth
,
1436 GLint border
, GLenum format
, GLenum type
,
1437 const GLvoid
*pixels
)
1439 GET_CURRENT_CONTEXT(ctx
);
1440 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1442 if (target
== GL_TEXTURE_3D
) {
1443 struct gl_texture_unit
*texUnit
;
1444 struct gl_texture_object
*texObj
;
1445 struct gl_texture_image
*texImage
;
1447 if (texture_error_check(ctx
, target
, level
, (GLint
) internalFormat
,
1448 format
, type
, 3, width
, height
, depth
, border
)) {
1449 return; /* error was recorded */
1452 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1453 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1454 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1457 texImage
= _mesa_alloc_texture_image();
1458 texObj
->Image
[level
] = texImage
;
1460 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
1464 else if (texImage
->Data
) {
1465 FREE(texImage
->Data
);
1466 texImage
->Data
= NULL
;
1468 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1469 _mesa_init_teximage_fields(ctx
, texImage
, width
, height
, depth
, border
,
1472 if (ctx
->NewState
& _NEW_PIXEL
)
1473 _mesa_update_state(ctx
);
1475 ASSERT(ctx
->Driver
.TexImage3D
);
1477 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, (GLint
) internalFormat
,
1478 width
, height
, depth
, border
,
1479 format
, type
, pixels
,
1480 &ctx
->Unpack
, texObj
, texImage
);
1483 GLubyte
*dummy
= make_null_texture(width
, height
, depth
, format
);
1485 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
,
1486 (GLint
) internalFormat
,
1487 width
, height
, depth
, border
,
1488 format
, GL_UNSIGNED_BYTE
, dummy
,
1489 &_mesa_native_packing
, texObj
, texImage
);
1494 ASSERT(texImage
->TexFormat
);
1495 if (!texImage
->FetchTexel
) {
1496 /* If driver didn't explicitly set this, use the default */
1497 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel3D
;
1499 ASSERT(texImage
->FetchTexel
);
1502 texObj
->Complete
= GL_FALSE
;
1503 ctx
->NewState
|= _NEW_TEXTURE
;
1505 else if (target
== GL_PROXY_TEXTURE_3D
) {
1506 /* Proxy texture: check for errors and update proxy state */
1507 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1508 format
, type
, 3, width
, height
, depth
, border
);
1510 struct gl_texture_unit
*texUnit
;
1511 struct gl_texture_image
*texImage
;
1512 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1513 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1514 _mesa_init_teximage_fields(ctx
, texImage
, width
, height
, 1,
1515 border
, internalFormat
);
1516 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1517 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1518 internalFormat
, format
, type
,
1519 width
, height
, depth
, border
);
1522 /* if error, clear all proxy texture image parameters */
1523 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1524 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
1529 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1536 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
1537 GLsizei width
, GLsizei height
, GLsizei depth
,
1538 GLint border
, GLenum format
, GLenum type
,
1539 const GLvoid
*pixels
)
1541 _mesa_TexImage3D(target
, level
, internalFormat
, width
, height
,
1542 depth
, border
, format
, type
, pixels
);
1548 _mesa_TexSubImage1D( GLenum target
, GLint level
,
1549 GLint xoffset
, GLsizei width
,
1550 GLenum format
, GLenum type
,
1551 const GLvoid
*pixels
)
1553 GLsizei postConvWidth
= width
;
1554 struct gl_texture_unit
*texUnit
;
1555 struct gl_texture_object
*texObj
;
1556 struct gl_texture_image
*texImage
;
1557 GET_CURRENT_CONTEXT(ctx
);
1558 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1560 if (ctx
->NewState
& _NEW_PIXEL
)
1561 _mesa_update_state(ctx
);
1563 /* XXX should test internal format */
1564 if (is_color_format(format
)) {
1565 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1568 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
1569 postConvWidth
, 1, 1, format
, type
)) {
1570 return; /* error was detected */
1573 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1574 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1575 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1578 if (width
== 0 || !pixels
)
1579 return; /* no-op, not an error */
1581 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1582 xoffset
+= texImage
->Border
;
1584 ASSERT(ctx
->Driver
.TexSubImage1D
);
1585 (*ctx
->Driver
.TexSubImage1D
)(ctx
, target
, level
, xoffset
, width
,
1586 format
, type
, pixels
, &ctx
->Unpack
,
1588 ctx
->NewState
|= _NEW_TEXTURE
;
1593 _mesa_TexSubImage2D( GLenum target
, GLint level
,
1594 GLint xoffset
, GLint yoffset
,
1595 GLsizei width
, GLsizei height
,
1596 GLenum format
, GLenum type
,
1597 const GLvoid
*pixels
)
1599 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1600 struct gl_texture_unit
*texUnit
;
1601 struct gl_texture_object
*texObj
;
1602 struct gl_texture_image
*texImage
;
1603 GET_CURRENT_CONTEXT(ctx
);
1604 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1606 if (ctx
->NewState
& _NEW_PIXEL
)
1607 _mesa_update_state(ctx
);
1609 /* XXX should test internal format */
1610 if (is_color_format(format
)) {
1611 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1615 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1616 postConvWidth
, postConvHeight
, 1, format
, type
)) {
1617 return; /* error was detected */
1620 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1621 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1622 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1625 if (width
== 0 || height
== 0 || !pixels
)
1626 return; /* no-op, not an error */
1628 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1629 xoffset
+= texImage
->Border
;
1630 yoffset
+= texImage
->Border
;
1632 ASSERT(ctx
->Driver
.TexSubImage2D
);
1633 (*ctx
->Driver
.TexSubImage2D
)(ctx
, target
, level
, xoffset
, yoffset
,
1634 width
, height
, format
, type
, pixels
,
1635 &ctx
->Unpack
, texObj
, texImage
);
1636 ctx
->NewState
|= _NEW_TEXTURE
;
1642 _mesa_TexSubImage3D( GLenum target
, GLint level
,
1643 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1644 GLsizei width
, GLsizei height
, GLsizei depth
,
1645 GLenum format
, GLenum type
,
1646 const GLvoid
*pixels
)
1648 struct gl_texture_unit
*texUnit
;
1649 struct gl_texture_object
*texObj
;
1650 struct gl_texture_image
*texImage
;
1651 GET_CURRENT_CONTEXT(ctx
);
1652 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1654 if (ctx
->NewState
& _NEW_PIXEL
)
1655 _mesa_update_state(ctx
);
1657 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
1658 width
, height
, depth
, format
, type
)) {
1659 return; /* error was detected */
1662 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1663 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1664 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1667 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
1668 return; /* no-op, not an error */
1670 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1671 xoffset
+= texImage
->Border
;
1672 yoffset
+= texImage
->Border
;
1673 zoffset
+= texImage
->Border
;
1675 ASSERT(ctx
->Driver
.TexSubImage3D
);
1676 (*ctx
->Driver
.TexSubImage3D
)(ctx
, target
, level
,
1677 xoffset
, yoffset
, zoffset
,
1678 width
, height
, depth
,
1679 format
, type
, pixels
,
1680 &ctx
->Unpack
, texObj
, texImage
);
1681 ctx
->NewState
|= _NEW_TEXTURE
;
1687 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
1688 GLenum internalFormat
,
1690 GLsizei width
, GLint border
)
1692 struct gl_texture_unit
*texUnit
;
1693 struct gl_texture_object
*texObj
;
1694 struct gl_texture_image
*texImage
;
1695 GLsizei postConvWidth
= width
;
1696 GET_CURRENT_CONTEXT(ctx
);
1697 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1699 if (ctx
->NewState
& _NEW_PIXEL
)
1700 _mesa_update_state(ctx
);
1702 if (is_color_format(internalFormat
)) {
1703 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1706 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
1707 postConvWidth
, 1, border
))
1710 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1711 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1712 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1714 texImage
= _mesa_alloc_texture_image();
1715 _mesa_set_tex_image(texObj
, target
, level
, texImage
);
1717 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D");
1721 else if (texImage
->Data
) {
1722 /* free the old texture data */
1723 FREE(texImage
->Data
);
1724 texImage
->Data
= NULL
;
1727 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1728 _mesa_init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1729 border
, internalFormat
);
1732 ASSERT(ctx
->Driver
.CopyTexImage1D
);
1733 (*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
, internalFormat
,
1734 x
, y
, width
, border
);
1736 ASSERT(texImage
->TexFormat
);
1737 if (!texImage
->FetchTexel
) {
1738 /* If driver didn't explicitly set this, use the default */
1739 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel1D
;
1741 ASSERT(texImage
->FetchTexel
);
1744 texObj
->Complete
= GL_FALSE
;
1745 ctx
->NewState
|= _NEW_TEXTURE
;
1751 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
1752 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1755 struct gl_texture_unit
*texUnit
;
1756 struct gl_texture_object
*texObj
;
1757 struct gl_texture_image
*texImage
;
1758 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1759 GET_CURRENT_CONTEXT(ctx
);
1760 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1762 if (ctx
->NewState
& _NEW_PIXEL
)
1763 _mesa_update_state(ctx
);
1765 if (is_color_format(internalFormat
)) {
1766 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1770 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
1771 postConvWidth
, postConvHeight
, border
))
1774 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1775 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1776 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1778 texImage
= _mesa_alloc_texture_image();
1779 _mesa_set_tex_image(texObj
, target
, level
, texImage
);
1781 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D");
1785 else if (texImage
->Data
) {
1786 /* free the old texture data */
1787 FREE(texImage
->Data
);
1788 texImage
->Data
= NULL
;
1791 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1792 _mesa_init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
, 1,
1793 border
, internalFormat
);
1795 ASSERT(ctx
->Driver
.CopyTexImage2D
);
1796 (*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
, internalFormat
,
1797 x
, y
, width
, height
, border
);
1799 ASSERT(texImage
->TexFormat
);
1800 if (!texImage
->FetchTexel
) {
1801 /* If driver didn't explicitly set this, use the default */
1802 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel2D
;
1804 ASSERT(texImage
->FetchTexel
);
1807 texObj
->Complete
= GL_FALSE
;
1808 ctx
->NewState
|= _NEW_TEXTURE
;
1814 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
1815 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
1817 struct gl_texture_unit
*texUnit
;
1818 struct gl_texture_object
*texObj
;
1819 struct gl_texture_image
*texImage
;
1820 GLsizei postConvWidth
= width
;
1821 GET_CURRENT_CONTEXT(ctx
);
1822 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1824 if (ctx
->NewState
& _NEW_PIXEL
)
1825 _mesa_update_state(ctx
);
1827 /* XXX should test internal format */
1828 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1830 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
1831 xoffset
, 0, 0, postConvWidth
, 1))
1834 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1835 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1836 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1838 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1839 xoffset
+= texImage
->Border
;
1841 ASSERT(ctx
->Driver
.CopyTexSubImage1D
);
1842 (*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
, xoffset
, x
, y
, width
);
1843 ctx
->NewState
|= _NEW_TEXTURE
;
1849 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
1850 GLint xoffset
, GLint yoffset
,
1851 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1853 struct gl_texture_unit
*texUnit
;
1854 struct gl_texture_object
*texObj
;
1855 struct gl_texture_image
*texImage
;
1856 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1857 GET_CURRENT_CONTEXT(ctx
);
1858 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1860 if (ctx
->NewState
& _NEW_PIXEL
)
1861 _mesa_update_state(ctx
);
1863 /* XXX should test internal format */
1864 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
1866 if (copytexsubimage_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1867 postConvWidth
, postConvHeight
))
1870 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1871 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1872 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1874 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1875 xoffset
+= texImage
->Border
;
1876 yoffset
+= texImage
->Border
;
1878 ASSERT(ctx
->Driver
.CopyTexSubImage2D
);
1879 (*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
1880 xoffset
, yoffset
, x
, y
, width
, height
);
1881 ctx
->NewState
|= _NEW_TEXTURE
;
1887 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
1888 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1889 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1891 struct gl_texture_unit
*texUnit
;
1892 struct gl_texture_object
*texObj
;
1893 struct gl_texture_image
*texImage
;
1894 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1895 GET_CURRENT_CONTEXT(ctx
);
1896 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1898 if (ctx
->NewState
& _NEW_PIXEL
)
1899 _mesa_update_state(ctx
);
1901 /* XXX should test internal format */
1902 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
1904 if (copytexsubimage_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
,
1905 zoffset
, postConvWidth
, postConvHeight
))
1908 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1909 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1910 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1912 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1913 xoffset
+= texImage
->Border
;
1914 yoffset
+= texImage
->Border
;
1915 zoffset
+= texImage
->Border
;
1917 ASSERT(ctx
->Driver
.CopyTexSubImage3D
);
1918 (*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
1919 xoffset
, yoffset
, zoffset
,
1920 x
, y
, width
, height
);
1921 ctx
->NewState
|= _NEW_TEXTURE
;
1927 _mesa_CompressedTexImage1DARB(GLenum target
, GLint level
,
1928 GLenum internalFormat
, GLsizei width
,
1929 GLint border
, GLsizei imageSize
,
1932 GET_CURRENT_CONTEXT(ctx
);
1933 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1935 switch (internalFormat
) {
1936 case GL_COMPRESSED_ALPHA_ARB
:
1937 case GL_COMPRESSED_LUMINANCE_ARB
:
1938 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
1939 case GL_COMPRESSED_INTENSITY_ARB
:
1940 case GL_COMPRESSED_RGB_ARB
:
1941 case GL_COMPRESSED_RGBA_ARB
:
1942 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB");
1945 /* silence compiler warning */
1949 if (target
== GL_TEXTURE_1D
) {
1950 struct gl_texture_unit
*texUnit
;
1951 struct gl_texture_object
*texObj
;
1952 struct gl_texture_image
*texImage
;
1954 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1955 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
1956 return; /* error in texture image was detected */
1959 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1960 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1961 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1964 texImage
= _mesa_alloc_texture_image();
1965 texObj
->Image
[level
] = texImage
;
1967 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage1DARB");
1971 else if (texImage
->Data
) {
1972 FREE(texImage
->Data
);
1973 texImage
->Data
= NULL
;
1976 _mesa_init_teximage_fields(ctx
, texImage
, width
, 1, 1,
1977 border
, internalFormat
);
1979 if (ctx
->Extensions
.ARB_texture_compression
) {
1980 ASSERT(ctx
->Driver
.CompressedTexImage1D
);
1981 (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
,
1982 internalFormat
, width
, border
,
1985 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
1989 texObj
->Complete
= GL_FALSE
;
1990 ctx
->NewState
|= _NEW_TEXTURE
;
1992 else if (target
== GL_PROXY_TEXTURE_1D
) {
1993 /* Proxy texture: check for errors and update proxy state */
1994 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1995 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
);
1997 struct gl_texture_unit
*texUnit
;
1998 struct gl_texture_image
*texImage
;
1999 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2000 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2001 _mesa_init_teximage_fields(ctx
, texImage
, width
, 1, 1,
2002 border
, internalFormat
);
2003 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2004 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2005 internalFormat
, GL_NONE
, GL_NONE
,
2006 width
, 1, 1, border
);
2009 /* if error, clear all proxy texture image parameters */
2010 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2011 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
2016 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB(target)" );
2023 _mesa_CompressedTexImage2DARB(GLenum target
, GLint level
,
2024 GLenum internalFormat
, GLsizei width
,
2025 GLsizei height
, GLint border
, GLsizei imageSize
,
2028 GET_CURRENT_CONTEXT(ctx
);
2029 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2031 switch (internalFormat
) {
2032 case GL_COMPRESSED_ALPHA_ARB
:
2033 case GL_COMPRESSED_LUMINANCE_ARB
:
2034 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2035 case GL_COMPRESSED_INTENSITY_ARB
:
2036 case GL_COMPRESSED_RGB_ARB
:
2037 case GL_COMPRESSED_RGBA_ARB
:
2038 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB");
2041 /* silence compiler warning */
2045 if (target
== GL_TEXTURE_2D
||
2046 (ctx
->Extensions
.ARB_texture_cube_map
&&
2047 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2048 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
2049 struct gl_texture_unit
*texUnit
;
2050 struct gl_texture_object
*texObj
;
2051 struct gl_texture_image
*texImage
;
2053 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2054 GL_NONE
, GL_NONE
, 1, width
, height
, 1, border
)) {
2055 return; /* error in texture image was detected */
2058 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2059 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2060 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2063 texImage
= _mesa_alloc_texture_image();
2064 texObj
->Image
[level
] = texImage
;
2066 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
2070 else if (texImage
->Data
) {
2071 FREE(texImage
->Data
);
2072 texImage
->Data
= NULL
;
2075 _mesa_init_teximage_fields(ctx
, texImage
, width
, height
, 1, border
,
2078 if (ctx
->Extensions
.ARB_texture_compression
) {
2079 ASSERT(ctx
->Driver
.CompressedTexImage2D
);
2080 (*ctx
->Driver
.CompressedTexImage2D
)(ctx
, target
, level
,
2081 internalFormat
, width
, height
,
2082 border
, imageSize
, data
,
2084 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2088 texObj
->Complete
= GL_FALSE
;
2089 ctx
->NewState
|= _NEW_TEXTURE
;
2091 else if (target
== GL_PROXY_TEXTURE_2D
) {
2092 /* Proxy texture: check for errors and update proxy state */
2093 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2094 GL_NONE
, GL_NONE
, 2, width
, height
, 1, border
);
2096 struct gl_texture_unit
*texUnit
;
2097 struct gl_texture_image
*texImage
;
2098 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2099 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2100 _mesa_init_teximage_fields(ctx
, texImage
, width
, height
, 1,
2101 border
, internalFormat
);
2102 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2103 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2104 internalFormat
, GL_NONE
, GL_NONE
,
2105 width
, height
, 1, border
);
2108 /* if error, clear all proxy texture image parameters */
2109 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2110 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
2115 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB(target)" );
2122 _mesa_CompressedTexImage3DARB(GLenum target
, GLint level
,
2123 GLenum internalFormat
, GLsizei width
,
2124 GLsizei height
, GLsizei depth
, GLint border
,
2125 GLsizei imageSize
, const GLvoid
*data
)
2127 GET_CURRENT_CONTEXT(ctx
);
2128 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2130 switch (internalFormat
) {
2131 case GL_COMPRESSED_ALPHA_ARB
:
2132 case GL_COMPRESSED_LUMINANCE_ARB
:
2133 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2134 case GL_COMPRESSED_INTENSITY_ARB
:
2135 case GL_COMPRESSED_RGB_ARB
:
2136 case GL_COMPRESSED_RGBA_ARB
:
2137 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB");
2140 /* silence compiler warning */
2144 if (target
== GL_TEXTURE_3D
) {
2145 struct gl_texture_unit
*texUnit
;
2146 struct gl_texture_object
*texObj
;
2147 struct gl_texture_image
*texImage
;
2149 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2150 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
)) {
2151 return; /* error in texture image was detected */
2154 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2155 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2156 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2159 texImage
= _mesa_alloc_texture_image();
2160 texObj
->Image
[level
] = texImage
;
2162 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage3DARB");
2166 else if (texImage
->Data
) {
2167 FREE(texImage
->Data
);
2168 texImage
->Data
= NULL
;
2171 _mesa_init_teximage_fields(ctx
, texImage
, width
, height
, depth
, border
,
2174 if (ctx
->Extensions
.ARB_texture_compression
) {
2175 ASSERT(ctx
->Driver
.CompressedTexImage3D
);
2176 (*ctx
->Driver
.CompressedTexImage3D
)(ctx
, target
, level
,
2178 width
, height
, depth
,
2179 border
, imageSize
, data
,
2181 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2185 texObj
->Complete
= GL_FALSE
;
2186 ctx
->NewState
|= _NEW_TEXTURE
;
2188 else if (target
== GL_PROXY_TEXTURE_3D
) {
2189 /* Proxy texture: check for errors and update proxy state */
2190 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2191 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
);
2193 struct gl_texture_unit
*texUnit
;
2194 struct gl_texture_image
*texImage
;
2195 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2196 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2197 _mesa_init_teximage_fields(ctx
, texImage
, width
, height
, depth
,
2198 border
, internalFormat
);
2199 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2200 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2201 internalFormat
, GL_NONE
, GL_NONE
,
2202 width
, height
, depth
, border
);
2205 /* if error, clear all proxy texture image parameters */
2206 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2207 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
2212 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB(target)" );
2219 _mesa_CompressedTexSubImage1DARB(GLenum target
, GLint level
, GLint xoffset
,
2220 GLsizei width
, GLenum format
,
2221 GLsizei imageSize
, const GLvoid
*data
)
2223 struct gl_texture_unit
*texUnit
;
2224 struct gl_texture_object
*texObj
;
2225 struct gl_texture_image
*texImage
;
2226 GET_CURRENT_CONTEXT(ctx
);
2227 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2229 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
2230 width
, 1, 1, format
, GL_NONE
)) {
2231 return; /* error was detected */
2234 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2235 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2236 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2239 if (width
== 0 || !data
)
2240 return; /* no-op, not an error */
2242 if (ctx
->Driver
.CompressedTexSubImage1D
) {
2243 (*ctx
->Driver
.CompressedTexSubImage1D
)(ctx
, target
, level
,
2245 format
, imageSize
, data
,
2248 ctx
->NewState
|= _NEW_TEXTURE
;
2253 _mesa_CompressedTexSubImage2DARB(GLenum target
, GLint level
, GLint xoffset
,
2254 GLint yoffset
, GLsizei width
, GLsizei height
,
2255 GLenum format
, GLsizei imageSize
,
2258 struct gl_texture_unit
*texUnit
;
2259 struct gl_texture_object
*texObj
;
2260 struct gl_texture_image
*texImage
;
2261 GET_CURRENT_CONTEXT(ctx
);
2262 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2264 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2265 width
, height
, 1, format
, GL_NONE
)) {
2266 return; /* error was detected */
2269 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2270 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2271 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2274 if (width
== 0 || height
== 0 || !data
)
2275 return; /* no-op, not an error */
2277 if (ctx
->Driver
.CompressedTexSubImage2D
) {
2278 (*ctx
->Driver
.CompressedTexSubImage2D
)(ctx
, target
, level
,
2279 xoffset
, yoffset
, width
, height
,
2280 format
, imageSize
, data
,
2283 ctx
->NewState
|= _NEW_TEXTURE
;
2288 _mesa_CompressedTexSubImage3DARB(GLenum target
, GLint level
, GLint xoffset
,
2289 GLint yoffset
, GLint zoffset
, GLsizei width
,
2290 GLsizei height
, GLsizei depth
, GLenum format
,
2291 GLsizei imageSize
, const GLvoid
*data
)
2293 struct gl_texture_unit
*texUnit
;
2294 struct gl_texture_object
*texObj
;
2295 struct gl_texture_image
*texImage
;
2296 GET_CURRENT_CONTEXT(ctx
);
2297 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2299 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2300 width
, height
, depth
, format
, GL_NONE
)) {
2301 return; /* error was detected */
2304 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2305 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2306 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2309 if (width
== 0 || height
== 0 || depth
== 0 || !data
)
2310 return; /* no-op, not an error */
2312 if (ctx
->Driver
.CompressedTexSubImage3D
) {
2313 (*ctx
->Driver
.CompressedTexSubImage3D
)(ctx
, target
, level
,
2314 xoffset
, yoffset
, zoffset
,
2315 width
, height
, depth
,
2316 format
, imageSize
, data
,
2319 ctx
->NewState
|= _NEW_TEXTURE
;
2324 _mesa_GetCompressedTexImageARB(GLenum target
, GLint level
, GLvoid
*img
)
2326 const struct gl_texture_unit
*texUnit
;
2327 const struct gl_texture_object
*texObj
;
2328 struct gl_texture_image
*texImage
;
2329 GET_CURRENT_CONTEXT(ctx
);
2330 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2332 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
2333 _mesa_error( ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)" );
2337 if (is_proxy_target(target
)) {
2338 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB(target)");
2342 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2343 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2344 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2347 /* invalid mipmap level */
2348 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
2352 if (!texImage
->IsCompressed
) {
2353 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetCompressedTexImageARB");
2360 if (ctx
->Extensions
.ARB_texture_compression
) {
2361 ASSERT(ctx
->Driver
.GetCompressedTexImage
);
2362 (*ctx
->Driver
.GetCompressedTexImage
)(ctx
, target
, level
, img
, texObj
,