1 /* $Id: teximage.c,v 1.109 2002/06/15 03:03:09 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2002 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
)
61 #if CHAN_TYPE == GL_FLOAT
62 _mesa_problem(NULL
, "PrintTexture doesn't support float channels");
65 const GLchan
*data
= (const GLchan
*) img
->Data
;
68 printf("No texture data\n");
72 switch (img
->Format
) {
79 case GL_LUMINANCE_ALPHA
:
89 _mesa_problem(NULL
, "error in PrintTexture\n");
93 for (i
= 0; i
< img
->Height
; i
++) {
94 for (j
= 0; j
< img
->Width
; j
++) {
96 printf("%02x ", data
[0]);
98 printf("%02x%02x ", data
[0], data
[1]);
100 printf("%02x%02x%02x ", data
[0], data
[1], data
[2]);
102 printf("%02x%02x%02x%02x ", data
[0], data
[1], data
[2], data
[3]);
114 * Compute log base 2 of n.
115 * If n isn't an exact power of two return -1.
116 * If n < 0 return -1.
143 * Given an internal texture format enum or 1, 2, 3, 4 return the
144 * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE,
145 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.
146 * Return -1 if invalid enum.
149 _mesa_base_tex_format( GLcontext
*ctx
, GLint format
)
152 * Ask the driver for the base format, if it doesn't
153 * know, it will return -1;
155 if (ctx
->Driver
.BaseCompressedTexFormat
) {
156 GLint ifmt
= (*ctx
->Driver
.BaseCompressedTexFormat
)(ctx
, format
);
176 case GL_LUMINANCE_ALPHA
:
177 case GL_LUMINANCE4_ALPHA4
:
178 case GL_LUMINANCE6_ALPHA2
:
179 case GL_LUMINANCE8_ALPHA8
:
180 case GL_LUMINANCE12_ALPHA4
:
181 case GL_LUMINANCE12_ALPHA12
:
182 case GL_LUMINANCE16_ALPHA16
:
183 return GL_LUMINANCE_ALPHA
;
211 case GL_COLOR_INDEX1_EXT
:
212 case GL_COLOR_INDEX2_EXT
:
213 case GL_COLOR_INDEX4_EXT
:
214 case GL_COLOR_INDEX8_EXT
:
215 case GL_COLOR_INDEX12_EXT
:
216 case GL_COLOR_INDEX16_EXT
:
217 return GL_COLOR_INDEX
;
218 case GL_DEPTH_COMPONENT
:
219 case GL_DEPTH_COMPONENT16_SGIX
:
220 case GL_DEPTH_COMPONENT24_SGIX
:
221 case GL_DEPTH_COMPONENT32_SGIX
:
222 if (ctx
->Extensions
.SGIX_depth_texture
)
223 return GL_DEPTH_COMPONENT
;
227 return -1; /* error */
233 * Test if the given image format is a color/rgba format. That is,
234 * not color index, depth, stencil, etc.
237 is_color_format(GLenum format
)
252 case GL_LUMINANCE_ALPHA
:
253 case GL_LUMINANCE4_ALPHA4
:
254 case GL_LUMINANCE6_ALPHA2
:
255 case GL_LUMINANCE8_ALPHA8
:
256 case GL_LUMINANCE12_ALPHA4
:
257 case GL_LUMINANCE12_ALPHA12
:
258 case GL_LUMINANCE16_ALPHA16
:
290 is_index_format(GLenum format
)
294 case GL_COLOR_INDEX1_EXT
:
295 case GL_COLOR_INDEX2_EXT
:
296 case GL_COLOR_INDEX4_EXT
:
297 case GL_COLOR_INDEX8_EXT
:
298 case GL_COLOR_INDEX12_EXT
:
299 case GL_COLOR_INDEX16_EXT
:
308 * Return GL_TRUE if internalFormat is a compressed format, return GL_FALSE
312 is_compressed_format(GLcontext
*ctx
, GLenum internalFormat
)
314 if (ctx
->Driver
.BaseCompressedTexFormat
) {
315 GLint b
= (*ctx
->Driver
.BaseCompressedTexFormat
)(ctx
, internalFormat
);
327 * Store a gl_texture_image pointer in a gl_texture_object structure
328 * according to the target and level parameters.
329 * This was basically prompted by the introduction of cube maps.
332 _mesa_set_tex_image(struct gl_texture_object
*tObj
,
333 GLenum target
, GLint level
,
334 struct gl_texture_image
*texImage
)
342 tObj
->Image
[level
] = texImage
;
344 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
345 tObj
->Image
[level
] = texImage
;
347 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
348 tObj
->NegX
[level
] = texImage
;
350 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
351 tObj
->PosY
[level
] = texImage
;
353 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
354 tObj
->NegY
[level
] = texImage
;
356 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
357 tObj
->PosZ
[level
] = texImage
;
359 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
360 tObj
->NegZ
[level
] = texImage
;
362 case GL_TEXTURE_RECTANGLE_NV
:
364 tObj
->Image
[level
] = texImage
;
367 _mesa_problem(NULL
, "bad target in _mesa_set_tex_image()");
375 * Return new gl_texture_image struct with all fields initialized to zero.
377 struct gl_texture_image
*
378 _mesa_alloc_texture_image( void )
380 return CALLOC_STRUCT(gl_texture_image
);
386 _mesa_free_texture_image( struct gl_texture_image
*teximage
)
388 if (teximage
->Data
) {
389 MESA_PBUFFER_FREE( teximage
->Data
);
390 teximage
->Data
= NULL
;
397 * Return GL_TRUE if the target is a proxy target.
400 is_proxy_target(GLenum target
)
402 return (target
== GL_PROXY_TEXTURE_1D
||
403 target
== GL_PROXY_TEXTURE_2D
||
404 target
== GL_PROXY_TEXTURE_3D
||
405 target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
);
410 * Given a texture unit and a texture target, return the corresponding
413 struct gl_texture_object
*
414 _mesa_select_tex_object(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
419 return texUnit
->Current1D
;
420 case GL_PROXY_TEXTURE_1D
:
421 return ctx
->Texture
.Proxy1D
;
423 return texUnit
->Current2D
;
424 case GL_PROXY_TEXTURE_2D
:
425 return ctx
->Texture
.Proxy2D
;
427 return texUnit
->Current3D
;
428 case GL_PROXY_TEXTURE_3D
:
429 return ctx
->Texture
.Proxy3D
;
430 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
431 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
432 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
433 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
434 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
435 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
436 case GL_TEXTURE_CUBE_MAP_ARB
:
437 return ctx
->Extensions
.ARB_texture_cube_map
438 ? texUnit
->CurrentCubeMap
: NULL
;
439 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
440 return ctx
->Extensions
.ARB_texture_cube_map
441 ? ctx
->Texture
.ProxyCubeMap
: NULL
;
442 case GL_TEXTURE_RECTANGLE_NV
:
443 return ctx
->Extensions
.NV_texture_rectangle
444 ? texUnit
->CurrentRect
: NULL
;
445 case GL_PROXY_TEXTURE_RECTANGLE_NV
:
446 return ctx
->Extensions
.NV_texture_rectangle
447 ? ctx
->Texture
.ProxyRect
: NULL
;
449 _mesa_problem(NULL
, "bad target in _mesa_select_tex_object()");
456 * Return the texture image struct which corresponds to target and level
457 * for the given texture unit.
459 struct gl_texture_image
*
460 _mesa_select_tex_image(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
461 GLenum target
, GLint level
)
464 ASSERT(level
< MAX_TEXTURE_LEVELS
);
467 return texUnit
->Current1D
->Image
[level
];
468 case GL_PROXY_TEXTURE_1D
:
469 return ctx
->Texture
.Proxy1D
->Image
[level
];
471 return texUnit
->Current2D
->Image
[level
];
472 case GL_PROXY_TEXTURE_2D
:
473 return ctx
->Texture
.Proxy2D
->Image
[level
];
475 return texUnit
->Current3D
->Image
[level
];
476 case GL_PROXY_TEXTURE_3D
:
477 return ctx
->Texture
.Proxy3D
->Image
[level
];
478 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
479 if (ctx
->Extensions
.ARB_texture_cube_map
)
480 return texUnit
->CurrentCubeMap
->Image
[level
];
483 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
484 if (ctx
->Extensions
.ARB_texture_cube_map
)
485 return texUnit
->CurrentCubeMap
->NegX
[level
];
488 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
489 if (ctx
->Extensions
.ARB_texture_cube_map
)
490 return texUnit
->CurrentCubeMap
->PosY
[level
];
493 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
494 if (ctx
->Extensions
.ARB_texture_cube_map
)
495 return texUnit
->CurrentCubeMap
->NegY
[level
];
498 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
499 if (ctx
->Extensions
.ARB_texture_cube_map
)
500 return texUnit
->CurrentCubeMap
->PosZ
[level
];
503 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
504 if (ctx
->Extensions
.ARB_texture_cube_map
)
505 return texUnit
->CurrentCubeMap
->NegZ
[level
];
508 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
509 if (ctx
->Extensions
.ARB_texture_cube_map
)
510 return ctx
->Texture
.ProxyCubeMap
->Image
[level
];
513 case GL_TEXTURE_RECTANGLE_NV
:
514 if (ctx
->Extensions
.NV_texture_rectangle
) {
516 return texUnit
->CurrentRect
->Image
[level
];
521 case GL_PROXY_TEXTURE_RECTANGLE_NV
:
522 if (ctx
->Extensions
.NV_texture_rectangle
) {
524 return ctx
->Texture
.ProxyRect
->Image
[level
];
530 _mesa_problem(ctx
, "bad target in _mesa_select_tex_image()");
537 #if 000 /* not used anymore */
539 * glTexImage[123]D can accept a NULL image pointer. In this case we
540 * create a texture image with unspecified image contents per the OpenGL
544 make_null_texture(GLint width
, GLint height
, GLint depth
, GLenum format
)
546 const GLint components
= _mesa_components_in_format(format
);
547 const GLint numPixels
= width
* height
* depth
;
548 GLubyte
*data
= (GLubyte
*) MALLOC(numPixels
* components
* sizeof(GLubyte
));
552 * Let's see if anyone finds this. If glTexImage2D() is called with
553 * a NULL image pointer then load the texture image with something
554 * interesting instead of leaving it indeterminate.
557 static const char message
[8][32] = {
561 " X X XXXX XXX XXXXX ",
564 " X X XXXXX XXX X X ",
568 GLubyte
*imgPtr
= data
;
570 for (h
= 0; h
< depth
; h
++) {
571 for (i
= 0; i
< height
; i
++) {
572 GLint srcRow
= 7 - (i
% 8);
573 for (j
= 0; j
< width
; j
++) {
574 GLint srcCol
= j
% 32;
575 GLubyte texel
= (message
[srcRow
][srcCol
]=='X') ? 255 : 70;
576 for (k
= 0; k
< components
; k
++) {
592 * Reset the fields of a gl_texture_image struct to zero.
593 * This is called when a proxy texture test fails, we set all the
594 * image members (except DriverData) to zero.
595 * It's also used in glTexImage[123]D as a safeguard to be sure all
596 * required fields get initialized properly by the Driver.TexImage[123]D
600 clear_teximage_fields(struct gl_texture_image
*img
)
616 img
->TexFormat
= &_mesa_null_texformat
;
617 img
->FetchTexel
= NULL
;
618 img
->IsCompressed
= 0;
619 img
->CompressedSize
= 0;
624 * Initialize basic fields of the gl_texture_image struct.
627 _mesa_init_teximage_fields(GLcontext
*ctx
, GLenum target
,
628 struct gl_texture_image
*img
,
629 GLsizei width
, GLsizei height
, GLsizei depth
,
630 GLint border
, GLenum internalFormat
)
633 img
->Format
= _mesa_base_tex_format( ctx
, internalFormat
);
634 ASSERT(img
->Format
> 0);
635 img
->IntFormat
= internalFormat
;
636 img
->Border
= border
;
638 img
->Height
= height
;
640 img
->WidthLog2
= logbase2(width
- 2 * border
);
641 if (height
== 1) /* 1-D texture */
644 img
->HeightLog2
= logbase2(height
- 2 * border
);
645 if (depth
== 1) /* 2-D texture */
648 img
->DepthLog2
= logbase2(depth
- 2 * border
);
649 img
->Width2
= 1 << img
->WidthLog2
;
650 img
->Height2
= 1 << img
->HeightLog2
;
651 img
->Depth2
= 1 << img
->DepthLog2
;
652 img
->MaxLog2
= MAX2(img
->WidthLog2
, img
->HeightLog2
);
653 img
->IsCompressed
= is_compressed_format(ctx
, internalFormat
);
654 /* Compute Width/Height/DepthScale for mipmap lod computation */
655 if (target
== GL_TEXTURE_RECTANGLE_NV
) {
656 /* scale = 1.0 since texture coords directly map to texels */
657 img
->WidthScale
= 1.0;
658 img
->HeightScale
= 1.0;
659 img
->DepthScale
= 1.0;
662 img
->WidthScale
= (GLfloat
) img
->Width
;
663 img
->HeightScale
= (GLfloat
) img
->Height
;
664 img
->DepthScale
= (GLfloat
) img
->Depth
;
671 * Test glTexImage[123]D() parameters for errors.
673 * dimensions - must be 1 or 2 or 3
674 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
677 texture_error_check( GLcontext
*ctx
, GLenum target
,
678 GLint level
, GLint internalFormat
,
679 GLenum format
, GLenum type
,
681 GLint width
, GLint height
,
682 GLint depth
, GLint border
)
686 GLint maxLevels
= 0, maxTextureSize
;
688 if (dimensions
== 1) {
689 if (target
== GL_PROXY_TEXTURE_1D
) {
692 else if (target
== GL_TEXTURE_1D
) {
696 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
699 maxLevels
= ctx
->Const
.MaxTextureLevels
;
701 else if (dimensions
== 2) {
702 if (target
== GL_PROXY_TEXTURE_2D
) {
704 maxLevels
= ctx
->Const
.MaxTextureLevels
;
706 else if (target
== GL_TEXTURE_2D
) {
708 maxLevels
= ctx
->Const
.MaxTextureLevels
;
710 else if (target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
) {
711 if (!ctx
->Extensions
.ARB_texture_cube_map
) {
712 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
716 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
718 else if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
719 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
720 if (!ctx
->Extensions
.ARB_texture_cube_map
) {
721 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
725 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
727 else if (target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) {
728 if (!ctx
->Extensions
.NV_texture_rectangle
) {
729 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
735 else if (target
== GL_TEXTURE_RECTANGLE_NV
) {
736 if (!ctx
->Extensions
.NV_texture_rectangle
) {
737 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
744 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
748 else if (dimensions
== 3) {
749 if (target
== GL_PROXY_TEXTURE_3D
) {
752 else if (target
== GL_TEXTURE_3D
) {
756 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
759 maxLevels
= ctx
->Const
.Max3DTextureLevels
;
762 _mesa_problem( ctx
, "bad dims in texture_error_check" );
766 ASSERT(maxLevels
> 0);
767 maxTextureSize
= 1 << (maxLevels
- 1);
770 if (border
!= 0 && border
!= 1) {
773 sprintf(message
, "glTexImage%dD(border=%d)", dimensions
, border
);
774 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
778 if ((target
== GL_TEXTURE_RECTANGLE_NV
||
779 target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) && border
!= 0) {
784 if (target
== GL_TEXTURE_RECTANGLE_NV
||
785 target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) {
786 if (width
< 1 || width
> ctx
->Const
.MaxTextureRectSize
) {
789 sprintf(message
, "glTexImage%dD(width=%d)", dimensions
, width
);
790 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
795 else if (width
< 2 * border
|| width
> 2 + maxTextureSize
796 || logbase2( width
- 2 * border
) < 0) {
799 sprintf(message
, "glTexImage%dD(width=%d)", dimensions
, width
);
800 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
806 if (target
== GL_TEXTURE_RECTANGLE_NV
||
807 target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) {
808 if (height
< 1 || height
> ctx
->Const
.MaxTextureRectSize
) {
811 sprintf(message
, "glTexImage%dD(height=%d)", dimensions
, height
);
812 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
817 else if (dimensions
>= 2) {
818 if (height
< 2 * border
|| height
> 2 + maxTextureSize
819 || logbase2( height
- 2 * border
) < 0) {
822 sprintf(message
, "glTexImage%dD(height=%d)", dimensions
, height
);
823 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
829 /* For cube map, width must equal height */
830 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
831 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
832 if (width
!= height
) {
834 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
841 if (dimensions
>= 3) {
842 if (depth
< 2 * border
|| depth
> 2 + maxTextureSize
843 || logbase2( depth
- 2 * border
) < 0) {
846 sprintf(message
, "glTexImage3D(depth=%d)", depth
);
847 _mesa_error( ctx
, GL_INVALID_VALUE
, message
);
854 if (target
== GL_TEXTURE_RECTANGLE_NV
||
855 target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) {
859 sprintf(message
, "glTexImage2D(level=%d)", level
);
860 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
865 else if (level
< 0 || level
>= maxLevels
) {
868 sprintf(message
, "glTexImage%dD(level=%d)", dimensions
, level
);
869 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
874 /* For cube map, width must equal height */
875 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
876 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
877 if (width
!= height
) {
878 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
883 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
887 sprintf(message
, "glTexImage%dD(internalFormat=0x%x)", dimensions
,
889 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
896 if (!is_compressed_format( ctx
, internalFormat
) &&
897 !_mesa_is_legal_format_and_type( format
, type
)) {
898 /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
899 * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
903 sprintf(message
, "glTexImage%dD(format or type)", dimensions
);
904 _mesa_error(ctx
, GL_INVALID_OPERATION
, message
);
909 /* if we get here, the parameters are OK */
916 * Test glTexSubImage[123]D() parameters for errors.
918 * dimensions - must be 1 or 2 or 3
919 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
922 subtexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
923 GLenum target
, GLint level
,
924 GLint xoffset
, GLint yoffset
, GLint zoffset
,
925 GLint width
, GLint height
, GLint depth
,
926 GLenum format
, GLenum type
)
928 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
929 struct gl_texture_image
*destTex
;
931 GLboolean compressed
;
933 if (dimensions
== 1) {
934 if (target
!= GL_TEXTURE_1D
) {
935 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(target)" );
938 maxLevels
= ctx
->Const
.MaxTextureLevels
;
940 else if (dimensions
== 2) {
941 if (ctx
->Extensions
.ARB_texture_cube_map
) {
942 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
943 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
944 target
!= GL_TEXTURE_2D
) {
945 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
949 else if (target
!= GL_TEXTURE_2D
) {
950 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
953 if (target
== GL_PROXY_TEXTURE_2D
&& target
== GL_TEXTURE_2D
)
954 maxLevels
= ctx
->Const
.MaxTextureLevels
;
956 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
958 else if (dimensions
== 3) {
959 if (target
!= GL_TEXTURE_3D
) {
960 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3D(target)" );
963 maxLevels
= ctx
->Const
.Max3DTextureLevels
;
966 _mesa_problem( ctx
, "bad dims in texture_error_check" );
970 ASSERT(maxLevels
> 0);
972 if (level
< 0 || level
>= maxLevels
) {
974 sprintf(message
, "glTexSubImage2D(level=%d)", level
);
975 _mesa_error(ctx
, GL_INVALID_ENUM
, message
);
981 sprintf(message
, "glTexSubImage%dD(width=%d)", dimensions
, width
);
982 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
985 if (height
< 0 && dimensions
> 1) {
987 sprintf(message
, "glTexSubImage%dD(height=%d)", dimensions
, height
);
988 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
991 if (depth
< 0 && dimensions
> 2) {
993 sprintf(message
, "glTexSubImage%dD(depth=%d)", dimensions
, depth
);
994 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
998 destTex
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1001 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glTexSubImage2D");
1005 if (xoffset
< -((GLint
)destTex
->Border
)) {
1006 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset)");
1009 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
1010 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset+width)");
1013 if (dimensions
> 1) {
1014 if (yoffset
< -((GLint
)destTex
->Border
)) {
1015 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset)");
1018 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
1019 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset+height)");
1023 if (dimensions
> 2) {
1024 if (zoffset
< -((GLint
)destTex
->Border
)) {
1025 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset)");
1028 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+ destTex
->Border
)) {
1029 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset+depth)");
1034 compressed
= is_compressed_format(ctx
, destTex
->IntFormat
);
1036 if (!compressed
&& !_mesa_is_legal_format_and_type(format
, type
)) {
1038 sprintf(message
, "glTexSubImage%dD(format or type)", dimensions
);
1039 _mesa_error(ctx
, GL_INVALID_ENUM
, message
);
1044 if (xoffset
!= -((GLint
)destTex
->Border
)) {
1045 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1046 "glTexSubImage1/2/3D(xoffset != -border");
1049 if (dimensions
> 1 && yoffset
!= -((GLint
)destTex
->Border
)) {
1050 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1051 "glTexSubImage2/3D(yoffset != -border");
1054 if (dimensions
> 2 && zoffset
!= -((GLint
)destTex
->Border
)) {
1055 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1056 "glTexSubImage3D(zoffset != -border");
1066 * Test glCopyTexImage[12]D() parameters for errors.
1067 * Input: dimensions - must be 1 or 2 or 3
1068 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
1071 copytexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
1072 GLenum target
, GLint level
, GLint internalFormat
,
1073 GLint width
, GLint height
, GLint border
)
1076 GLint maxLevels
= 0, maxTextureSize
;
1078 if (dimensions
== 1) {
1079 if (target
!= GL_TEXTURE_1D
) {
1080 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
1083 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1085 else if (dimensions
== 2) {
1086 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1087 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
1088 if (!ctx
->Extensions
.ARB_texture_cube_map
) {
1089 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1093 else if (target
== GL_TEXTURE_RECTANGLE_NV
) {
1094 if (!ctx
->Extensions
.NV_texture_rectangle
) {
1095 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1099 else if (target
!= GL_TEXTURE_2D
) {
1100 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1103 if (target
== GL_TEXTURE_2D
)
1104 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1105 else if (target
== GL_TEXTURE_RECTANGLE_NV
)
1108 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
1111 ASSERT(maxLevels
> 0);
1112 maxTextureSize
= 1 << (maxLevels
- 1);
1115 if (border
!= 0 && border
!= 1) {
1117 sprintf(message
, "glCopyTexImage%dD(border)", dimensions
);
1118 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1123 if (width
< 2 * border
|| width
> 2 + maxTextureSize
1124 || logbase2( width
- 2 * border
) < 0) {
1126 sprintf(message
, "glCopyTexImage%dD(width=%d)", dimensions
, width
);
1127 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1132 if (dimensions
>= 2) {
1133 if (height
< 2 * border
|| height
> 2 + maxTextureSize
1134 || logbase2( height
- 2 * border
) < 0) {
1136 sprintf(message
, "glCopyTexImage%dD(height=%d)", dimensions
, height
);
1137 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1142 /* For cube map, width must equal height */
1143 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1144 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
1145 if (width
!= height
) {
1146 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(width != height)");
1152 if (level
< 0 || level
>= maxLevels
) {
1154 sprintf(message
, "glCopyTexImage%dD(level=%d)", dimensions
, level
);
1155 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1159 iformat
= _mesa_base_tex_format(ctx
, internalFormat
);
1162 sprintf(message
, "glCopyTexImage%dD(internalFormat)", dimensions
);
1163 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1167 /* if we get here, the parameters are OK */
1173 copytexsubimage_error_check( GLcontext
*ctx
, GLuint dimensions
,
1174 GLenum target
, GLint level
,
1175 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1176 GLsizei width
, GLsizei height
)
1178 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1179 struct gl_texture_image
*teximage
;
1180 GLint maxLevels
= 0;
1181 GLboolean compressed
;
1183 if (dimensions
== 1) {
1184 if (target
!= GL_TEXTURE_1D
) {
1185 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
1188 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1190 else if (dimensions
== 2) {
1191 if (ctx
->Extensions
.ARB_texture_cube_map
) {
1192 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1193 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1194 target
!= GL_TEXTURE_2D
) {
1195 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1199 else if (target
!= GL_TEXTURE_2D
) {
1200 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1203 if (target
== GL_PROXY_TEXTURE_2D
&& target
== GL_TEXTURE_2D
)
1204 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1206 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
1208 else if (dimensions
== 3) {
1209 if (target
!= GL_TEXTURE_3D
) {
1210 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3D(target)" );
1213 maxLevels
= ctx
->Const
.Max3DTextureLevels
;
1216 ASSERT(maxLevels
> 0);
1218 if (level
< 0 || level
>= maxLevels
) {
1220 sprintf(message
, "glCopyTexSubImage%dD(level=%d)", dimensions
, level
);
1221 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1227 sprintf(message
, "glCopyTexSubImage%dD(width=%d)", dimensions
, width
);
1228 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1231 if (dimensions
> 1 && height
< 0) {
1233 sprintf(message
, "glCopyTexSubImage%dD(height=%d)", dimensions
, height
);
1234 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1238 teximage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1241 sprintf(message
, "glCopyTexSubImage%dD(undefined texture)", dimensions
);
1242 _mesa_error(ctx
, GL_INVALID_OPERATION
, message
);
1246 if (xoffset
< -((GLint
)teximage
->Border
)) {
1248 sprintf(message
, "glCopyTexSubImage%dD(xoffset=%d)", dimensions
, xoffset
);
1249 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1252 if (xoffset
+ width
> (GLint
) (teximage
->Width
+ teximage
->Border
)) {
1254 sprintf(message
, "glCopyTexSubImage%dD(xoffset+width)", dimensions
);
1255 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1258 if (dimensions
> 1) {
1259 if (yoffset
< -((GLint
)teximage
->Border
)) {
1261 sprintf(message
, "glCopyTexSubImage%dD(yoffset=%d)", dimensions
, yoffset
);
1262 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1265 /* NOTE: we're adding the border here, not subtracting! */
1266 if (yoffset
+ height
> (GLint
) (teximage
->Height
+ teximage
->Border
)) {
1268 sprintf(message
, "glCopyTexSubImage%dD(yoffset+height)", dimensions
);
1269 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1274 if (dimensions
> 2) {
1275 if (zoffset
< -((GLint
)teximage
->Border
)) {
1277 sprintf(message
, "glCopyTexSubImage%dD(zoffset)", dimensions
);
1278 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1281 if (zoffset
> (GLint
) (teximage
->Depth
+ teximage
->Border
)) {
1283 sprintf(message
, "glCopyTexSubImage%dD(zoffset+depth)", dimensions
);
1284 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
1289 compressed
= is_compressed_format(ctx
, teximage
->IntFormat
);
1291 if (xoffset
!= -((GLint
)teximage
->Border
)) {
1292 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1293 "glCopyTexSubImage1/2/3D(xoffset != -border");
1296 if (dimensions
> 1 && yoffset
!= -((GLint
)teximage
->Border
)) {
1297 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1298 "glCopyTexSubImage2/3D(yoffset != -border");
1301 if (dimensions
> 2 && zoffset
!= -((GLint
)teximage
->Border
)) {
1302 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1303 "glCopyTexSubImage3D(zoffset != -border");
1308 /* if we get here, the parameters are OK */
1315 _mesa_GetTexImage( GLenum target
, GLint level
, GLenum format
,
1316 GLenum type
, GLvoid
*pixels
)
1318 const struct gl_texture_unit
*texUnit
;
1319 const struct gl_texture_object
*texObj
;
1320 struct gl_texture_image
*texImage
;
1321 GLint maxLevels
= 0;
1322 GET_CURRENT_CONTEXT(ctx
);
1323 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1325 texUnit
= &(ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
]);
1326 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1327 if (!texObj
|| is_proxy_target(target
)) {
1328 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)");
1332 if (target
== GL_TEXTURE_1D
|| target
== GL_TEXTURE_2D
) {
1333 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1335 else if (target
== GL_TEXTURE_3D
) {
1336 maxLevels
= ctx
->Const
.Max3DTextureLevels
;
1338 else if (target
== GL_TEXTURE_RECTANGLE_NV
) {
1342 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
1345 ASSERT(maxLevels
> 0);
1347 if (level
< 0 || level
>= maxLevels
) {
1348 _mesa_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
1352 if (_mesa_sizeof_packed_type(type
) <= 0) {
1353 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
1357 if (_mesa_components_in_format(format
) <= 0 ||
1358 format
== GL_STENCIL_INDEX
) {
1359 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
1363 if (!ctx
->Extensions
.EXT_paletted_texture
&& is_index_format(format
)) {
1364 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1367 if (!ctx
->Extensions
.SGIX_depth_texture
&& format
== GL_DEPTH_COMPONENT
) {
1368 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1371 /* XXX what if format/type doesn't match texture format/type? */
1376 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1378 /* invalid mipmap level, not an error */
1382 if (!texImage
->Data
) {
1383 /* no image data, not an error */
1388 const GLint width
= texImage
->Width
;
1389 const GLint height
= texImage
->Height
;
1390 const GLint depth
= texImage
->Depth
;
1392 for (img
= 0; img
< depth
; img
++) {
1393 for (row
= 0; row
< height
; row
++) {
1394 /* compute destination address in client memory */
1395 GLvoid
*dest
= _mesa_image_address( &ctx
->Unpack
, pixels
,
1396 width
, height
, format
, type
,
1400 if (format
== GL_COLOR_INDEX
) {
1401 GLuint indexRow
[MAX_WIDTH
];
1403 for (col
= 0; col
< width
; col
++) {
1404 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1405 (GLvoid
*) &indexRow
[col
]);
1407 _mesa_pack_index_span(ctx
, width
, type
, dest
,
1408 indexRow
, &ctx
->Pack
,
1409 0 /* no image transfer */);
1411 else if (format
== GL_DEPTH_COMPONENT
) {
1412 GLfloat depthRow
[MAX_WIDTH
];
1414 for (col
= 0; col
< width
; col
++) {
1415 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1416 (GLvoid
*) &depthRow
[col
]);
1418 _mesa_pack_depth_span(ctx
, width
, dest
, type
,
1419 depthRow
, &ctx
->Pack
);
1422 /* general case: convert row to RGBA format */
1423 GLchan rgba
[MAX_WIDTH
][4];
1425 for (col
= 0; col
< width
; col
++) {
1426 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1427 (GLvoid
*) rgba
[col
]);
1429 _mesa_pack_rgba_span(ctx
, width
, (const GLchan (*)[4])rgba
,
1430 format
, type
, dest
, &ctx
->Pack
,
1431 0 /* no image transfer */);
1441 * Called from the API. Note that width includes the border.
1444 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
1445 GLsizei width
, GLint border
, GLenum format
,
1446 GLenum type
, const GLvoid
*pixels
)
1448 GLsizei postConvWidth
= width
;
1449 GET_CURRENT_CONTEXT(ctx
);
1450 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1452 if (is_color_format(internalFormat
)) {
1453 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1456 if (target
== GL_TEXTURE_1D
) {
1457 struct gl_texture_unit
*texUnit
;
1458 struct gl_texture_object
*texObj
;
1459 struct gl_texture_image
*texImage
;
1461 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1462 format
, type
, 1, postConvWidth
, 1, 1, border
)) {
1463 return; /* error was recorded */
1466 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1467 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1468 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1471 texImage
= _mesa_alloc_texture_image();
1472 texObj
->Image
[level
] = texImage
;
1474 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
1478 else if (texImage
->Data
) {
1479 /* free the old texture data */
1480 MESA_PBUFFER_FREE(texImage
->Data
);
1481 texImage
->Data
= NULL
;
1483 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1484 _mesa_init_teximage_fields(ctx
, target
, texImage
,
1485 postConvWidth
, 1, 1,
1486 border
, internalFormat
);
1488 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1489 _mesa_update_state(ctx
);
1491 ASSERT(ctx
->Driver
.TexImage1D
);
1493 #if 0 /* don't make default teximage anymore */
1495 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1496 width
, border
, format
, type
, pixels
,
1497 &ctx
->Unpack
, texObj
, texImage
);
1500 GLubyte
*dummy
= make_null_texture(width
, 1, 1, format
);
1502 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1504 format
, GL_UNSIGNED_BYTE
, dummy
,
1505 &_mesa_native_packing
, texObj
, texImage
);
1510 /* <pixels> may be null! */
1511 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1512 width
, border
, format
, type
, pixels
,
1513 &ctx
->Unpack
, texObj
, texImage
);
1516 ASSERT(texImage
->TexFormat
);
1517 if (!texImage
->FetchTexel
) {
1518 /* If driver didn't explicitly set this, use the default */
1519 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel1D
;
1521 ASSERT(texImage
->FetchTexel
);
1523 if (texImage
->IsCompressed
) {
1524 ASSERT(texImage
->CompressedSize
> 0);
1528 texObj
->Complete
= GL_FALSE
;
1529 ctx
->NewState
|= _NEW_TEXTURE
;
1531 else if (target
== GL_PROXY_TEXTURE_1D
) {
1532 /* Proxy texture: check for errors and update proxy state */
1533 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1535 postConvWidth
, 1, 1, border
);
1537 struct gl_texture_unit
*texUnit
;
1538 struct gl_texture_image
*texImage
;
1539 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1540 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1541 _mesa_init_teximage_fields(ctx
, target
, texImage
,
1542 postConvWidth
, 1, 1,
1543 border
, internalFormat
);
1544 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1545 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1546 internalFormat
, format
, type
,
1547 postConvWidth
, 1, 1, border
);
1550 /* if error, clear all proxy texture image parameters */
1551 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1552 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
1557 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1564 _mesa_TexImage2D( GLenum target
, GLint level
, GLint internalFormat
,
1565 GLsizei width
, GLsizei height
, GLint border
,
1566 GLenum format
, GLenum type
,
1567 const GLvoid
*pixels
)
1569 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1570 GET_CURRENT_CONTEXT(ctx
);
1571 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1573 if (is_color_format(internalFormat
)) {
1574 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1578 if (target
== GL_TEXTURE_2D
||
1579 (ctx
->Extensions
.ARB_texture_cube_map
&&
1580 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1581 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) ||
1582 (ctx
->Extensions
.NV_texture_rectangle
&&
1583 target
== GL_TEXTURE_RECTANGLE_NV
)) {
1584 /* non-proxy target */
1585 struct gl_texture_unit
*texUnit
;
1586 struct gl_texture_object
*texObj
;
1587 struct gl_texture_image
*texImage
;
1589 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1590 format
, type
, 2, postConvWidth
, postConvHeight
,
1592 return; /* error was recorded */
1595 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1596 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1597 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1600 texImage
= _mesa_alloc_texture_image();
1601 _mesa_set_tex_image(texObj
, target
, level
, texImage
);
1603 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1607 else if (texImage
->Data
) {
1608 /* free the old texture data */
1609 MESA_PBUFFER_FREE(texImage
->Data
);
1610 texImage
->Data
= NULL
;
1612 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1613 _mesa_init_teximage_fields(ctx
, target
, texImage
,
1614 postConvWidth
, postConvHeight
, 1,
1615 border
, internalFormat
);
1617 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1618 _mesa_update_state(ctx
);
1620 ASSERT(ctx
->Driver
.TexImage2D
);
1622 #if 0 /* don't make default teximage anymore */
1624 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1625 width
, height
, border
, format
, type
, pixels
,
1626 &ctx
->Unpack
, texObj
, texImage
);
1629 GLubyte
*dummy
= make_null_texture(width
, height
, 1, format
);
1631 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1632 width
, height
, border
,
1633 format
, GL_UNSIGNED_BYTE
, dummy
,
1634 &_mesa_native_packing
, texObj
, texImage
);
1639 /* <pixels> may be null! */
1640 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1641 width
, height
, border
, format
, type
, pixels
,
1642 &ctx
->Unpack
, texObj
, texImage
);
1645 ASSERT(texImage
->TexFormat
);
1646 if (!texImage
->FetchTexel
) {
1647 /* If driver didn't explicitly set this, use the default */
1648 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel2D
;
1650 ASSERT(texImage
->FetchTexel
);
1652 if (texImage
->IsCompressed
) {
1653 ASSERT(texImage
->CompressedSize
> 0);
1657 texObj
->Complete
= GL_FALSE
;
1658 ctx
->NewState
|= _NEW_TEXTURE
;
1660 else if (target
== GL_PROXY_TEXTURE_2D
||
1661 (target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
&&
1662 ctx
->Extensions
.ARB_texture_cube_map
) ||
1663 (target
== GL_PROXY_TEXTURE_RECTANGLE_NV
&&
1664 ctx
->Extensions
.NV_texture_rectangle
)) {
1665 /* Proxy texture: check for errors and update proxy state */
1666 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1668 postConvWidth
, postConvHeight
, 1, border
);
1670 struct gl_texture_unit
*texUnit
;
1671 struct gl_texture_image
*texImage
;
1672 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1673 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1674 _mesa_init_teximage_fields(ctx
, target
, texImage
,
1675 postConvWidth
, postConvHeight
, 1,
1676 border
, internalFormat
);
1677 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1678 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1679 internalFormat
, format
, type
,
1680 postConvWidth
, postConvHeight
, 1, border
);
1683 /* if error, clear all proxy texture image parameters */
1684 const GLint maxLevels
= (target
== GL_PROXY_TEXTURE_2D
) ?
1685 ctx
->Const
.MaxTextureLevels
: ctx
->Const
.MaxCubeTextureLevels
;
1686 if (level
>= 0 && level
< maxLevels
) {
1687 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
1692 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1699 * Called by the API or display list executor.
1700 * Note that width and height include the border.
1703 _mesa_TexImage3D( GLenum target
, GLint level
, GLint internalFormat
,
1704 GLsizei width
, GLsizei height
, GLsizei depth
,
1705 GLint border
, GLenum format
, GLenum type
,
1706 const GLvoid
*pixels
)
1708 GET_CURRENT_CONTEXT(ctx
);
1709 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1711 if (target
== GL_TEXTURE_3D
) {
1712 struct gl_texture_unit
*texUnit
;
1713 struct gl_texture_object
*texObj
;
1714 struct gl_texture_image
*texImage
;
1716 if (texture_error_check(ctx
, target
, level
, (GLint
) internalFormat
,
1717 format
, type
, 3, width
, height
, depth
, border
)) {
1718 return; /* error was recorded */
1721 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1722 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1723 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1726 texImage
= _mesa_alloc_texture_image();
1727 texObj
->Image
[level
] = texImage
;
1729 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
1733 else if (texImage
->Data
) {
1734 MESA_PBUFFER_FREE(texImage
->Data
);
1735 texImage
->Data
= NULL
;
1737 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1738 _mesa_init_teximage_fields(ctx
, target
, texImage
,
1739 width
, height
, depth
,
1740 border
, internalFormat
);
1742 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1743 _mesa_update_state(ctx
);
1745 ASSERT(ctx
->Driver
.TexImage3D
);
1747 #if 0 /* don't make default teximage anymore */
1749 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, (GLint
) internalFormat
,
1750 width
, height
, depth
, border
,
1751 format
, type
, pixels
,
1752 &ctx
->Unpack
, texObj
, texImage
);
1755 GLubyte
*dummy
= make_null_texture(width
, height
, depth
, format
);
1757 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
,
1758 (GLint
) internalFormat
,
1759 width
, height
, depth
, border
,
1760 format
, GL_UNSIGNED_BYTE
, dummy
,
1761 &_mesa_native_packing
, texObj
, texImage
);
1766 /* <pixels> may be null! */
1767 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, internalFormat
,
1768 width
, height
, depth
, border
, format
, type
,
1769 pixels
, &ctx
->Unpack
, texObj
, texImage
);
1772 ASSERT(texImage
->TexFormat
);
1773 if (!texImage
->FetchTexel
) {
1774 /* If driver didn't explicitly set this, use the default */
1775 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel3D
;
1777 ASSERT(texImage
->FetchTexel
);
1779 if (texImage
->IsCompressed
) {
1780 ASSERT(texImage
->CompressedSize
> 0);
1784 texObj
->Complete
= GL_FALSE
;
1785 ctx
->NewState
|= _NEW_TEXTURE
;
1787 else if (target
== GL_PROXY_TEXTURE_3D
) {
1788 /* Proxy texture: check for errors and update proxy state */
1789 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1790 format
, type
, 3, width
, height
, depth
, border
);
1792 struct gl_texture_unit
*texUnit
;
1793 struct gl_texture_image
*texImage
;
1794 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1795 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1796 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
, 1,
1797 border
, internalFormat
);
1798 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1799 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1800 internalFormat
, format
, type
,
1801 width
, height
, depth
, border
);
1804 /* if error, clear all proxy texture image parameters */
1805 if (level
>= 0 && level
< ctx
->Const
.Max3DTextureLevels
) {
1806 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
1811 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1818 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
1819 GLsizei width
, GLsizei height
, GLsizei depth
,
1820 GLint border
, GLenum format
, GLenum type
,
1821 const GLvoid
*pixels
)
1823 _mesa_TexImage3D(target
, level
, internalFormat
, width
, height
,
1824 depth
, border
, format
, type
, pixels
);
1830 _mesa_TexSubImage1D( GLenum target
, GLint level
,
1831 GLint xoffset
, GLsizei width
,
1832 GLenum format
, GLenum type
,
1833 const GLvoid
*pixels
)
1835 GLsizei postConvWidth
= width
;
1836 struct gl_texture_unit
*texUnit
;
1837 struct gl_texture_object
*texObj
;
1838 struct gl_texture_image
*texImage
;
1839 GET_CURRENT_CONTEXT(ctx
);
1840 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1842 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1843 _mesa_update_state(ctx
);
1845 /* XXX should test internal format */
1846 if (is_color_format(format
)) {
1847 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1850 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
1851 postConvWidth
, 1, 1, format
, type
)) {
1852 return; /* error was detected */
1855 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1856 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1857 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1860 if (width
== 0 || !pixels
)
1861 return; /* no-op, not an error */
1863 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1864 xoffset
+= texImage
->Border
;
1866 ASSERT(ctx
->Driver
.TexSubImage1D
);
1867 (*ctx
->Driver
.TexSubImage1D
)(ctx
, target
, level
, xoffset
, width
,
1868 format
, type
, pixels
, &ctx
->Unpack
,
1870 ctx
->NewState
|= _NEW_TEXTURE
;
1875 _mesa_TexSubImage2D( GLenum target
, GLint level
,
1876 GLint xoffset
, GLint yoffset
,
1877 GLsizei width
, GLsizei height
,
1878 GLenum format
, GLenum type
,
1879 const GLvoid
*pixels
)
1881 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1882 struct gl_texture_unit
*texUnit
;
1883 struct gl_texture_object
*texObj
;
1884 struct gl_texture_image
*texImage
;
1885 GET_CURRENT_CONTEXT(ctx
);
1886 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1888 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1889 _mesa_update_state(ctx
);
1891 /* XXX should test internal format */
1892 if (is_color_format(format
)) {
1893 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1897 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1898 postConvWidth
, postConvHeight
, 1, format
, type
)) {
1899 return; /* error was detected */
1902 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1903 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1904 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1907 if (width
== 0 || height
== 0 || !pixels
)
1908 return; /* no-op, not an error */
1910 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1911 xoffset
+= texImage
->Border
;
1912 yoffset
+= texImage
->Border
;
1914 ASSERT(ctx
->Driver
.TexSubImage2D
);
1915 (*ctx
->Driver
.TexSubImage2D
)(ctx
, target
, level
, xoffset
, yoffset
,
1916 width
, height
, format
, type
, pixels
,
1917 &ctx
->Unpack
, texObj
, texImage
);
1918 ctx
->NewState
|= _NEW_TEXTURE
;
1924 _mesa_TexSubImage3D( GLenum target
, GLint level
,
1925 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1926 GLsizei width
, GLsizei height
, GLsizei depth
,
1927 GLenum format
, GLenum type
,
1928 const GLvoid
*pixels
)
1930 struct gl_texture_unit
*texUnit
;
1931 struct gl_texture_object
*texObj
;
1932 struct gl_texture_image
*texImage
;
1933 GET_CURRENT_CONTEXT(ctx
);
1934 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1936 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1937 _mesa_update_state(ctx
);
1939 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
1940 width
, height
, depth
, format
, type
)) {
1941 return; /* error was detected */
1944 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1945 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1946 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1949 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
1950 return; /* no-op, not an error */
1952 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1953 xoffset
+= texImage
->Border
;
1954 yoffset
+= texImage
->Border
;
1955 zoffset
+= texImage
->Border
;
1957 ASSERT(ctx
->Driver
.TexSubImage3D
);
1958 (*ctx
->Driver
.TexSubImage3D
)(ctx
, target
, level
,
1959 xoffset
, yoffset
, zoffset
,
1960 width
, height
, depth
,
1961 format
, type
, pixels
,
1962 &ctx
->Unpack
, texObj
, texImage
);
1963 ctx
->NewState
|= _NEW_TEXTURE
;
1969 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
1970 GLenum internalFormat
,
1972 GLsizei width
, GLint border
)
1974 struct gl_texture_unit
*texUnit
;
1975 struct gl_texture_object
*texObj
;
1976 struct gl_texture_image
*texImage
;
1977 GLsizei postConvWidth
= width
;
1978 GET_CURRENT_CONTEXT(ctx
);
1979 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1981 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1982 _mesa_update_state(ctx
);
1984 if (is_color_format(internalFormat
)) {
1985 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1988 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
1989 postConvWidth
, 1, border
))
1992 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1993 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1994 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1996 texImage
= _mesa_alloc_texture_image();
1997 _mesa_set_tex_image(texObj
, target
, level
, texImage
);
1999 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D");
2003 else if (texImage
->Data
) {
2004 /* free the old texture data */
2005 MESA_PBUFFER_FREE(texImage
->Data
);
2006 texImage
->Data
= NULL
;
2009 clear_teximage_fields(texImage
); /* not really needed, but helpful */
2010 _mesa_init_teximage_fields(ctx
, target
, texImage
, postConvWidth
, 1, 1,
2011 border
, internalFormat
);
2014 ASSERT(ctx
->Driver
.CopyTexImage1D
);
2015 (*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
, internalFormat
,
2016 x
, y
, width
, border
);
2018 ASSERT(texImage
->TexFormat
);
2019 if (!texImage
->FetchTexel
) {
2020 /* If driver didn't explicitly set this, use the default */
2021 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel1D
;
2023 ASSERT(texImage
->FetchTexel
);
2026 texObj
->Complete
= GL_FALSE
;
2027 ctx
->NewState
|= _NEW_TEXTURE
;
2033 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
2034 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
2037 struct gl_texture_unit
*texUnit
;
2038 struct gl_texture_object
*texObj
;
2039 struct gl_texture_image
*texImage
;
2040 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2041 GET_CURRENT_CONTEXT(ctx
);
2042 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2044 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2045 _mesa_update_state(ctx
);
2047 if (is_color_format(internalFormat
)) {
2048 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
2052 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
2053 postConvWidth
, postConvHeight
, border
))
2056 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2057 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2058 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2060 texImage
= _mesa_alloc_texture_image();
2061 _mesa_set_tex_image(texObj
, target
, level
, texImage
);
2063 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D");
2067 else if (texImage
->Data
) {
2068 /* free the old texture data */
2069 MESA_PBUFFER_FREE(texImage
->Data
);
2070 texImage
->Data
= NULL
;
2073 clear_teximage_fields(texImage
); /* not really needed, but helpful */
2074 _mesa_init_teximage_fields(ctx
, target
, texImage
,
2075 postConvWidth
, postConvHeight
, 1,
2076 border
, internalFormat
);
2078 ASSERT(ctx
->Driver
.CopyTexImage2D
);
2079 (*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
, internalFormat
,
2080 x
, y
, width
, height
, border
);
2082 ASSERT(texImage
->TexFormat
);
2083 if (!texImage
->FetchTexel
) {
2084 /* If driver didn't explicitly set this, use the default */
2085 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel2D
;
2087 ASSERT(texImage
->FetchTexel
);
2090 texObj
->Complete
= GL_FALSE
;
2091 ctx
->NewState
|= _NEW_TEXTURE
;
2097 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
2098 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
2100 struct gl_texture_unit
*texUnit
;
2101 struct gl_texture_object
*texObj
;
2102 struct gl_texture_image
*texImage
;
2103 GLsizei postConvWidth
= width
;
2104 GET_CURRENT_CONTEXT(ctx
);
2105 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2107 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2108 _mesa_update_state(ctx
);
2110 /* XXX should test internal format */
2111 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
2113 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
2114 xoffset
, 0, 0, postConvWidth
, 1))
2117 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2118 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2119 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2121 /* If we have a border, xoffset=-1 is legal. Bias by border width */
2122 xoffset
+= texImage
->Border
;
2124 ASSERT(ctx
->Driver
.CopyTexSubImage1D
);
2125 (*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
, xoffset
, x
, y
, width
);
2126 ctx
->NewState
|= _NEW_TEXTURE
;
2132 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
2133 GLint xoffset
, GLint yoffset
,
2134 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2136 struct gl_texture_unit
*texUnit
;
2137 struct gl_texture_object
*texObj
;
2138 struct gl_texture_image
*texImage
;
2139 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2140 GET_CURRENT_CONTEXT(ctx
);
2141 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2143 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2144 _mesa_update_state(ctx
);
2146 /* XXX should test internal format */
2147 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
2149 if (copytexsubimage_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2150 postConvWidth
, postConvHeight
))
2153 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2154 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2155 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2157 /* If we have a border, xoffset=-1 is legal. Bias by border width */
2158 xoffset
+= texImage
->Border
;
2159 yoffset
+= texImage
->Border
;
2161 ASSERT(ctx
->Driver
.CopyTexSubImage2D
);
2162 (*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
2163 xoffset
, yoffset
, x
, y
, width
, height
);
2164 ctx
->NewState
|= _NEW_TEXTURE
;
2170 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
2171 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2172 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2174 struct gl_texture_unit
*texUnit
;
2175 struct gl_texture_object
*texObj
;
2176 struct gl_texture_image
*texImage
;
2177 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2178 GET_CURRENT_CONTEXT(ctx
);
2179 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2181 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2182 _mesa_update_state(ctx
);
2184 /* XXX should test internal format */
2185 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
2187 if (copytexsubimage_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
,
2188 zoffset
, postConvWidth
, postConvHeight
))
2191 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2192 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2193 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2195 /* If we have a border, xoffset=-1 is legal. Bias by border width */
2196 xoffset
+= texImage
->Border
;
2197 yoffset
+= texImage
->Border
;
2198 zoffset
+= texImage
->Border
;
2200 ASSERT(ctx
->Driver
.CopyTexSubImage3D
);
2201 (*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
2202 xoffset
, yoffset
, zoffset
,
2203 x
, y
, width
, height
);
2204 ctx
->NewState
|= _NEW_TEXTURE
;
2210 _mesa_CompressedTexImage1DARB(GLenum target
, GLint level
,
2211 GLenum internalFormat
, GLsizei width
,
2212 GLint border
, GLsizei imageSize
,
2215 GET_CURRENT_CONTEXT(ctx
);
2216 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2218 switch (internalFormat
) {
2219 case GL_COMPRESSED_ALPHA_ARB
:
2220 case GL_COMPRESSED_LUMINANCE_ARB
:
2221 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2222 case GL_COMPRESSED_INTENSITY_ARB
:
2223 case GL_COMPRESSED_RGB_ARB
:
2224 case GL_COMPRESSED_RGBA_ARB
:
2225 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB");
2228 /* silence compiler warning */
2232 if (target
== GL_TEXTURE_1D
) {
2233 struct gl_texture_unit
*texUnit
;
2234 struct gl_texture_object
*texObj
;
2235 struct gl_texture_image
*texImage
;
2237 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2238 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
2239 return; /* error in texture image was detected */
2242 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2243 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2244 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2247 texImage
= _mesa_alloc_texture_image();
2248 texObj
->Image
[level
] = texImage
;
2250 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage1DARB");
2254 else if (texImage
->Data
) {
2255 MESA_PBUFFER_FREE(texImage
->Data
);
2256 texImage
->Data
= NULL
;
2259 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, 1, 1,
2260 border
, internalFormat
);
2262 if (ctx
->Extensions
.ARB_texture_compression
) {
2263 ASSERT(ctx
->Driver
.CompressedTexImage1D
);
2264 (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
,
2265 internalFormat
, width
, border
,
2268 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2272 texObj
->Complete
= GL_FALSE
;
2273 ctx
->NewState
|= _NEW_TEXTURE
;
2275 else if (target
== GL_PROXY_TEXTURE_1D
) {
2276 /* Proxy texture: check for errors and update proxy state */
2277 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2278 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
);
2280 struct gl_texture_unit
*texUnit
;
2281 struct gl_texture_image
*texImage
;
2282 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2283 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2284 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, 1, 1,
2285 border
, internalFormat
);
2286 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2287 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2288 internalFormat
, GL_NONE
, GL_NONE
,
2289 width
, 1, 1, border
);
2292 /* if error, clear all proxy texture image parameters */
2293 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2294 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
2299 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB(target)");
2306 _mesa_CompressedTexImage2DARB(GLenum target
, GLint level
,
2307 GLenum internalFormat
, GLsizei width
,
2308 GLsizei height
, GLint border
, GLsizei imageSize
,
2311 GET_CURRENT_CONTEXT(ctx
);
2312 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2314 switch (internalFormat
) {
2315 case GL_COMPRESSED_ALPHA_ARB
:
2316 case GL_COMPRESSED_LUMINANCE_ARB
:
2317 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2318 case GL_COMPRESSED_INTENSITY_ARB
:
2319 case GL_COMPRESSED_RGB_ARB
:
2320 case GL_COMPRESSED_RGBA_ARB
:
2321 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB");
2324 /* silence compiler warning */
2328 if (target
== GL_TEXTURE_2D
||
2329 (ctx
->Extensions
.ARB_texture_cube_map
&&
2330 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2331 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) ||
2332 (ctx
->Extensions
.NV_texture_rectangle
&&
2333 target
== GL_TEXTURE_RECTANGLE_NV
)) {
2334 struct gl_texture_unit
*texUnit
;
2335 struct gl_texture_object
*texObj
;
2336 struct gl_texture_image
*texImage
;
2338 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2339 GL_NONE
, GL_NONE
, 1, width
, height
, 1, border
)) {
2340 return; /* error in texture image was detected */
2343 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2344 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2345 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2348 texImage
= _mesa_alloc_texture_image();
2349 texObj
->Image
[level
] = texImage
;
2351 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
2355 else if (texImage
->Data
) {
2356 MESA_PBUFFER_FREE(texImage
->Data
);
2357 texImage
->Data
= NULL
;
2360 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
, 1,
2361 border
, internalFormat
);
2363 if (ctx
->Extensions
.ARB_texture_compression
) {
2364 ASSERT(ctx
->Driver
.CompressedTexImage2D
);
2365 (*ctx
->Driver
.CompressedTexImage2D
)(ctx
, target
, level
,
2366 internalFormat
, width
, height
,
2367 border
, imageSize
, data
,
2369 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2373 texObj
->Complete
= GL_FALSE
;
2374 ctx
->NewState
|= _NEW_TEXTURE
;
2376 else if (target
== GL_PROXY_TEXTURE_2D
) {
2377 /* Proxy texture: check for errors and update proxy state */
2378 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2379 GL_NONE
, GL_NONE
, 2, width
, height
, 1, border
);
2381 struct gl_texture_unit
*texUnit
;
2382 struct gl_texture_image
*texImage
;
2383 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2384 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2385 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
, 1,
2386 border
, internalFormat
);
2387 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2388 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2389 internalFormat
, GL_NONE
, GL_NONE
,
2390 width
, height
, 1, border
);
2393 /* if error, clear all proxy texture image parameters */
2394 const GLint maxLevels
= (target
== GL_PROXY_TEXTURE_2D
) ?
2395 ctx
->Const
.MaxTextureLevels
: ctx
->Const
.MaxCubeTextureLevels
;
2396 if (level
>= 0 && level
< maxLevels
) {
2397 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
2402 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB(target)");
2409 _mesa_CompressedTexImage3DARB(GLenum target
, GLint level
,
2410 GLenum internalFormat
, GLsizei width
,
2411 GLsizei height
, GLsizei depth
, GLint border
,
2412 GLsizei imageSize
, const GLvoid
*data
)
2414 GET_CURRENT_CONTEXT(ctx
);
2415 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2417 switch (internalFormat
) {
2418 case GL_COMPRESSED_ALPHA_ARB
:
2419 case GL_COMPRESSED_LUMINANCE_ARB
:
2420 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2421 case GL_COMPRESSED_INTENSITY_ARB
:
2422 case GL_COMPRESSED_RGB_ARB
:
2423 case GL_COMPRESSED_RGBA_ARB
:
2424 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB");
2427 /* silence compiler warning */
2431 if (target
== GL_TEXTURE_3D
) {
2432 struct gl_texture_unit
*texUnit
;
2433 struct gl_texture_object
*texObj
;
2434 struct gl_texture_image
*texImage
;
2436 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2437 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
)) {
2438 return; /* error in texture image was detected */
2441 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2442 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2443 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2446 texImage
= _mesa_alloc_texture_image();
2447 texObj
->Image
[level
] = texImage
;
2449 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage3DARB");
2453 else if (texImage
->Data
) {
2454 MESA_PBUFFER_FREE(texImage
->Data
);
2455 texImage
->Data
= NULL
;
2458 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
, depth
,
2459 border
, internalFormat
);
2461 if (ctx
->Extensions
.ARB_texture_compression
) {
2462 ASSERT(ctx
->Driver
.CompressedTexImage3D
);
2463 (*ctx
->Driver
.CompressedTexImage3D
)(ctx
, target
, level
,
2465 width
, height
, depth
,
2466 border
, imageSize
, data
,
2468 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2472 texObj
->Complete
= GL_FALSE
;
2473 ctx
->NewState
|= _NEW_TEXTURE
;
2475 else if (target
== GL_PROXY_TEXTURE_3D
) {
2476 /* Proxy texture: check for errors and update proxy state */
2477 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2478 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
);
2480 struct gl_texture_unit
*texUnit
;
2481 struct gl_texture_image
*texImage
;
2482 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2483 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2484 _mesa_init_teximage_fields(ctx
, target
, texImage
,
2485 width
, height
, depth
,
2486 border
, internalFormat
);
2487 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2488 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2489 internalFormat
, GL_NONE
, GL_NONE
,
2490 width
, height
, depth
, border
);
2493 /* if error, clear all proxy texture image parameters */
2494 if (level
>= 0 && level
< ctx
->Const
.Max3DTextureLevels
) {
2495 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
2500 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB(target)");
2507 _mesa_CompressedTexSubImage1DARB(GLenum target
, GLint level
, GLint xoffset
,
2508 GLsizei width
, GLenum format
,
2509 GLsizei imageSize
, const GLvoid
*data
)
2511 struct gl_texture_unit
*texUnit
;
2512 struct gl_texture_object
*texObj
;
2513 struct gl_texture_image
*texImage
;
2514 GET_CURRENT_CONTEXT(ctx
);
2515 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2517 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
2518 width
, 1, 1, format
, GL_NONE
)) {
2519 return; /* error was detected */
2522 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2523 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2524 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2527 if (width
== 0 || !data
)
2528 return; /* no-op, not an error */
2530 if (ctx
->Driver
.CompressedTexSubImage1D
) {
2531 (*ctx
->Driver
.CompressedTexSubImage1D
)(ctx
, target
, level
,
2533 format
, imageSize
, data
,
2536 ctx
->NewState
|= _NEW_TEXTURE
;
2541 _mesa_CompressedTexSubImage2DARB(GLenum target
, GLint level
, GLint xoffset
,
2542 GLint yoffset
, GLsizei width
, GLsizei height
,
2543 GLenum format
, GLsizei imageSize
,
2546 struct gl_texture_unit
*texUnit
;
2547 struct gl_texture_object
*texObj
;
2548 struct gl_texture_image
*texImage
;
2549 GET_CURRENT_CONTEXT(ctx
);
2550 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2552 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2553 width
, height
, 1, format
, GL_NONE
)) {
2554 return; /* error was detected */
2557 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2558 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2559 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2562 if (width
== 0 || height
== 0 || !data
)
2563 return; /* no-op, not an error */
2565 if (ctx
->Driver
.CompressedTexSubImage2D
) {
2566 (*ctx
->Driver
.CompressedTexSubImage2D
)(ctx
, target
, level
,
2567 xoffset
, yoffset
, width
, height
,
2568 format
, imageSize
, data
,
2571 ctx
->NewState
|= _NEW_TEXTURE
;
2576 _mesa_CompressedTexSubImage3DARB(GLenum target
, GLint level
, GLint xoffset
,
2577 GLint yoffset
, GLint zoffset
, GLsizei width
,
2578 GLsizei height
, GLsizei depth
, GLenum format
,
2579 GLsizei imageSize
, const GLvoid
*data
)
2581 struct gl_texture_unit
*texUnit
;
2582 struct gl_texture_object
*texObj
;
2583 struct gl_texture_image
*texImage
;
2584 GET_CURRENT_CONTEXT(ctx
);
2585 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2587 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2588 width
, height
, depth
, format
, GL_NONE
)) {
2589 return; /* error was detected */
2592 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2593 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2594 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2597 if (width
== 0 || height
== 0 || depth
== 0 || !data
)
2598 return; /* no-op, not an error */
2600 if (ctx
->Driver
.CompressedTexSubImage3D
) {
2601 (*ctx
->Driver
.CompressedTexSubImage3D
)(ctx
, target
, level
,
2602 xoffset
, yoffset
, zoffset
,
2603 width
, height
, depth
,
2604 format
, imageSize
, data
,
2607 ctx
->NewState
|= _NEW_TEXTURE
;
2612 _mesa_GetCompressedTexImageARB(GLenum target
, GLint level
, GLvoid
*img
)
2614 const struct gl_texture_unit
*texUnit
;
2615 const struct gl_texture_object
*texObj
;
2616 struct gl_texture_image
*texImage
;
2618 GET_CURRENT_CONTEXT(ctx
);
2619 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2621 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2622 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2624 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB");
2628 if (target
== GL_TEXTURE_1D
|| target
== GL_TEXTURE_2D
) {
2629 maxLevels
= ctx
->Const
.MaxTextureLevels
;
2631 else if (target
== GL_TEXTURE_3D
) {
2632 maxLevels
= ctx
->Const
.Max3DTextureLevels
;
2635 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
2638 ASSERT(maxLevels
> 0);
2640 if (level
< 0 || level
>= maxLevels
) {
2641 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
2645 if (is_proxy_target(target
)) {
2646 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB(target)");
2650 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2652 /* probably invalid mipmap level */
2653 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
2657 if (!texImage
->IsCompressed
) {
2658 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetCompressedTexImageARB");
2665 if (ctx
->Extensions
.ARB_texture_compression
) {
2666 ASSERT(ctx
->Driver
.GetCompressedTexImage
);
2667 (*ctx
->Driver
.GetCompressedTexImage
)(ctx
, target
, level
, img
, texObj
,