1 /* $Id: teximage.c,v 1.84 2001/03/12 00:48:38 gareth 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.
42 #include "swrast/s_span.h" /* XXX SWRAST hack */
49 * Mesa's native texture datatype is GLchan. Native formats are
50 * GL_ALPHA, GL_LUMINANCE, GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, GL_RGBA,
52 * Device drivers are free to implement any internal format they want.
57 static void PrintTexture(const struct gl_texture_image
*img
)
60 const GLchan
*data
= (const GLchan
*) img
->Data
;
63 printf("No texture data\n");
67 switch (img
->Format
) {
74 case GL_LUMINANCE_ALPHA
:
84 _mesa_problem(NULL
, "error in PrintTexture\n");
88 for (i
= 0; i
< img
->Height
; i
++) {
89 for (j
= 0; j
< img
->Width
; j
++) {
91 printf("%02x ", data
[0]);
93 printf("%02x%02x ", data
[0], data
[1]);
95 printf("%02x%02x%02x ", data
[0], data
[1], data
[2]);
97 printf("%02x%02x%02x%02x ", data
[0], data
[1], data
[2], data
[3]);
108 * Compute log base 2 of n.
109 * If n isn't an exact power of two return -1.
137 * Given an internal texture format enum or 1, 2, 3, 4 return the
138 * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE,
139 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.
140 * Return -1 if invalid enum.
143 _mesa_base_tex_format( GLcontext
*ctx
, GLint format
)
146 * Ask the driver for the base format, if it doesn't
147 * know, it will return -1;
149 if (ctx
->Driver
.BaseCompressedTexFormat
) {
150 GLint ifmt
= (*ctx
->Driver
.BaseCompressedTexFormat
)(ctx
, format
);
170 case GL_LUMINANCE_ALPHA
:
171 case GL_LUMINANCE4_ALPHA4
:
172 case GL_LUMINANCE6_ALPHA2
:
173 case GL_LUMINANCE8_ALPHA8
:
174 case GL_LUMINANCE12_ALPHA4
:
175 case GL_LUMINANCE12_ALPHA12
:
176 case GL_LUMINANCE16_ALPHA16
:
177 return GL_LUMINANCE_ALPHA
;
205 case GL_COLOR_INDEX1_EXT
:
206 case GL_COLOR_INDEX2_EXT
:
207 case GL_COLOR_INDEX4_EXT
:
208 case GL_COLOR_INDEX8_EXT
:
209 case GL_COLOR_INDEX12_EXT
:
210 case GL_COLOR_INDEX16_EXT
:
211 return GL_COLOR_INDEX
;
212 case GL_DEPTH_COMPONENT
:
213 case GL_DEPTH_COMPONENT16_SGIX
:
214 case GL_DEPTH_COMPONENT24_SGIX
:
215 case GL_DEPTH_COMPONENT32_SGIX
:
216 if (ctx
->Extensions
.SGIX_depth_texture
)
217 return GL_DEPTH_COMPONENT
;
221 return -1; /* error */
227 * Test if the given image format is a color/rgba format. That is,
228 * not color index, depth, stencil, etc.
231 is_color_format(GLenum format
)
246 case GL_LUMINANCE_ALPHA
:
247 case GL_LUMINANCE4_ALPHA4
:
248 case GL_LUMINANCE6_ALPHA2
:
249 case GL_LUMINANCE8_ALPHA8
:
250 case GL_LUMINANCE12_ALPHA4
:
251 case GL_LUMINANCE12_ALPHA12
:
252 case GL_LUMINANCE16_ALPHA16
:
284 is_index_format(GLenum format
)
288 case GL_COLOR_INDEX1_EXT
:
289 case GL_COLOR_INDEX2_EXT
:
290 case GL_COLOR_INDEX4_EXT
:
291 case GL_COLOR_INDEX8_EXT
:
292 case GL_COLOR_INDEX12_EXT
:
293 case GL_COLOR_INDEX16_EXT
:
302 * Return GL_TRUE if internalFormat is a compressed format, return GL_FALSE
306 is_compressed_format(GLcontext
*ctx
, GLenum internalFormat
)
308 if (ctx
->Driver
.IsCompressedFormat
) {
309 return (*ctx
->Driver
.IsCompressedFormat
)(ctx
, internalFormat
);
317 * Store a gl_texture_image pointer in a gl_texture_object structure
318 * according to the target and level parameters.
319 * This was basically prompted by the introduction of cube maps.
322 set_tex_image(struct gl_texture_object
*tObj
,
323 GLenum target
, GLint level
,
324 struct gl_texture_image
*texImage
)
330 tObj
->Image
[level
] = texImage
;
332 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
333 tObj
->Image
[level
] = texImage
;
335 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
336 tObj
->NegX
[level
] = texImage
;
338 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
339 tObj
->PosY
[level
] = texImage
;
341 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
342 tObj
->NegY
[level
] = texImage
;
344 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
345 tObj
->PosZ
[level
] = texImage
;
347 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
348 tObj
->NegZ
[level
] = texImage
;
351 _mesa_problem(NULL
, "bad target in set_tex_image()");
359 * Return new gl_texture_image struct with all fields initialized to zero.
361 struct gl_texture_image
*
362 _mesa_alloc_texture_image( void )
364 return CALLOC_STRUCT(gl_texture_image
);
370 _mesa_free_texture_image( struct gl_texture_image
*teximage
)
372 if (teximage
->Data
) {
373 FREE( teximage
->Data
);
374 teximage
->Data
= NULL
;
381 * Return GL_TRUE if the target is a proxy target.
384 is_proxy_target(GLenum target
)
386 return (target
== GL_PROXY_TEXTURE_1D
||
387 target
== GL_PROXY_TEXTURE_2D
||
388 target
== GL_PROXY_TEXTURE_3D
||
389 target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
);
394 * Given a texture unit and a texture target, return the corresponding
397 struct gl_texture_object
*
398 _mesa_select_tex_object(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
403 return texUnit
->Current1D
;
404 case GL_PROXY_TEXTURE_1D
:
405 return ctx
->Texture
.Proxy1D
;
407 return texUnit
->Current2D
;
408 case GL_PROXY_TEXTURE_2D
:
409 return ctx
->Texture
.Proxy2D
;
411 return texUnit
->Current3D
;
412 case GL_PROXY_TEXTURE_3D
:
413 return ctx
->Texture
.Proxy3D
;
414 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
415 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
416 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
417 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
418 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
419 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
420 return ctx
->Extensions
.ARB_texture_cube_map
421 ? texUnit
->CurrentCubeMap
: NULL
;
422 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
423 return ctx
->Extensions
.ARB_texture_cube_map
424 ? ctx
->Texture
.ProxyCubeMap
: NULL
;
426 _mesa_problem(NULL
, "bad target in _mesa_select_tex_object()");
433 * Return the texture image struct which corresponds to target and level
434 * for the given texture unit.
436 struct gl_texture_image
*
437 _mesa_select_tex_image(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
438 GLenum target
, GLint level
)
443 return texUnit
->Current1D
->Image
[level
];
444 case GL_PROXY_TEXTURE_1D
:
445 return ctx
->Texture
.Proxy1D
->Image
[level
];
447 return texUnit
->Current2D
->Image
[level
];
448 case GL_PROXY_TEXTURE_2D
:
449 return ctx
->Texture
.Proxy2D
->Image
[level
];
451 return texUnit
->Current3D
->Image
[level
];
452 case GL_PROXY_TEXTURE_3D
:
453 return ctx
->Texture
.Proxy3D
->Image
[level
];
454 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
455 if (ctx
->Extensions
.ARB_texture_cube_map
)
456 return texUnit
->CurrentCubeMap
->Image
[level
];
459 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
460 if (ctx
->Extensions
.ARB_texture_cube_map
)
461 return texUnit
->CurrentCubeMap
->NegX
[level
];
464 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
465 if (ctx
->Extensions
.ARB_texture_cube_map
)
466 return texUnit
->CurrentCubeMap
->PosY
[level
];
469 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
470 if (ctx
->Extensions
.ARB_texture_cube_map
)
471 return texUnit
->CurrentCubeMap
->NegY
[level
];
474 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
475 if (ctx
->Extensions
.ARB_texture_cube_map
)
476 return texUnit
->CurrentCubeMap
->PosZ
[level
];
479 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
480 if (ctx
->Extensions
.ARB_texture_cube_map
)
481 return texUnit
->CurrentCubeMap
->NegZ
[level
];
484 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
485 if (ctx
->Extensions
.ARB_texture_cube_map
)
486 return ctx
->Texture
.ProxyCubeMap
->Image
[level
];
490 _mesa_problem(ctx
, "bad target in _mesa_select_tex_image()");
498 * glTexImage[123]D can accept a NULL image pointer. In this case we
499 * create a texture image with unspecified image contents per the OpenGL
503 make_null_texture(GLint width
, GLint height
, GLint depth
, GLenum format
)
505 const GLint components
= _mesa_components_in_format(format
);
506 const GLint numPixels
= width
* height
* depth
;
507 GLubyte
*data
= (GLubyte
*) MALLOC(numPixels
* components
* sizeof(GLubyte
));
510 * Let's see if anyone finds this. If glTexImage2D() is called with
511 * a NULL image pointer then load the texture image with something
512 * interesting instead of leaving it indeterminate.
515 static const char message
[8][32] = {
519 " X X XXXX XXX XXXXX ",
522 " X X XXXXX XXX X X ",
526 GLubyte
*imgPtr
= data
;
528 for (h
= 0; h
< depth
; h
++) {
529 for (i
= 0; i
< height
; i
++) {
530 GLint srcRow
= 7 - (i
% 8);
531 for (j
= 0; j
< width
; j
++) {
532 GLint srcCol
= j
% 32;
533 GLubyte texel
= (message
[srcRow
][srcCol
]=='X') ? 255 : 70;
534 for (k
= 0; k
< components
; k
++) {
548 * Reset the fields of a gl_texture_image struct to zero.
549 * This is called when a proxy texture test fails, we set all the
550 * image members (except DriverData) to zero.
551 * It's also used in glTexImage[123]D as a safeguard to be sure all
552 * required fields get initialized properly by the Driver.TexImage[123]D
556 clear_teximage_fields(struct gl_texture_image
*img
)
566 img
->IntensityBits
= 0;
567 img
->LuminanceBits
= 0;
580 img
->IsCompressed
= 0;
581 img
->CompressedSize
= 0;
582 img
->FetchTexel
= NULL
;
587 * Initialize basic fields of the gl_texture_image struct.
590 init_teximage_fields(GLcontext
*ctx
,
591 struct gl_texture_image
*img
,
592 GLsizei width
, GLsizei height
, GLsizei depth
,
593 GLint border
, GLenum internalFormat
)
597 img
->IntFormat
= internalFormat
;
598 img
->Border
= border
;
600 img
->Height
= height
;
602 img
->WidthLog2
= logbase2(width
- 2 * border
);
603 if (height
== 1) /* 1-D texture */
606 img
->HeightLog2
= logbase2(height
- 2 * border
);
607 if (depth
== 1) /* 2-D texture */
610 img
->DepthLog2
= logbase2(depth
- 2 * border
);
611 img
->Width2
= 1 << img
->WidthLog2
;
612 img
->Height2
= 1 << img
->HeightLog2
;
613 img
->Depth2
= 1 << img
->DepthLog2
;
614 img
->MaxLog2
= MAX2(img
->WidthLog2
, img
->HeightLog2
);
615 img
->IsCompressed
= is_compressed_format(ctx
, internalFormat
);
621 * Test glTexImage[123]D() parameters for errors.
623 * dimensions - must be 1 or 2 or 3
624 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
627 texture_error_check( GLcontext
*ctx
, GLenum target
,
628 GLint level
, GLint internalFormat
,
629 GLenum format
, GLenum type
,
631 GLint width
, GLint height
,
632 GLint depth
, GLint border
)
637 if (dimensions
== 1) {
638 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_1D
);
639 if (target
!= GL_TEXTURE_1D
&& !isProxy
) {
640 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
644 else if (dimensions
== 2) {
645 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_2D
||
646 target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
);
647 if (target
!= GL_TEXTURE_2D
&& !isProxy
&&
648 !(ctx
->Extensions
.ARB_texture_cube_map
&&
649 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
650 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
651 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
655 else if (dimensions
== 3) {
656 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_3D
);
657 if (target
!= GL_TEXTURE_3D
&& !isProxy
) {
658 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
663 _mesa_problem( ctx
, "bad dims in texture_error_check" );
668 if (border
!= 0 && border
!= 1) {
671 sprintf(message
, "glTexImage%dD(border=%d)", dimensions
, border
);
672 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
678 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
679 || logbase2( width
- 2 * border
) < 0) {
682 sprintf(message
, "glTexImage%dD(width=%d)", dimensions
, width
);
683 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
689 if (dimensions
>= 2) {
690 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
691 || logbase2( height
- 2 * border
) < 0) {
694 sprintf(message
, "glTexImage%dD(height=%d)", dimensions
, height
);
695 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
701 /* For cube map, width must equal height */
702 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
703 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
704 if (width
!= height
) {
706 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
713 if (dimensions
>= 3) {
714 if (depth
< 2 * border
|| depth
> 2 + ctx
->Const
.MaxTextureSize
715 || logbase2( depth
- 2 * border
) < 0) {
718 sprintf(message
, "glTexImage3D(depth=%d)", depth
);
719 _mesa_error( ctx
, GL_INVALID_VALUE
, message
);
726 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
729 sprintf(message
, "glTexImage%dD(level=%d)", dimensions
, level
);
730 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
735 /* For cube map, width must equal height */
736 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
737 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
738 if (width
!= height
) {
739 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
744 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
748 sprintf(message
, "glTexImage%dD(internalFormat=0x%x)", dimensions
,
750 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
755 if (!is_compressed_format(ctx
, internalFormat
)) {
756 if (!_mesa_is_legal_format_and_type( format
, type
)) {
757 /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
758 * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
762 sprintf(message
, "glTexImage%dD(format or type)", dimensions
);
763 _mesa_error(ctx
, GL_INVALID_OPERATION
, message
);
769 /* if we get here, the parameters are OK */
776 * Test glTexSubImage[123]D() parameters for errors.
778 * dimensions - must be 1 or 2 or 3
779 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
782 subtexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
783 GLenum target
, GLint level
,
784 GLint xoffset
, GLint yoffset
, GLint zoffset
,
785 GLint width
, GLint height
, GLint depth
,
786 GLenum format
, GLenum type
)
788 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
789 struct gl_texture_image
*destTex
;
791 if (dimensions
== 1) {
792 if (target
!= GL_TEXTURE_1D
) {
793 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(target)" );
797 else if (dimensions
== 2) {
798 if (ctx
->Extensions
.ARB_texture_cube_map
) {
799 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
800 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
801 target
!= GL_TEXTURE_2D
) {
802 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
806 else if (target
!= GL_TEXTURE_2D
) {
807 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
811 else if (dimensions
== 3) {
812 if (target
!= GL_TEXTURE_3D
) {
813 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3D(target)" );
818 _mesa_problem( ctx
, "bad dims in texture_error_check" );
822 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
824 sprintf(message
, "glTexSubImage2D(level=%d)", level
);
825 _mesa_error(ctx
, GL_INVALID_ENUM
, message
);
831 sprintf(message
, "glTexSubImage%dD(width=%d)", dimensions
, width
);
832 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
835 if (height
< 0 && dimensions
> 1) {
837 sprintf(message
, "glTexSubImage%dD(height=%d)", dimensions
, height
);
838 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
841 if (depth
< 0 && dimensions
> 2) {
843 sprintf(message
, "glTexSubImage%dD(depth=%d)", dimensions
, depth
);
844 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
848 destTex
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
851 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glTexSubImage2D");
855 if (xoffset
< -((GLint
)destTex
->Border
)) {
856 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset)");
859 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
860 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset+width)");
863 if (dimensions
> 1) {
864 if (yoffset
< -((GLint
)destTex
->Border
)) {
865 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset)");
868 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
869 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset+height)");
873 if (dimensions
> 2) {
874 if (zoffset
< -((GLint
)destTex
->Border
)) {
875 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset)");
878 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+destTex
->Border
)) {
879 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset+depth)");
884 if (!is_compressed_format(ctx
, destTex
->IntFormat
)) {
885 if (!_mesa_is_legal_format_and_type(format
, type
)) {
887 sprintf(message
, "glTexSubImage%dD(format or type)", dimensions
);
888 _mesa_error(ctx
, GL_INVALID_ENUM
, message
);
898 * Test glCopyTexImage[12]D() parameters for errors.
899 * Input: dimensions - must be 1 or 2 or 3
900 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
903 copytexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
904 GLenum target
, GLint level
, GLint internalFormat
,
905 GLint width
, GLint height
, GLint border
)
909 if (dimensions
== 1) {
910 if (target
!= GL_TEXTURE_1D
) {
911 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
915 else if (dimensions
== 2) {
916 if (ctx
->Extensions
.ARB_texture_cube_map
) {
917 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
918 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
919 target
!= GL_TEXTURE_2D
) {
920 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
924 else if (target
!= GL_TEXTURE_2D
) {
925 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
931 if (border
!=0 && border
!=1) {
933 sprintf(message
, "glCopyTexImage%dD(border)", dimensions
);
934 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
939 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
940 || logbase2( width
- 2 * border
) < 0) {
942 sprintf(message
, "glCopyTexImage%dD(width=%d)", dimensions
, width
);
943 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
948 if (dimensions
>= 2) {
949 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
950 || logbase2( height
- 2 * border
) < 0) {
952 sprintf(message
, "glCopyTexImage%dD(height=%d)", dimensions
, height
);
953 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
958 /* For cube map, width must equal height */
959 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
960 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
961 if (width
!= height
) {
962 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(width != height)");
968 if (level
<0 || level
>=ctx
->Const
.MaxTextureLevels
) {
970 sprintf(message
, "glCopyTexImage%dD(level=%d)", dimensions
, level
);
971 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
975 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
978 sprintf(message
, "glCopyTexImage%dD(internalFormat)", dimensions
);
979 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
983 /* if we get here, the parameters are OK */
989 copytexsubimage_error_check( GLcontext
*ctx
, GLuint dimensions
,
990 GLenum target
, GLint level
,
991 GLint xoffset
, GLint yoffset
, GLint zoffset
,
992 GLsizei width
, GLsizei height
)
994 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
995 struct gl_texture_image
*teximage
;
997 if (dimensions
== 1) {
998 if (target
!= GL_TEXTURE_1D
) {
999 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
1003 else if (dimensions
== 2) {
1004 if (ctx
->Extensions
.ARB_texture_cube_map
) {
1005 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1006 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1007 target
!= GL_TEXTURE_2D
) {
1008 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1012 else if (target
!= GL_TEXTURE_2D
) {
1013 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1017 else if (dimensions
== 3) {
1018 if (target
!= GL_TEXTURE_3D
) {
1019 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3D(target)" );
1024 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1026 sprintf(message
, "glCopyTexSubImage%dD(level=%d)", dimensions
, level
);
1027 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1033 sprintf(message
, "glCopyTexSubImage%dD(width=%d)", dimensions
, width
);
1034 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1037 if (dimensions
> 1 && height
< 0) {
1039 sprintf(message
, "glCopyTexSubImage%dD(height=%d)", dimensions
, height
);
1040 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1044 teximage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1047 sprintf(message
, "glCopyTexSubImage%dD(undefined texture)", dimensions
);
1048 _mesa_error(ctx
, GL_INVALID_OPERATION
, message
);
1052 if (xoffset
< -((GLint
)teximage
->Border
)) {
1054 sprintf(message
, "glCopyTexSubImage%dD(xoffset=%d)", dimensions
, xoffset
);
1055 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1058 if (xoffset
+width
> (GLint
) (teximage
->Width
+teximage
->Border
)) {
1060 sprintf(message
, "glCopyTexSubImage%dD(xoffset+width)", dimensions
);
1061 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1064 if (dimensions
> 1) {
1065 if (yoffset
< -((GLint
)teximage
->Border
)) {
1067 sprintf(message
, "glCopyTexSubImage%dD(yoffset=%d)", dimensions
, yoffset
);
1068 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1071 /* NOTE: we're adding the border here, not subtracting! */
1072 if (yoffset
+height
> (GLint
) (teximage
->Height
+teximage
->Border
)) {
1074 sprintf(message
, "glCopyTexSubImage%dD(yoffset+height)", dimensions
);
1075 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1080 if (dimensions
> 2) {
1081 if (zoffset
< -((GLint
)teximage
->Border
)) {
1083 sprintf(message
, "glCopyTexSubImage%dD(zoffset)", dimensions
);
1084 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1087 if (zoffset
> (GLint
) (teximage
->Depth
+teximage
->Border
)) {
1089 sprintf(message
, "glCopyTexSubImage%dD(zoffset+depth)", dimensions
);
1090 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1095 /* if we get here, the parameters are OK */
1102 _mesa_GetTexImage( GLenum target
, GLint level
, GLenum format
,
1103 GLenum type
, GLvoid
*pixels
)
1105 GET_CURRENT_CONTEXT(ctx
);
1106 const struct gl_texture_unit
*texUnit
;
1107 const struct gl_texture_object
*texObj
;
1108 struct gl_texture_image
*texImage
;
1110 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1112 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1113 _mesa_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
1117 if (_mesa_sizeof_type(type
) <= 0) {
1118 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
1122 if (_mesa_components_in_format(format
) <= 0 ||
1123 format
== GL_STENCIL_INDEX
) {
1124 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
1128 if (!ctx
->Extensions
.EXT_paletted_texture
&& is_index_format(format
)) {
1129 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1132 if (!ctx
->Extensions
.SGIX_depth_texture
&& format
== GL_DEPTH_COMPONENT
) {
1133 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1136 /* XXX what if format/type doesn't match texture format/type? */
1141 texUnit
= &(ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
]);
1142 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1143 if (!texObj
|| is_proxy_target(target
)) {
1144 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)");
1148 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1150 /* invalid mipmap level, not an error */
1154 if (!texImage
->Data
) {
1155 /* no image data, not an error */
1159 if (ctx
->NewState
& _NEW_PIXEL
)
1160 _mesa_update_state(ctx
);
1162 if (is_color_format(format
) &&
1163 ctx
->_ImageTransferState
& IMAGE_CONVOLUTION_BIT
) {
1164 /* convert texture image to GL_RGBA, GL_FLOAT */
1165 GLint width
= texImage
->Width
;
1166 GLint height
= texImage
->Height
;
1167 GLint depth
= texImage
->Depth
;
1169 GLfloat
*tmpImage
, *convImage
;
1170 tmpImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
1172 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
1175 convImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
1178 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
1182 for (img
= 0; img
< depth
; img
++) {
1183 GLint convWidth
, convHeight
;
1185 /* convert texture data to GLfloat/GL_RGBA */
1186 for (row
= 0; row
< height
; row
++) {
1187 GLchan texels
[1 << MAX_TEXTURE_LEVELS
][4];
1189 GLfloat
*dst
= tmpImage
+ row
* width
* 4;
1190 for (col
= 0; col
< width
; col
++) {
1191 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1194 _mesa_unpack_float_color_span(ctx
, width
, GL_RGBA
, dst
,
1195 GL_RGBA
, CHAN_TYPE
, texels
,
1196 &_mesa_native_packing
,
1197 ctx
->_ImageTransferState
& IMAGE_PRE_CONVOLUTION_BITS
,
1202 convHeight
= height
;
1205 if (target
== GL_TEXTURE_1D
) {
1206 if (ctx
->Pixel
.Convolution1DEnabled
) {
1207 _mesa_convolve_1d_image(ctx
, &convWidth
, tmpImage
, convImage
);
1211 if (ctx
->Pixel
.Convolution2DEnabled
) {
1212 _mesa_convolve_2d_image(ctx
, &convWidth
, &convHeight
,
1213 tmpImage
, convImage
);
1215 else if (ctx
->Pixel
.Separable2DEnabled
) {
1216 _mesa_convolve_sep_image(ctx
, &convWidth
, &convHeight
,
1217 tmpImage
, convImage
);
1221 /* pack convolved image */
1222 for (row
= 0; row
< convHeight
; row
++) {
1223 const GLfloat
*src
= convImage
+ row
* convWidth
* 4;
1224 GLvoid
*dest
= _mesa_image_address(&ctx
->Pack
, pixels
,
1225 convWidth
, convHeight
,
1226 format
, type
, img
, row
, 0);
1227 _mesa_pack_float_rgba_span(ctx
, convWidth
,
1228 (const GLfloat(*)[4]) src
,
1229 format
, type
, dest
, &ctx
->Pack
,
1230 ctx
->_ImageTransferState
& IMAGE_POST_CONVOLUTION_BITS
);
1238 /* no convolution, or non-rgba image */
1239 GLint width
= texImage
->Width
;
1240 GLint height
= texImage
->Height
;
1241 GLint depth
= texImage
->Depth
;
1243 for (img
= 0; img
< depth
; img
++) {
1244 for (row
= 0; row
< height
; row
++) {
1245 /* compute destination address in client memory */
1246 GLvoid
*dest
= _mesa_image_address( &ctx
->Unpack
, pixels
,
1247 width
, height
, format
, type
,
1251 if (format
== GL_COLOR_INDEX
) {
1252 GLuint indexRow
[MAX_WIDTH
];
1254 for (col
= 0; col
< width
; col
++) {
1255 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1256 (GLvoid
*) &indexRow
[col
]);
1258 _mesa_pack_index_span(ctx
, width
, type
, dest
,
1259 indexRow
, &ctx
->Pack
,
1260 ctx
->_ImageTransferState
);
1262 else if (format
== GL_DEPTH_COMPONENT
) {
1263 GLfloat depthRow
[MAX_WIDTH
];
1265 for (col
= 0; col
< width
; col
++) {
1266 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1267 (GLvoid
*) &depthRow
[col
]);
1269 _mesa_pack_depth_span(ctx
, width
, dest
, type
,
1270 depthRow
, &ctx
->Pack
);
1273 /* general case: convert row to RGBA format */
1274 GLchan rgba
[MAX_WIDTH
][4];
1276 for (col
= 0; col
< width
; col
++) {
1277 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1278 (GLvoid
*) rgba
[col
]);
1280 _mesa_pack_rgba_span(ctx
, width
, (const GLchan (*)[4])rgba
,
1281 format
, type
, dest
, &ctx
->Pack
,
1282 ctx
->_ImageTransferState
);
1292 * Called from the API. Note that width includes the border.
1295 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
1296 GLsizei width
, GLint border
, GLenum format
,
1297 GLenum type
, const GLvoid
*pixels
)
1299 GLsizei postConvWidth
= width
;
1300 GET_CURRENT_CONTEXT(ctx
);
1301 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1303 if (is_color_format(internalFormat
)) {
1304 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1307 if (target
== GL_TEXTURE_1D
) {
1308 struct gl_texture_unit
*texUnit
;
1309 struct gl_texture_object
*texObj
;
1310 struct gl_texture_image
*texImage
;
1312 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1313 format
, type
, 1, postConvWidth
, 1, 1, border
)) {
1314 return; /* error was recorded */
1317 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1318 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1319 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1322 texImage
= _mesa_alloc_texture_image();
1323 texObj
->Image
[level
] = texImage
;
1325 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
1329 else if (texImage
->Data
) {
1330 /* free the old texture data */
1331 FREE(texImage
->Data
);
1332 texImage
->Data
= NULL
;
1334 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1335 init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1336 border
, internalFormat
);
1338 if (ctx
->NewState
& _NEW_PIXEL
)
1339 _mesa_update_state(ctx
);
1341 ASSERT(ctx
->Driver
.TexImage1D
);
1343 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1344 width
, border
, format
, type
, pixels
,
1345 &ctx
->Unpack
, texObj
, texImage
);
1348 GLubyte
*dummy
= make_null_texture(width
, 1, 1, format
);
1350 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1352 format
, GL_UNSIGNED_BYTE
, dummy
,
1353 &_mesa_native_packing
, texObj
, texImage
);
1358 /* one of these has to be non-zero! */
1359 ASSERT(texImage
->RedBits
|| texImage
->IndexBits
|| texImage
->AlphaBits
||
1360 texImage
->LuminanceBits
|| texImage
->IntensityBits
||
1361 texImage
->DepthBits
);
1362 ASSERT(texImage
->FetchTexel
);
1365 texObj
->Complete
= GL_FALSE
;
1366 ctx
->NewState
|= _NEW_TEXTURE
;
1368 else if (target
== GL_PROXY_TEXTURE_1D
) {
1369 /* Proxy texture: check for errors and update proxy state */
1370 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1372 postConvWidth
, 1, 1, border
);
1374 struct gl_texture_unit
*texUnit
;
1375 struct gl_texture_image
*texImage
;
1376 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1377 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1378 init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1379 border
, internalFormat
);
1380 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1381 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1382 internalFormat
, format
, type
,
1383 postConvWidth
, 1, 1, border
);
1386 /* if error, clear all proxy texture image parameters */
1387 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1388 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
1393 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1400 _mesa_TexImage2D( GLenum target
, GLint level
, GLint internalFormat
,
1401 GLsizei width
, GLsizei height
, GLint border
,
1402 GLenum format
, GLenum type
,
1403 const GLvoid
*pixels
)
1405 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1406 GET_CURRENT_CONTEXT(ctx
);
1407 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1409 if (is_color_format(internalFormat
)) {
1410 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1414 if (target
== GL_TEXTURE_2D
||
1415 (ctx
->Extensions
.ARB_texture_cube_map
&&
1416 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1417 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
1418 /* non-proxy target */
1419 struct gl_texture_unit
*texUnit
;
1420 struct gl_texture_object
*texObj
;
1421 struct gl_texture_image
*texImage
;
1423 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1424 format
, type
, 2, postConvWidth
, postConvHeight
,
1426 return; /* error was recorded */
1429 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1430 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1431 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1434 texImage
= _mesa_alloc_texture_image();
1435 set_tex_image(texObj
, target
, level
, texImage
);
1437 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1441 else if (texImage
->Data
) {
1442 /* free the old texture data */
1443 FREE(texImage
->Data
);
1444 texImage
->Data
= NULL
;
1446 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1447 init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
, 1,
1448 border
, internalFormat
);
1450 if (ctx
->NewState
& _NEW_PIXEL
)
1451 _mesa_update_state(ctx
);
1453 ASSERT(ctx
->Driver
.TexImage2D
);
1455 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1456 width
, height
, border
, format
, type
, pixels
,
1457 &ctx
->Unpack
, texObj
, texImage
);
1460 GLubyte
*dummy
= make_null_texture(width
, height
, 1, format
);
1462 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1463 width
, height
, border
,
1464 format
, GL_UNSIGNED_BYTE
, dummy
,
1465 &_mesa_native_packing
, texObj
, texImage
);
1470 /* one of these has to be non-zero! */
1471 ASSERT(texImage
->RedBits
|| texImage
->IndexBits
|| texImage
->AlphaBits
||
1472 texImage
->LuminanceBits
|| texImage
->IntensityBits
||
1473 texImage
->DepthBits
);
1474 ASSERT(texImage
->FetchTexel
);
1477 texObj
->Complete
= GL_FALSE
;
1478 ctx
->NewState
|= _NEW_TEXTURE
;
1480 else if (target
== GL_PROXY_TEXTURE_2D
) {
1481 /* Proxy texture: check for errors and update proxy state */
1482 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1484 postConvWidth
, postConvHeight
, 1, border
);
1486 struct gl_texture_unit
*texUnit
;
1487 struct gl_texture_image
*texImage
;
1488 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1489 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1490 init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
, 1,
1491 border
, internalFormat
);
1492 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1493 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1494 internalFormat
, format
, type
,
1495 postConvWidth
, postConvHeight
, 1, border
);
1498 /* if error, clear all proxy texture image parameters */
1499 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1500 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
1505 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1512 * Called by the API or display list executor.
1513 * Note that width and height include the border.
1516 _mesa_TexImage3D( GLenum target
, GLint level
, GLint internalFormat
,
1517 GLsizei width
, GLsizei height
, GLsizei depth
,
1518 GLint border
, GLenum format
, GLenum type
,
1519 const GLvoid
*pixels
)
1521 GET_CURRENT_CONTEXT(ctx
);
1522 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1524 if (target
== GL_TEXTURE_3D
) {
1525 struct gl_texture_unit
*texUnit
;
1526 struct gl_texture_object
*texObj
;
1527 struct gl_texture_image
*texImage
;
1529 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1530 format
, type
, 3, width
, height
, depth
, border
)) {
1531 return; /* error was recorded */
1534 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1535 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1536 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1539 texImage
= _mesa_alloc_texture_image();
1540 texObj
->Image
[level
] = texImage
;
1542 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
1546 else if (texImage
->Data
) {
1547 FREE(texImage
->Data
);
1548 texImage
->Data
= NULL
;
1550 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1551 init_teximage_fields(ctx
, texImage
, width
, height
, depth
, border
,
1554 if (ctx
->NewState
& _NEW_PIXEL
)
1555 _mesa_update_state(ctx
);
1557 ASSERT(ctx
->Driver
.TexImage3D
);
1559 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, internalFormat
,
1560 width
, height
, depth
, border
,
1561 format
, type
, pixels
,
1562 &ctx
->Unpack
, texObj
, texImage
);
1565 GLubyte
*dummy
= make_null_texture(width
, height
, depth
, format
);
1567 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, internalFormat
,
1568 width
, height
, depth
, border
,
1569 format
, GL_UNSIGNED_BYTE
, dummy
,
1570 &_mesa_native_packing
, texObj
, texImage
);
1575 /* one of these has to be non-zero! */
1576 ASSERT(texImage
->RedBits
|| texImage
->IndexBits
|| texImage
->AlphaBits
||
1577 texImage
->LuminanceBits
|| texImage
->IntensityBits
||
1578 texImage
->DepthBits
);
1579 ASSERT(texImage
->FetchTexel
);
1582 texObj
->Complete
= GL_FALSE
;
1583 ctx
->NewState
|= _NEW_TEXTURE
;
1585 else if (target
== GL_PROXY_TEXTURE_3D
) {
1586 /* Proxy texture: check for errors and update proxy state */
1587 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1588 format
, type
, 3, width
, height
, depth
, border
);
1590 struct gl_texture_unit
*texUnit
;
1591 struct gl_texture_image
*texImage
;
1592 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1593 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1594 init_teximage_fields(ctx
, texImage
, width
, height
, 1,
1595 border
, internalFormat
);
1596 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1597 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1598 internalFormat
, format
, type
,
1599 width
, height
, depth
, border
);
1602 /* if error, clear all proxy texture image parameters */
1603 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1604 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
1609 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1616 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
1617 GLsizei width
, GLsizei height
, GLsizei depth
,
1618 GLint border
, GLenum format
, GLenum type
,
1619 const GLvoid
*pixels
)
1621 _mesa_TexImage3D(target
, level
, (GLint
) internalFormat
, width
, height
,
1622 depth
, border
, format
, type
, pixels
);
1628 _mesa_TexSubImage1D( GLenum target
, GLint level
,
1629 GLint xoffset
, GLsizei width
,
1630 GLenum format
, GLenum type
,
1631 const GLvoid
*pixels
)
1633 GLsizei postConvWidth
= width
;
1634 GET_CURRENT_CONTEXT(ctx
);
1635 struct gl_texture_unit
*texUnit
;
1636 struct gl_texture_object
*texObj
;
1637 struct gl_texture_image
*texImage
;
1639 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1641 if (ctx
->NewState
& _NEW_PIXEL
)
1642 _mesa_update_state(ctx
);
1644 /* XXX should test internal format */
1645 if (is_color_format(format
)) {
1646 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1649 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
1650 postConvWidth
, 1, 1, format
, type
)) {
1651 return; /* error was detected */
1654 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1655 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1656 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1659 if (width
== 0 || !pixels
)
1660 return; /* no-op, not an error */
1662 ASSERT(ctx
->Driver
.TexSubImage1D
);
1663 (*ctx
->Driver
.TexSubImage1D
)(ctx
, target
, level
, xoffset
, width
,
1664 format
, type
, pixels
, &ctx
->Unpack
,
1666 ctx
->NewState
|= _NEW_TEXTURE
;
1671 _mesa_TexSubImage2D( GLenum target
, GLint level
,
1672 GLint xoffset
, GLint yoffset
,
1673 GLsizei width
, GLsizei height
,
1674 GLenum format
, GLenum type
,
1675 const GLvoid
*pixels
)
1677 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1678 GET_CURRENT_CONTEXT(ctx
);
1679 struct gl_texture_unit
*texUnit
;
1680 struct gl_texture_object
*texObj
;
1681 struct gl_texture_image
*texImage
;
1683 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1685 if (ctx
->NewState
& _NEW_PIXEL
)
1686 _mesa_update_state(ctx
);
1688 /* XXX should test internal format */
1689 if (is_color_format(format
)) {
1690 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1694 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1695 postConvWidth
, postConvHeight
, 1, format
, type
)) {
1696 return; /* error was detected */
1699 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1700 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1701 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1704 if (width
== 0 || height
== 0 || !pixels
)
1705 return; /* no-op, not an error */
1707 ASSERT(ctx
->Driver
.TexSubImage2D
);
1708 (*ctx
->Driver
.TexSubImage2D
)(ctx
, target
, level
, xoffset
, yoffset
,
1709 width
, height
, format
, type
, pixels
,
1710 &ctx
->Unpack
, texObj
, texImage
);
1711 ctx
->NewState
|= _NEW_TEXTURE
;
1717 _mesa_TexSubImage3D( GLenum target
, GLint level
,
1718 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1719 GLsizei width
, GLsizei height
, GLsizei depth
,
1720 GLenum format
, GLenum type
,
1721 const GLvoid
*pixels
)
1723 GET_CURRENT_CONTEXT(ctx
);
1724 struct gl_texture_unit
*texUnit
;
1725 struct gl_texture_object
*texObj
;
1726 struct gl_texture_image
*texImage
;
1728 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1730 if (ctx
->NewState
& _NEW_PIXEL
)
1731 _mesa_update_state(ctx
);
1733 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
1734 width
, height
, depth
, format
, type
)) {
1735 return; /* error was detected */
1738 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1739 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1740 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1743 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
1744 return; /* no-op, not an error */
1746 ASSERT(ctx
->Driver
.TexSubImage3D
);
1747 (*ctx
->Driver
.TexSubImage3D
)(ctx
, target
, level
,
1748 xoffset
, yoffset
, zoffset
,
1749 width
, height
, depth
,
1750 format
, type
, pixels
,
1751 &ctx
->Unpack
, texObj
, texImage
);
1752 ctx
->NewState
|= _NEW_TEXTURE
;
1758 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
1759 GLenum internalFormat
,
1761 GLsizei width
, GLint border
)
1763 struct gl_texture_unit
*texUnit
;
1764 struct gl_texture_object
*texObj
;
1765 struct gl_texture_image
*texImage
;
1766 GLsizei postConvWidth
= width
;
1767 GET_CURRENT_CONTEXT(ctx
);
1768 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1770 if (ctx
->NewState
& _NEW_PIXEL
)
1771 _mesa_update_state(ctx
);
1773 if (is_color_format(internalFormat
)) {
1774 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1777 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
1778 postConvWidth
, 1, border
))
1781 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1782 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1783 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1785 texImage
= _mesa_alloc_texture_image();
1786 set_tex_image(texObj
, target
, level
, texImage
);
1788 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D");
1792 else if (texImage
->Data
) {
1793 /* free the old texture data */
1794 FREE(texImage
->Data
);
1795 texImage
->Data
= NULL
;
1798 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1799 init_teximage_fields(ctx
, texImage
, postConvWidth
, 1, 1,
1800 border
, internalFormat
);
1803 ASSERT(ctx
->Driver
.CopyTexImage1D
);
1804 (*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
, internalFormat
,
1805 x
, y
, width
, border
);
1808 texObj
->Complete
= GL_FALSE
;
1809 ctx
->NewState
|= _NEW_TEXTURE
;
1815 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
1816 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1819 struct gl_texture_unit
*texUnit
;
1820 struct gl_texture_object
*texObj
;
1821 struct gl_texture_image
*texImage
;
1822 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1823 GET_CURRENT_CONTEXT(ctx
);
1824 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1826 if (ctx
->NewState
& _NEW_PIXEL
)
1827 _mesa_update_state(ctx
);
1829 if (is_color_format(internalFormat
)) {
1830 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1834 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
1835 postConvWidth
, postConvHeight
, border
))
1838 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1839 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1840 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1842 texImage
= _mesa_alloc_texture_image();
1843 set_tex_image(texObj
, target
, level
, texImage
);
1845 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D");
1849 else if (texImage
->Data
) {
1850 /* free the old texture data */
1851 FREE(texImage
->Data
);
1852 texImage
->Data
= NULL
;
1855 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1856 init_teximage_fields(ctx
, texImage
, postConvWidth
, postConvHeight
, 1,
1857 border
, internalFormat
);
1859 ASSERT(ctx
->Driver
.CopyTexImage2D
);
1860 (*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
, internalFormat
,
1861 x
, y
, width
, height
, border
);
1864 texObj
->Complete
= GL_FALSE
;
1865 ctx
->NewState
|= _NEW_TEXTURE
;
1871 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
1872 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
1874 GLsizei postConvWidth
= width
;
1875 GET_CURRENT_CONTEXT(ctx
);
1876 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1878 if (ctx
->NewState
& _NEW_PIXEL
)
1879 _mesa_update_state(ctx
);
1881 /* XXX should test internal format */
1882 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1884 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
1885 xoffset
, 0, 0, postConvWidth
, 1))
1888 ASSERT(ctx
->Driver
.CopyTexSubImage1D
);
1889 (*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
, xoffset
, x
, y
, width
);
1890 ctx
->NewState
|= _NEW_TEXTURE
;
1896 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
1897 GLint xoffset
, GLint yoffset
,
1898 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1900 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1901 GET_CURRENT_CONTEXT(ctx
);
1902 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1904 if (ctx
->NewState
& _NEW_PIXEL
)
1905 _mesa_update_state(ctx
);
1907 /* XXX should test internal format */
1908 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
1910 if (copytexsubimage_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1911 postConvWidth
, postConvHeight
))
1914 ASSERT(ctx
->Driver
.CopyTexSubImage2D
);
1915 (*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
1916 xoffset
, yoffset
, x
, y
, width
, height
);
1917 ctx
->NewState
|= _NEW_TEXTURE
;
1923 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
1924 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1925 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1927 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1928 GET_CURRENT_CONTEXT(ctx
);
1929 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1931 if (ctx
->NewState
& _NEW_PIXEL
)
1932 _mesa_update_state(ctx
);
1934 /* XXX should test internal format */
1935 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
1937 if (copytexsubimage_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
,
1938 zoffset
, postConvWidth
, postConvHeight
))
1941 ASSERT(ctx
->Driver
.CopyTexSubImage3D
);
1942 (*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
1943 xoffset
, yoffset
, zoffset
,
1944 x
, y
, width
, height
);
1945 ctx
->NewState
|= _NEW_TEXTURE
;
1951 _mesa_CompressedTexImage1DARB(GLenum target
, GLint level
,
1952 GLenum internalFormat
, GLsizei width
,
1953 GLint border
, GLsizei imageSize
,
1956 GET_CURRENT_CONTEXT(ctx
);
1957 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1959 switch (internalFormat
) {
1960 case GL_COMPRESSED_ALPHA_ARB
:
1961 case GL_COMPRESSED_LUMINANCE_ARB
:
1962 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
1963 case GL_COMPRESSED_INTENSITY_ARB
:
1964 case GL_COMPRESSED_RGB_ARB
:
1965 case GL_COMPRESSED_RGBA_ARB
:
1966 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB");
1969 /* silence compiler warning */
1973 if (target
== GL_TEXTURE_1D
) {
1974 struct gl_texture_unit
*texUnit
;
1975 struct gl_texture_object
*texObj
;
1976 struct gl_texture_image
*texImage
;
1978 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1979 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
1980 return; /* error in texture image was detected */
1983 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1984 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1985 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1988 texImage
= _mesa_alloc_texture_image();
1989 texObj
->Image
[level
] = texImage
;
1991 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage1DARB");
1995 else if (texImage
->Data
) {
1996 FREE(texImage
->Data
);
1997 texImage
->Data
= NULL
;
2000 init_teximage_fields(ctx
, texImage
, width
, 1, 1, border
, internalFormat
);
2002 if (ctx
->Extensions
.ARB_texture_compression
) {
2003 ASSERT(ctx
->Driver
.CompressedTexImage1D
);
2004 (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
,
2005 internalFormat
, width
, border
,
2008 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2012 texObj
->Complete
= GL_FALSE
;
2013 ctx
->NewState
|= _NEW_TEXTURE
;
2015 else if (target
== GL_PROXY_TEXTURE_1D
) {
2016 /* Proxy texture: check for errors and update proxy state */
2017 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2018 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
);
2020 struct gl_texture_unit
*texUnit
;
2021 struct gl_texture_image
*texImage
;
2022 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2023 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2024 init_teximage_fields(ctx
, texImage
, width
, 1, 1,
2025 border
, internalFormat
);
2026 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2027 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2028 internalFormat
, GL_NONE
, GL_NONE
,
2029 width
, 1, 1, border
);
2032 /* if error, clear all proxy texture image parameters */
2033 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2034 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
2039 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB(target)" );
2046 _mesa_CompressedTexImage2DARB(GLenum target
, GLint level
,
2047 GLenum internalFormat
, GLsizei width
,
2048 GLsizei height
, GLint border
, GLsizei imageSize
,
2051 GET_CURRENT_CONTEXT(ctx
);
2052 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2054 switch (internalFormat
) {
2055 case GL_COMPRESSED_ALPHA_ARB
:
2056 case GL_COMPRESSED_LUMINANCE_ARB
:
2057 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2058 case GL_COMPRESSED_INTENSITY_ARB
:
2059 case GL_COMPRESSED_RGB_ARB
:
2060 case GL_COMPRESSED_RGBA_ARB
:
2061 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB");
2064 /* silence compiler warning */
2068 if (target
== GL_TEXTURE_2D
||
2069 (ctx
->Extensions
.ARB_texture_cube_map
&&
2070 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2071 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
2072 struct gl_texture_unit
*texUnit
;
2073 struct gl_texture_object
*texObj
;
2074 struct gl_texture_image
*texImage
;
2076 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2077 GL_NONE
, GL_NONE
, 1, width
, height
, 1, border
)) {
2078 return; /* error in texture image was detected */
2081 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2082 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2083 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2086 texImage
= _mesa_alloc_texture_image();
2087 texObj
->Image
[level
] = texImage
;
2089 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
2093 else if (texImage
->Data
) {
2094 FREE(texImage
->Data
);
2095 texImage
->Data
= NULL
;
2098 init_teximage_fields(ctx
, texImage
, width
, height
, 1, border
,
2101 if (ctx
->Extensions
.ARB_texture_compression
) {
2102 ASSERT(ctx
->Driver
.CompressedTexImage2D
);
2103 (*ctx
->Driver
.CompressedTexImage2D
)(ctx
, target
, level
,
2104 internalFormat
, width
, height
,
2105 border
, imageSize
, data
,
2107 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2111 texObj
->Complete
= GL_FALSE
;
2112 ctx
->NewState
|= _NEW_TEXTURE
;
2114 else if (target
== GL_PROXY_TEXTURE_2D
) {
2115 /* Proxy texture: check for errors and update proxy state */
2116 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2117 GL_NONE
, GL_NONE
, 2, width
, height
, 1, border
);
2119 struct gl_texture_unit
*texUnit
;
2120 struct gl_texture_image
*texImage
;
2121 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2122 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2123 init_teximage_fields(ctx
, texImage
, width
, height
, 1,
2124 border
, internalFormat
);
2125 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2126 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2127 internalFormat
, GL_NONE
, GL_NONE
,
2128 width
, height
, 1, border
);
2131 /* if error, clear all proxy texture image parameters */
2132 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2133 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
2138 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB(target)" );
2145 _mesa_CompressedTexImage3DARB(GLenum target
, GLint level
,
2146 GLenum internalFormat
, GLsizei width
,
2147 GLsizei height
, GLsizei depth
, GLint border
,
2148 GLsizei imageSize
, const GLvoid
*data
)
2150 GET_CURRENT_CONTEXT(ctx
);
2151 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2153 switch (internalFormat
) {
2154 case GL_COMPRESSED_ALPHA_ARB
:
2155 case GL_COMPRESSED_LUMINANCE_ARB
:
2156 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2157 case GL_COMPRESSED_INTENSITY_ARB
:
2158 case GL_COMPRESSED_RGB_ARB
:
2159 case GL_COMPRESSED_RGBA_ARB
:
2160 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB");
2163 /* silence compiler warning */
2167 if (target
== GL_TEXTURE_3D
) {
2168 struct gl_texture_unit
*texUnit
;
2169 struct gl_texture_object
*texObj
;
2170 struct gl_texture_image
*texImage
;
2172 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2173 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
)) {
2174 return; /* error in texture image was detected */
2177 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2178 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2179 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2182 texImage
= _mesa_alloc_texture_image();
2183 texObj
->Image
[level
] = texImage
;
2185 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage3DARB");
2189 else if (texImage
->Data
) {
2190 FREE(texImage
->Data
);
2191 texImage
->Data
= NULL
;
2194 init_teximage_fields(ctx
, texImage
, width
, height
, depth
, border
,
2197 if (ctx
->Extensions
.ARB_texture_compression
) {
2198 ASSERT(ctx
->Driver
.CompressedTexImage3D
);
2199 (*ctx
->Driver
.CompressedTexImage3D
)(ctx
, target
, level
,
2201 width
, height
, depth
,
2202 border
, imageSize
, data
,
2204 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2208 texObj
->Complete
= GL_FALSE
;
2209 ctx
->NewState
|= _NEW_TEXTURE
;
2211 else if (target
== GL_PROXY_TEXTURE_3D
) {
2212 /* Proxy texture: check for errors and update proxy state */
2213 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2214 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
);
2216 struct gl_texture_unit
*texUnit
;
2217 struct gl_texture_image
*texImage
;
2218 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2219 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2220 init_teximage_fields(ctx
, texImage
, width
, height
, depth
,
2221 border
, internalFormat
);
2222 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2223 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2224 internalFormat
, GL_NONE
, GL_NONE
,
2225 width
, height
, depth
, border
);
2228 /* if error, clear all proxy texture image parameters */
2229 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2230 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
2235 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB(target)" );
2242 _mesa_CompressedTexSubImage1DARB(GLenum target
, GLint level
, GLint xoffset
,
2243 GLsizei width
, GLenum format
,
2244 GLsizei imageSize
, const GLvoid
*data
)
2246 struct gl_texture_unit
*texUnit
;
2247 struct gl_texture_object
*texObj
;
2248 struct gl_texture_image
*texImage
;
2249 GET_CURRENT_CONTEXT(ctx
);
2251 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2253 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
2254 width
, 1, 1, format
, GL_NONE
)) {
2255 return; /* error was detected */
2258 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2259 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2260 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2263 if (width
== 0 || !data
)
2264 return; /* no-op, not an error */
2266 if (ctx
->Driver
.CompressedTexSubImage1D
) {
2267 (*ctx
->Driver
.CompressedTexSubImage1D
)(ctx
, target
, level
,
2269 format
, imageSize
, data
,
2272 ctx
->NewState
|= _NEW_TEXTURE
;
2277 _mesa_CompressedTexSubImage2DARB(GLenum target
, GLint level
, GLint xoffset
,
2278 GLint yoffset
, GLsizei width
, GLsizei height
,
2279 GLenum format
, GLsizei imageSize
,
2282 struct gl_texture_unit
*texUnit
;
2283 struct gl_texture_object
*texObj
;
2284 struct gl_texture_image
*texImage
;
2285 GET_CURRENT_CONTEXT(ctx
);
2287 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2289 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2290 width
, height
, 1, format
, GL_NONE
)) {
2291 return; /* error was detected */
2294 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2295 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2296 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2299 if (width
== 0 || height
== 0 || !data
)
2300 return; /* no-op, not an error */
2302 if (ctx
->Driver
.CompressedTexSubImage2D
) {
2303 (*ctx
->Driver
.CompressedTexSubImage2D
)(ctx
, target
, level
,
2304 xoffset
, yoffset
, width
, height
,
2305 format
, imageSize
, data
,
2308 ctx
->NewState
|= _NEW_TEXTURE
;
2313 _mesa_CompressedTexSubImage3DARB(GLenum target
, GLint level
, GLint xoffset
,
2314 GLint yoffset
, GLint zoffset
, GLsizei width
,
2315 GLsizei height
, GLsizei depth
, GLenum format
,
2316 GLsizei imageSize
, const GLvoid
*data
)
2318 struct gl_texture_unit
*texUnit
;
2319 struct gl_texture_object
*texObj
;
2320 struct gl_texture_image
*texImage
;
2321 GET_CURRENT_CONTEXT(ctx
);
2323 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2325 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2326 width
, height
, depth
, format
, GL_NONE
)) {
2327 return; /* error was detected */
2330 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2331 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2332 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2335 if (width
== 0 || height
== 0 || depth
== 0 || !data
)
2336 return; /* no-op, not an error */
2338 if (ctx
->Driver
.CompressedTexSubImage3D
) {
2339 (*ctx
->Driver
.CompressedTexSubImage3D
)(ctx
, target
, level
,
2340 xoffset
, yoffset
, zoffset
,
2341 width
, height
, depth
,
2342 format
, imageSize
, data
,
2345 ctx
->NewState
|= _NEW_TEXTURE
;
2350 _mesa_GetCompressedTexImageARB(GLenum target
, GLint level
, GLvoid
*img
)
2352 const struct gl_texture_unit
*texUnit
;
2353 const struct gl_texture_object
*texObj
;
2354 struct gl_texture_image
*texImage
;
2355 GET_CURRENT_CONTEXT(ctx
);
2357 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2359 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
2360 _mesa_error( ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)" );
2364 if (is_proxy_target(target
)) {
2365 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB(target)");
2369 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2370 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2371 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2374 /* invalid mipmap level */
2375 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
2379 if (!texImage
->IsCompressed
) {
2380 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetCompressedTexImageARB");
2387 if (ctx
->Extensions
.ARB_texture_compression
) {
2388 ASSERT(ctx
->Driver
.GetCompressedTexImage
);
2389 (*ctx
->Driver
.GetCompressedTexImage
)(ctx
, target
, level
, img
, texObj
,