1 /* $Id: teximage.c,v 1.118 2002/10/02 17:25:05 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 "texcompress.h"
40 #include "texformat.h"
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(GLcontext
*ctx
, 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 _mesa_printf(ctx
, "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 _mesa_printf(ctx
, "%02x ", data
[0]);
98 _mesa_printf(ctx
, "%02x%02x ", data
[0], data
[1]);
100 _mesa_printf(ctx
, "%02x%02x%02x ", data
[0], data
[1], data
[2]);
102 _mesa_printf(ctx
, "%02x%02x%02x%02x ", data
[0], data
[1], data
[2], data
[3]);
103 data
+= (img
->RowStride
- img
->Width
) * c
;
105 _mesa_printf(ctx
, "\n");
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.
147 * This is the format which is used during texture application (i.e. the
148 * texture format and env mode determine the arithmetic used.
150 * Return -1 if invalid enum.
153 _mesa_base_tex_format( GLcontext
*ctx
, GLint format
)
156 * Ask the driver for the base format, if it doesn't
157 * know, it will return -1;
174 case GL_LUMINANCE_ALPHA
:
175 case GL_LUMINANCE4_ALPHA4
:
176 case GL_LUMINANCE6_ALPHA2
:
177 case GL_LUMINANCE8_ALPHA8
:
178 case GL_LUMINANCE12_ALPHA4
:
179 case GL_LUMINANCE12_ALPHA12
:
180 case GL_LUMINANCE16_ALPHA16
:
181 return GL_LUMINANCE_ALPHA
;
209 case GL_COLOR_INDEX1_EXT
:
210 case GL_COLOR_INDEX2_EXT
:
211 case GL_COLOR_INDEX4_EXT
:
212 case GL_COLOR_INDEX8_EXT
:
213 case GL_COLOR_INDEX12_EXT
:
214 case GL_COLOR_INDEX16_EXT
:
215 return GL_COLOR_INDEX
;
216 case GL_DEPTH_COMPONENT
:
217 case GL_DEPTH_COMPONENT16_SGIX
:
218 case GL_DEPTH_COMPONENT24_SGIX
:
219 case GL_DEPTH_COMPONENT32_SGIX
:
220 if (ctx
->Extensions
.SGIX_depth_texture
)
221 return GL_DEPTH_COMPONENT
;
225 /* GL_ARB_texture_compression */
226 case GL_COMPRESSED_ALPHA
:
227 if (ctx
->Extensions
.ARB_texture_compression
)
231 case GL_COMPRESSED_LUMINANCE
:
232 if (ctx
->Extensions
.ARB_texture_compression
)
236 case GL_COMPRESSED_LUMINANCE_ALPHA
:
237 if (ctx
->Extensions
.ARB_texture_compression
)
238 return GL_LUMINANCE_ALPHA
;
241 case GL_COMPRESSED_INTENSITY
:
242 if (ctx
->Extensions
.ARB_texture_compression
)
246 case GL_COMPRESSED_RGB
:
247 if (ctx
->Extensions
.ARB_texture_compression
)
251 case GL_COMPRESSED_RGBA
:
252 if (ctx
->Extensions
.ARB_texture_compression
)
256 case GL_COMPRESSED_RGB_FXT1_3DFX
:
257 if (ctx
->Extensions
.TDFX_texture_compression_FXT1
)
261 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
262 if (ctx
->Extensions
.TDFX_texture_compression_FXT1
)
268 if (ctx
->Extensions
.MESA_ycbcr_texture
)
269 return GL_YCBCR_MESA
;
274 return -1; /* error */
280 * Test if the given image format is a color/rgba format. That is,
281 * not color index, depth, stencil, etc.
284 is_color_format(GLenum format
)
299 case GL_LUMINANCE_ALPHA
:
300 case GL_LUMINANCE4_ALPHA4
:
301 case GL_LUMINANCE6_ALPHA2
:
302 case GL_LUMINANCE8_ALPHA8
:
303 case GL_LUMINANCE12_ALPHA4
:
304 case GL_LUMINANCE12_ALPHA12
:
305 case GL_LUMINANCE16_ALPHA16
:
330 case GL_YCBCR_MESA
: /* not considered to be RGB */
338 is_index_format(GLenum format
)
342 case GL_COLOR_INDEX1_EXT
:
343 case GL_COLOR_INDEX2_EXT
:
344 case GL_COLOR_INDEX4_EXT
:
345 case GL_COLOR_INDEX8_EXT
:
346 case GL_COLOR_INDEX12_EXT
:
347 case GL_COLOR_INDEX16_EXT
:
356 * Return GL_TRUE if internalFormat is a supported compressed format,
357 * return GL_FALSE otherwise.
358 * \param - internalFormat - the internal format token provided by the user
361 is_compressed_format(GLenum internalFormat
)
363 switch (internalFormat
) {
364 case GL_COMPRESSED_RGB_FXT1_3DFX
:
365 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
374 * Store a gl_texture_image pointer in a gl_texture_object structure
375 * according to the target and level parameters.
376 * This was basically prompted by the introduction of cube maps.
379 _mesa_set_tex_image(struct gl_texture_object
*tObj
,
380 GLenum target
, GLint level
,
381 struct gl_texture_image
*texImage
)
389 tObj
->Image
[level
] = texImage
;
391 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
392 tObj
->Image
[level
] = texImage
;
394 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
395 tObj
->NegX
[level
] = texImage
;
397 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
398 tObj
->PosY
[level
] = texImage
;
400 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
401 tObj
->NegY
[level
] = texImage
;
403 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
404 tObj
->PosZ
[level
] = texImage
;
406 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
407 tObj
->NegZ
[level
] = texImage
;
409 case GL_TEXTURE_RECTANGLE_NV
:
411 tObj
->Image
[level
] = texImage
;
414 _mesa_problem(NULL
, "bad target in _mesa_set_tex_image()");
422 * Return new gl_texture_image struct with all fields initialized to zero.
424 struct gl_texture_image
*
425 _mesa_alloc_texture_image( void )
427 return CALLOC_STRUCT(gl_texture_image
);
433 _mesa_free_texture_image( struct gl_texture_image
*teximage
)
435 if (teximage
->Data
) {
436 MESA_PBUFFER_FREE( teximage
->Data
);
437 teximage
->Data
= NULL
;
444 * Return GL_TRUE if the target is a proxy target.
447 is_proxy_target(GLenum target
)
449 return (target
== GL_PROXY_TEXTURE_1D
||
450 target
== GL_PROXY_TEXTURE_2D
||
451 target
== GL_PROXY_TEXTURE_3D
||
452 target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
);
457 * Given a texture unit and a texture target, return the corresponding
460 struct gl_texture_object
*
461 _mesa_select_tex_object(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
466 return texUnit
->Current1D
;
467 case GL_PROXY_TEXTURE_1D
:
468 return ctx
->Texture
.Proxy1D
;
470 return texUnit
->Current2D
;
471 case GL_PROXY_TEXTURE_2D
:
472 return ctx
->Texture
.Proxy2D
;
474 return texUnit
->Current3D
;
475 case GL_PROXY_TEXTURE_3D
:
476 return ctx
->Texture
.Proxy3D
;
477 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
478 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
479 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
480 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
481 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
482 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
483 case GL_TEXTURE_CUBE_MAP_ARB
:
484 return ctx
->Extensions
.ARB_texture_cube_map
485 ? texUnit
->CurrentCubeMap
: NULL
;
486 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
487 return ctx
->Extensions
.ARB_texture_cube_map
488 ? ctx
->Texture
.ProxyCubeMap
: NULL
;
489 case GL_TEXTURE_RECTANGLE_NV
:
490 return ctx
->Extensions
.NV_texture_rectangle
491 ? texUnit
->CurrentRect
: NULL
;
492 case GL_PROXY_TEXTURE_RECTANGLE_NV
:
493 return ctx
->Extensions
.NV_texture_rectangle
494 ? ctx
->Texture
.ProxyRect
: NULL
;
496 _mesa_problem(NULL
, "bad target in _mesa_select_tex_object()");
503 * Return the texture image struct which corresponds to target and level
504 * for the given texture unit.
506 struct gl_texture_image
*
507 _mesa_select_tex_image(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
508 GLenum target
, GLint level
)
511 ASSERT(level
< MAX_TEXTURE_LEVELS
);
514 return texUnit
->Current1D
->Image
[level
];
515 case GL_PROXY_TEXTURE_1D
:
516 return ctx
->Texture
.Proxy1D
->Image
[level
];
518 return texUnit
->Current2D
->Image
[level
];
519 case GL_PROXY_TEXTURE_2D
:
520 return ctx
->Texture
.Proxy2D
->Image
[level
];
522 return texUnit
->Current3D
->Image
[level
];
523 case GL_PROXY_TEXTURE_3D
:
524 return ctx
->Texture
.Proxy3D
->Image
[level
];
525 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
526 if (ctx
->Extensions
.ARB_texture_cube_map
)
527 return texUnit
->CurrentCubeMap
->Image
[level
];
530 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
531 if (ctx
->Extensions
.ARB_texture_cube_map
)
532 return texUnit
->CurrentCubeMap
->NegX
[level
];
535 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
536 if (ctx
->Extensions
.ARB_texture_cube_map
)
537 return texUnit
->CurrentCubeMap
->PosY
[level
];
540 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
541 if (ctx
->Extensions
.ARB_texture_cube_map
)
542 return texUnit
->CurrentCubeMap
->NegY
[level
];
545 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
546 if (ctx
->Extensions
.ARB_texture_cube_map
)
547 return texUnit
->CurrentCubeMap
->PosZ
[level
];
550 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
551 if (ctx
->Extensions
.ARB_texture_cube_map
)
552 return texUnit
->CurrentCubeMap
->NegZ
[level
];
555 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
556 if (ctx
->Extensions
.ARB_texture_cube_map
)
557 return ctx
->Texture
.ProxyCubeMap
->Image
[level
];
560 case GL_TEXTURE_RECTANGLE_NV
:
561 if (ctx
->Extensions
.NV_texture_rectangle
) {
563 return texUnit
->CurrentRect
->Image
[level
];
568 case GL_PROXY_TEXTURE_RECTANGLE_NV
:
569 if (ctx
->Extensions
.NV_texture_rectangle
) {
571 return ctx
->Texture
.ProxyRect
->Image
[level
];
577 _mesa_problem(ctx
, "bad target in _mesa_select_tex_image()");
584 #if 000 /* not used anymore */
586 * glTexImage[123]D can accept a NULL image pointer. In this case we
587 * create a texture image with unspecified image contents per the OpenGL
591 make_null_texture(GLint width
, GLint height
, GLint depth
, GLenum format
)
593 const GLint components
= _mesa_components_in_format(format
);
594 const GLint numPixels
= width
* height
* depth
;
595 GLubyte
*data
= (GLubyte
*) MALLOC(numPixels
* components
* sizeof(GLubyte
));
599 * Let's see if anyone finds this. If glTexImage2D() is called with
600 * a NULL image pointer then load the texture image with something
601 * interesting instead of leaving it indeterminate.
604 static const char message
[8][32] = {
608 " X X XXXX XXX XXXXX ",
611 " X X XXXXX XXX X X ",
615 GLubyte
*imgPtr
= data
;
617 for (h
= 0; h
< depth
; h
++) {
618 for (i
= 0; i
< height
; i
++) {
619 GLint srcRow
= 7 - (i
% 8);
620 for (j
= 0; j
< width
; j
++) {
621 GLint srcCol
= j
% 32;
622 GLubyte texel
= (message
[srcRow
][srcCol
]=='X') ? 255 : 70;
623 for (k
= 0; k
< components
; k
++) {
639 * Reset the fields of a gl_texture_image struct to zero.
640 * This is called when a proxy texture test fails, we set all the
641 * image members (except DriverData) to zero.
642 * It's also used in glTexImage[123]D as a safeguard to be sure all
643 * required fields get initialized properly by the Driver.TexImage[123]D
647 clear_teximage_fields(struct gl_texture_image
*img
)
664 img
->TexFormat
= &_mesa_null_texformat
;
665 img
->FetchTexel
= NULL
;
666 img
->IsCompressed
= 0;
667 img
->CompressedSize
= 0;
672 * Initialize basic fields of the gl_texture_image struct.
675 _mesa_init_teximage_fields(GLcontext
*ctx
, GLenum target
,
676 struct gl_texture_image
*img
,
677 GLsizei width
, GLsizei height
, GLsizei depth
,
678 GLint border
, GLenum internalFormat
)
681 img
->Format
= _mesa_base_tex_format( ctx
, internalFormat
);
682 ASSERT(img
->Format
> 0);
683 img
->IntFormat
= internalFormat
;
684 img
->Border
= border
;
686 img
->Height
= height
;
688 img
->RowStride
= width
;
689 img
->WidthLog2
= logbase2(width
- 2 * border
);
690 if (height
== 1) /* 1-D texture */
693 img
->HeightLog2
= logbase2(height
- 2 * border
);
694 if (depth
== 1) /* 2-D texture */
697 img
->DepthLog2
= logbase2(depth
- 2 * border
);
698 img
->Width2
= 1 << img
->WidthLog2
;
699 img
->Height2
= 1 << img
->HeightLog2
;
700 img
->Depth2
= 1 << img
->DepthLog2
;
701 img
->MaxLog2
= MAX2(img
->WidthLog2
, img
->HeightLog2
);
702 img
->IsCompressed
= is_compressed_format(internalFormat
);
703 if (img
->IsCompressed
)
704 img
->CompressedSize
= _mesa_compressed_texture_size(ctx
, width
, height
,
705 depth
, internalFormat
);
707 img
->CompressedSize
= 0;
709 /* Compute Width/Height/DepthScale for mipmap lod computation */
710 if (target
== GL_TEXTURE_RECTANGLE_NV
) {
711 /* scale = 1.0 since texture coords directly map to texels */
712 img
->WidthScale
= 1.0;
713 img
->HeightScale
= 1.0;
714 img
->DepthScale
= 1.0;
717 img
->WidthScale
= (GLfloat
) img
->Width
;
718 img
->HeightScale
= (GLfloat
) img
->Height
;
719 img
->DepthScale
= (GLfloat
) img
->Depth
;
726 * Test glTexImage[123]D() parameters for errors.
728 * dimensions - must be 1 or 2 or 3
729 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
732 texture_error_check( GLcontext
*ctx
, GLenum target
,
733 GLint level
, GLint internalFormat
,
734 GLenum format
, GLenum type
,
736 GLint width
, GLint height
,
737 GLint depth
, GLint border
)
740 GLint maxLevels
= 0, maxTextureSize
;
742 if (dimensions
== 1) {
743 if (target
== GL_PROXY_TEXTURE_1D
) {
746 else if (target
== GL_TEXTURE_1D
) {
750 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
753 maxLevels
= ctx
->Const
.MaxTextureLevels
;
755 else if (dimensions
== 2) {
756 if (target
== GL_PROXY_TEXTURE_2D
) {
758 maxLevels
= ctx
->Const
.MaxTextureLevels
;
760 else if (target
== GL_TEXTURE_2D
) {
762 maxLevels
= ctx
->Const
.MaxTextureLevels
;
764 else if (target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
) {
765 if (!ctx
->Extensions
.ARB_texture_cube_map
) {
766 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
770 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
772 else if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
773 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
774 if (!ctx
->Extensions
.ARB_texture_cube_map
) {
775 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
779 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
781 else if (target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) {
782 if (!ctx
->Extensions
.NV_texture_rectangle
) {
783 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
789 else if (target
== GL_TEXTURE_RECTANGLE_NV
) {
790 if (!ctx
->Extensions
.NV_texture_rectangle
) {
791 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
798 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
802 else if (dimensions
== 3) {
803 if (target
== GL_PROXY_TEXTURE_3D
) {
806 else if (target
== GL_TEXTURE_3D
) {
810 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
813 maxLevels
= ctx
->Const
.Max3DTextureLevels
;
816 _mesa_problem( ctx
, "bad dims in texture_error_check" );
820 ASSERT(maxLevels
> 0);
821 maxTextureSize
= 1 << (maxLevels
- 1);
824 if (border
!= 0 && border
!= 1) {
826 _mesa_error(ctx
, GL_INVALID_VALUE
,
827 "glTexImage%dD(border=%d)", dimensions
, border
);
831 if ((target
== GL_TEXTURE_RECTANGLE_NV
||
832 target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) && border
!= 0) {
837 if (target
== GL_TEXTURE_RECTANGLE_NV
||
838 target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) {
839 if (width
< 1 || width
> ctx
->Const
.MaxTextureRectSize
) {
841 _mesa_error(ctx
, GL_INVALID_VALUE
,
842 "glTexImage%dD(width=%d)", dimensions
, width
);
847 else if (width
< 2 * border
|| width
> 2 + maxTextureSize
848 || logbase2( width
- 2 * border
) < 0) {
850 _mesa_error(ctx
, GL_INVALID_VALUE
,
851 "glTexImage%dD(width=%d)", dimensions
, width
);
857 if (target
== GL_TEXTURE_RECTANGLE_NV
||
858 target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) {
859 if (height
< 1 || height
> ctx
->Const
.MaxTextureRectSize
) {
861 _mesa_error(ctx
, GL_INVALID_VALUE
,
862 "glTexImage%dD(height=%d)", dimensions
, height
);
867 else if (dimensions
>= 2) {
868 if (height
< 2 * border
|| height
> 2 + maxTextureSize
869 || logbase2( height
- 2 * border
) < 0) {
871 _mesa_error(ctx
, GL_INVALID_VALUE
,
872 "glTexImage%dD(height=%d)", dimensions
, height
);
878 /* For cube map, width must equal height */
879 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
880 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
881 if (width
!= height
) {
883 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
890 if (dimensions
>= 3) {
891 if (depth
< 2 * border
|| depth
> 2 + maxTextureSize
892 || logbase2( depth
- 2 * border
) < 0) {
894 _mesa_error( ctx
, GL_INVALID_VALUE
,
895 "glTexImage3D(depth=%d)", depth
);
902 if (target
== GL_TEXTURE_RECTANGLE_NV
||
903 target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) {
906 _mesa_error(ctx
, GL_INVALID_VALUE
,
907 "glTexImage2D(level=%d)", level
);
912 else if (level
< 0 || level
>= maxLevels
) {
914 _mesa_error(ctx
, GL_INVALID_VALUE
,
915 "glTexImage%dD(level=%d)", dimensions
, level
);
920 /* For cube map, width must equal height */
921 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
922 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
923 if (width
!= height
) {
924 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
929 if (_mesa_base_tex_format(ctx
, internalFormat
) < 0) {
931 _mesa_error(ctx
, GL_INVALID_VALUE
,
932 "glTexImage%dD(internalFormat=0x%x)",
933 dimensions
, internalFormat
);
938 if (!_mesa_is_legal_format_and_type(format
, type
)) {
939 /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
940 * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
943 _mesa_error(ctx
, GL_INVALID_OPERATION
,
944 "glTexImage%dD(format or type)", dimensions
);
949 if (format
== GL_YCBCR_MESA
|| internalFormat
== GL_YCBCR_MESA
) {
950 ASSERT(ctx
->Extensions
.MESA_ycbcr_texture
);
951 if (format
!= GL_YCBCR_MESA
||
952 internalFormat
!= GL_YCBCR_MESA
||
953 (type
!= GL_UNSIGNED_SHORT_8_8_MESA
&&
954 type
!= GL_UNSIGNED_SHORT_8_8_REV_MESA
)) {
957 "glTexImage%d(format/type/internalFormat YCBCR mismatch",
959 _mesa_error(ctx
, GL_INVALID_ENUM
, message
);
960 return GL_TRUE
; /* error */
962 if (target
!= GL_TEXTURE_2D
&&
963 target
!= GL_PROXY_TEXTURE_2D
&&
964 target
!= GL_TEXTURE_RECTANGLE_NV
&&
965 target
!= GL_PROXY_TEXTURE_RECTANGLE_NV
) {
967 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage(target)");
974 "glTexImage%d(format=GL_YCBCR_MESA and border=%d)",
976 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
982 if (is_compressed_format(internalFormat
)) {
983 if (target
== GL_TEXTURE_2D
|| target
== GL_PROXY_TEXTURE_2D
) {
986 else if (ctx
->Extensions
.ARB_texture_cube_map
&&
987 (target
== GL_PROXY_TEXTURE_CUBE_MAP
||
988 (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X
&&
989 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
))) {
994 _mesa_error(ctx
, GL_INVALID_ENUM
,
995 "glTexImage%d(target)", dimensions
);
1001 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1002 "glTexImage%D(border!=0)", dimensions
);
1008 /* if we get here, the parameters are OK */
1015 * Test glTexSubImage[123]D() parameters for errors.
1017 * dimensions - must be 1 or 2 or 3
1018 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
1021 subtexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
1022 GLenum target
, GLint level
,
1023 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1024 GLint width
, GLint height
, GLint depth
,
1025 GLenum format
, GLenum type
)
1027 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1028 struct gl_texture_image
*destTex
;
1029 GLint maxLevels
= 0;
1031 if (dimensions
== 1) {
1032 if (target
== GL_TEXTURE_1D
) {
1033 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1036 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(target)" );
1040 else if (dimensions
== 2) {
1041 if (ctx
->Extensions
.ARB_texture_cube_map
&&
1042 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1043 target
<=GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
1044 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
1046 else if (ctx
->Extensions
.NV_texture_rectangle
&&
1047 target
== GL_TEXTURE_RECTANGLE_NV
) {
1050 else if (target
== GL_TEXTURE_2D
) {
1051 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1054 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
1058 else if (dimensions
== 3) {
1059 if (target
== GL_TEXTURE_3D
) {
1060 maxLevels
= ctx
->Const
.Max3DTextureLevels
;
1063 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3D(target)" );
1068 _mesa_problem( ctx
, "bad dims in texture_error_check" );
1072 ASSERT(maxLevels
> 0);
1074 if (level
< 0 || level
>= maxLevels
) {
1075 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(level=%d)", level
);
1080 _mesa_error(ctx
, GL_INVALID_VALUE
,
1081 "glTexSubImage%dD(width=%d)", dimensions
, width
);
1084 if (height
< 0 && dimensions
> 1) {
1085 _mesa_error(ctx
, GL_INVALID_VALUE
,
1086 "glTexSubImage%dD(height=%d)", dimensions
, height
);
1089 if (depth
< 0 && dimensions
> 2) {
1090 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage%dD(depth=%d)", dimensions
, depth
);
1094 destTex
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1097 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glTexSubImage2D");
1101 if (xoffset
< -((GLint
)destTex
->Border
)) {
1102 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset)");
1105 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
1106 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset+width)");
1109 if (dimensions
> 1) {
1110 if (yoffset
< -((GLint
)destTex
->Border
)) {
1111 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset)");
1114 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
1115 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset+height)");
1119 if (dimensions
> 2) {
1120 if (zoffset
< -((GLint
)destTex
->Border
)) {
1121 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset)");
1124 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+ destTex
->Border
)) {
1125 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset+depth)");
1130 if (!_mesa_is_legal_format_and_type(format
, type
)) {
1131 _mesa_error(ctx
, GL_INVALID_ENUM
,
1132 "glTexSubImage%dD(format or type)", dimensions
);
1136 if (destTex
->IsCompressed
) {
1137 const struct gl_texture_unit
*texUnit
;
1138 const struct gl_texture_object
*texObj
;
1139 const struct gl_texture_image
*texImage
;
1140 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1141 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1142 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1144 if (target
== GL_TEXTURE_2D
|| target
== GL_PROXY_TEXTURE_2D
) {
1147 else if (ctx
->Extensions
.ARB_texture_cube_map
&&
1148 (target
== GL_PROXY_TEXTURE_CUBE_MAP
||
1149 (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X
&&
1150 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
))) {
1154 _mesa_error(ctx
, GL_INVALID_ENUM
,
1155 "glTexSubImage%D(target)", dimensions
);
1158 /* offset must be multiple of 4 */
1159 if ((xoffset
& 3) || (yoffset
& 3)) {
1160 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1161 "glTexSubImage%D(xoffset or yoffset)", dimensions
);
1164 /* size must be multiple of 4 or equal to whole texture size */
1165 if ((width
& 3) && width
!= texImage
->Width
) {
1166 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1167 "glTexSubImage%D(width)", dimensions
);
1170 if ((height
& 3) && height
!= texImage
->Height
) {
1171 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1172 "glTexSubImage%D(width)", dimensions
);
1182 * Test glCopyTexImage[12]D() parameters for errors.
1183 * Input: dimensions - must be 1 or 2 or 3
1184 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
1187 copytexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
1188 GLenum target
, GLint level
, GLint internalFormat
,
1189 GLint width
, GLint height
, GLint border
)
1191 GLint maxLevels
= 0, maxTextureSize
;
1193 if (dimensions
== 1) {
1194 if (target
!= GL_TEXTURE_1D
) {
1195 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
1198 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1200 else if (dimensions
== 2) {
1201 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1202 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
1203 if (!ctx
->Extensions
.ARB_texture_cube_map
) {
1204 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1208 else if (target
== GL_TEXTURE_RECTANGLE_NV
) {
1209 if (!ctx
->Extensions
.NV_texture_rectangle
) {
1210 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1214 else if (target
!= GL_TEXTURE_2D
) {
1215 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1218 if (target
== GL_TEXTURE_2D
)
1219 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1220 else if (target
== GL_TEXTURE_RECTANGLE_NV
)
1223 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
1226 ASSERT(maxLevels
> 0);
1227 maxTextureSize
= 1 << (maxLevels
- 1);
1230 if (border
!= 0 && border
!= 1) {
1231 _mesa_error(ctx
, GL_INVALID_VALUE
,
1232 "glCopyTexImage%dD(border)", dimensions
);
1237 if (width
< 2 * border
|| width
> 2 + maxTextureSize
1238 || logbase2( width
- 2 * border
) < 0) {
1239 _mesa_error(ctx
, GL_INVALID_VALUE
,
1240 "glCopyTexImage%dD(width=%d)", dimensions
, width
);
1245 if (dimensions
>= 2) {
1246 if (height
< 2 * border
|| height
> 2 + maxTextureSize
1247 || logbase2( height
- 2 * border
) < 0) {
1248 _mesa_error(ctx
, GL_INVALID_VALUE
,
1249 "glCopyTexImage%dD(height=%d)", dimensions
, height
);
1254 /* For cube map, width must equal height */
1255 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1256 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
1257 if (width
!= height
) {
1258 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(width != height)");
1264 if (level
< 0 || level
>= maxLevels
) {
1265 _mesa_error(ctx
, GL_INVALID_VALUE
,
1266 "glCopyTexImage%dD(level=%d)", dimensions
, level
);
1270 if (_mesa_base_tex_format(ctx
, internalFormat
) < 0) {
1271 _mesa_error(ctx
, GL_INVALID_VALUE
,
1272 "glCopyTexImage%dD(internalFormat)", dimensions
);
1276 if (is_compressed_format(internalFormat
)) {
1277 if (target
!= GL_TEXTURE_2D
) {
1278 _mesa_error(ctx
, GL_INVALID_ENUM
,
1279 "glCopyTexImage%d(target)", dimensions
);
1283 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1284 "glCopyTexImage%D(border!=0)", dimensions
);
1289 /* if we get here, the parameters are OK */
1295 copytexsubimage_error_check( GLcontext
*ctx
, GLuint dimensions
,
1296 GLenum target
, GLint level
,
1297 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1298 GLsizei width
, GLsizei height
)
1300 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1301 struct gl_texture_image
*teximage
;
1302 GLint maxLevels
= 0;
1304 if (dimensions
== 1) {
1305 if (target
!= GL_TEXTURE_1D
) {
1306 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
1309 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1311 else if (dimensions
== 2) {
1312 if (ctx
->Extensions
.ARB_texture_cube_map
) {
1313 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1314 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1315 target
!= GL_TEXTURE_2D
) {
1316 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1320 else if (target
!= GL_TEXTURE_2D
) {
1321 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1324 if (target
== GL_PROXY_TEXTURE_2D
&& target
== GL_TEXTURE_2D
)
1325 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1327 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
1329 else if (dimensions
== 3) {
1330 if (target
!= GL_TEXTURE_3D
) {
1331 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3D(target)" );
1334 maxLevels
= ctx
->Const
.Max3DTextureLevels
;
1337 ASSERT(maxLevels
> 0);
1339 if (level
< 0 || level
>= maxLevels
) {
1340 _mesa_error(ctx
, GL_INVALID_VALUE
,
1341 "glCopyTexSubImage%dD(level=%d)", dimensions
, level
);
1346 _mesa_error(ctx
, GL_INVALID_VALUE
,
1347 "glCopyTexSubImage%dD(width=%d)", dimensions
, width
);
1350 if (dimensions
> 1 && height
< 0) {
1351 _mesa_error(ctx
, GL_INVALID_VALUE
,
1352 "glCopyTexSubImage%dD(height=%d)", dimensions
, height
);
1356 teximage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1358 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1359 "glCopyTexSubImage%dD(undefined texture level: %d)",
1364 if (xoffset
< -((GLint
)teximage
->Border
)) {
1365 _mesa_error(ctx
, GL_INVALID_VALUE
,
1366 "glCopyTexSubImage%dD(xoffset=%d)", dimensions
, xoffset
);
1369 if (xoffset
+ width
> (GLint
) (teximage
->Width
+ teximage
->Border
)) {
1370 _mesa_error(ctx
, GL_INVALID_VALUE
,
1371 "glCopyTexSubImage%dD(xoffset+width)", dimensions
);
1374 if (dimensions
> 1) {
1375 if (yoffset
< -((GLint
)teximage
->Border
)) {
1376 _mesa_error(ctx
, GL_INVALID_VALUE
,
1377 "glCopyTexSubImage%dD(yoffset=%d)", dimensions
, yoffset
);
1380 /* NOTE: we're adding the border here, not subtracting! */
1381 if (yoffset
+ height
> (GLint
) (teximage
->Height
+ teximage
->Border
)) {
1382 _mesa_error(ctx
, GL_INVALID_VALUE
,
1383 "glCopyTexSubImage%dD(yoffset+height)", dimensions
);
1388 if (dimensions
> 2) {
1389 if (zoffset
< -((GLint
)teximage
->Border
)) {
1390 _mesa_error(ctx
, GL_INVALID_VALUE
,
1391 "glCopyTexSubImage%dD(zoffset)", dimensions
);
1394 if (zoffset
> (GLint
) (teximage
->Depth
+ teximage
->Border
)) {
1395 _mesa_error(ctx
, GL_INVALID_VALUE
,
1396 "glCopyTexSubImage%dD(zoffset+depth)", dimensions
);
1401 if (teximage
->IsCompressed
) {
1402 if (target
!= GL_TEXTURE_2D
) {
1403 _mesa_error(ctx
, GL_INVALID_ENUM
,
1404 "glCopyTexSubImage%d(target)", dimensions
);
1407 /* offset must be multiple of 4 */
1408 if ((xoffset
& 3) || (yoffset
& 3)) {
1409 _mesa_error(ctx
, GL_INVALID_VALUE
,
1410 "glCopyTexSubImage%D(xoffset or yoffset)", dimensions
);
1413 /* size must be multiple of 4 */
1414 if ((width
& 3) != 0 && width
!= teximage
->Width
) {
1415 _mesa_error(ctx
, GL_INVALID_VALUE
,
1416 "glCopyTexSubImage%D(width)", dimensions
);
1419 if ((height
& 3) != 0 && height
!= teximage
->Height
) {
1420 _mesa_error(ctx
, GL_INVALID_VALUE
,
1421 "glCopyTexSubImage%D(height)", dimensions
);
1426 if (teximage
->IntFormat
== GL_YCBCR_MESA
) {
1427 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glCopyTexSubImage2D");
1431 /* if we get here, the parameters are OK */
1438 _mesa_GetTexImage( GLenum target
, GLint level
, GLenum format
,
1439 GLenum type
, GLvoid
*pixels
)
1441 const struct gl_texture_unit
*texUnit
;
1442 const struct gl_texture_object
*texObj
;
1443 const struct gl_texture_image
*texImage
;
1444 GLint maxLevels
= 0;
1445 GET_CURRENT_CONTEXT(ctx
);
1446 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1448 texUnit
= &(ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
]);
1449 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1450 if (!texObj
|| is_proxy_target(target
)) {
1451 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)");
1455 if (target
== GL_TEXTURE_1D
|| target
== GL_TEXTURE_2D
) {
1456 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1458 else if (target
== GL_TEXTURE_3D
) {
1459 maxLevels
= ctx
->Const
.Max3DTextureLevels
;
1461 else if (target
== GL_TEXTURE_RECTANGLE_NV
) {
1465 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
1468 ASSERT(maxLevels
> 0);
1470 if (level
< 0 || level
>= maxLevels
) {
1471 _mesa_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
1475 if (_mesa_sizeof_packed_type(type
) <= 0) {
1476 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
1480 if (_mesa_components_in_format(format
) <= 0 ||
1481 format
== GL_STENCIL_INDEX
) {
1482 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
1486 if (!ctx
->Extensions
.EXT_paletted_texture
&& is_index_format(format
)) {
1487 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1490 if (!ctx
->Extensions
.SGIX_depth_texture
&& format
== GL_DEPTH_COMPONENT
) {
1491 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1494 if (!ctx
->Extensions
.MESA_ycbcr_texture
&& format
== GL_YCBCR_MESA
) {
1495 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1498 /* XXX what if format/type doesn't match texture format/type? */
1503 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1505 /* invalid mipmap level, not an error */
1509 if (!texImage
->Data
) {
1510 /* no image data, not an error */
1515 const GLint width
= texImage
->Width
;
1516 const GLint height
= texImage
->Height
;
1517 const GLint depth
= texImage
->Depth
;
1519 for (img
= 0; img
< depth
; img
++) {
1520 for (row
= 0; row
< height
; row
++) {
1521 /* compute destination address in client memory */
1522 GLvoid
*dest
= _mesa_image_address( &ctx
->Pack
, pixels
,
1523 width
, height
, format
, type
,
1527 if (format
== GL_COLOR_INDEX
) {
1528 GLuint indexRow
[MAX_WIDTH
];
1530 for (col
= 0; col
< width
; col
++) {
1531 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1532 (GLvoid
*) &indexRow
[col
]);
1534 _mesa_pack_index_span(ctx
, width
, type
, dest
,
1535 indexRow
, &ctx
->Pack
,
1536 0 /* no image transfer */);
1538 else if (format
== GL_DEPTH_COMPONENT
) {
1539 GLfloat depthRow
[MAX_WIDTH
];
1541 for (col
= 0; col
< width
; col
++) {
1542 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1543 (GLvoid
*) &depthRow
[col
]);
1545 _mesa_pack_depth_span(ctx
, width
, dest
, type
,
1546 depthRow
, &ctx
->Pack
);
1548 else if (format
== GL_YCBCR_MESA
) {
1549 /* No pixel transfer */
1550 const GLint rowstride
= texImage
->RowStride
;
1552 (const GLushort
*) texImage
->Data
+ row
* rowstride
,
1553 width
* sizeof(GLushort
));
1554 /* check for byte swapping */
1555 if ((texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_YCBCR
1556 && type
== GL_UNSIGNED_SHORT_8_8_REV_MESA
) ||
1557 (texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_YCBCR_REV
1558 && type
== GL_UNSIGNED_SHORT_8_8_MESA
)) {
1559 if (!ctx
->Pack
.SwapBytes
)
1560 _mesa_swap2((GLushort
*) dest
, width
);
1562 else if (ctx
->Pack
.SwapBytes
) {
1563 _mesa_swap2((GLushort
*) dest
, width
);
1567 /* general case: convert row to RGBA format */
1568 GLchan rgba
[MAX_WIDTH
][4];
1570 for (col
= 0; col
< width
; col
++) {
1571 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1572 (GLvoid
*) rgba
[col
]);
1574 _mesa_pack_rgba_span(ctx
, width
, (const GLchan (*)[4])rgba
,
1575 format
, type
, dest
, &ctx
->Pack
,
1576 0 /* no image transfer */);
1586 * Called from the API. Note that width includes the border.
1589 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
1590 GLsizei width
, GLint border
, GLenum format
,
1591 GLenum type
, const GLvoid
*pixels
)
1593 GLsizei postConvWidth
= width
;
1594 GET_CURRENT_CONTEXT(ctx
);
1595 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1597 if (is_color_format(internalFormat
)) {
1598 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1601 if (target
== GL_TEXTURE_1D
) {
1602 struct gl_texture_unit
*texUnit
;
1603 struct gl_texture_object
*texObj
;
1604 struct gl_texture_image
*texImage
;
1606 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1607 format
, type
, 1, postConvWidth
, 1, 1, border
)) {
1608 return; /* error was recorded */
1611 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1612 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1613 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1616 texImage
= _mesa_alloc_texture_image();
1617 texObj
->Image
[level
] = texImage
;
1619 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
1623 else if (texImage
->Data
) {
1624 /* free the old texture data */
1625 MESA_PBUFFER_FREE(texImage
->Data
);
1626 texImage
->Data
= NULL
;
1628 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1629 _mesa_init_teximage_fields(ctx
, target
, texImage
,
1630 postConvWidth
, 1, 1,
1631 border
, internalFormat
);
1633 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1634 _mesa_update_state(ctx
);
1636 ASSERT(ctx
->Driver
.TexImage1D
);
1638 /* Give the texture to the driver! <pixels> may be null! */
1639 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1640 width
, border
, format
, type
, pixels
,
1641 &ctx
->Unpack
, texObj
, texImage
);
1643 ASSERT(texImage
->TexFormat
);
1644 if (!texImage
->FetchTexel
) {
1645 /* If driver didn't explicitly set this, use the default */
1646 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel1D
;
1648 ASSERT(texImage
->FetchTexel
);
1651 texObj
->Complete
= GL_FALSE
;
1652 ctx
->NewState
|= _NEW_TEXTURE
;
1654 else if (target
== GL_PROXY_TEXTURE_1D
) {
1655 /* Proxy texture: check for errors and update proxy state */
1656 GLboolean error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1657 format
, type
, 1, postConvWidth
, 1, 1, border
);
1659 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1660 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1661 internalFormat
, format
, type
,
1662 postConvWidth
, 1, 1, border
);
1665 /* if error, clear all proxy texture image parameters */
1666 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1667 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
1671 /* no error, set the tex image parameters */
1672 struct gl_texture_unit
*texUnit
;
1673 struct gl_texture_image
*texImage
;
1674 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1675 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1676 _mesa_init_teximage_fields(ctx
, target
, texImage
,
1677 postConvWidth
, 1, 1,
1678 border
, internalFormat
);
1682 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1689 _mesa_TexImage2D( GLenum target
, GLint level
, GLint internalFormat
,
1690 GLsizei width
, GLsizei height
, GLint border
,
1691 GLenum format
, GLenum type
,
1692 const GLvoid
*pixels
)
1694 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1695 GET_CURRENT_CONTEXT(ctx
);
1696 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1698 if (is_color_format(internalFormat
)) {
1699 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1703 if (target
== GL_TEXTURE_2D
||
1704 (ctx
->Extensions
.ARB_texture_cube_map
&&
1705 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1706 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) ||
1707 (ctx
->Extensions
.NV_texture_rectangle
&&
1708 target
== GL_TEXTURE_RECTANGLE_NV
)) {
1709 /* non-proxy target */
1710 struct gl_texture_unit
*texUnit
;
1711 struct gl_texture_object
*texObj
;
1712 struct gl_texture_image
*texImage
;
1714 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1715 format
, type
, 2, postConvWidth
, postConvHeight
,
1717 return; /* error was recorded */
1720 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1721 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1722 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1725 texImage
= _mesa_alloc_texture_image();
1726 _mesa_set_tex_image(texObj
, target
, level
, texImage
);
1728 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1732 else if (texImage
->Data
) {
1733 /* free the old texture 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 postConvWidth
, postConvHeight
, 1,
1740 border
, internalFormat
);
1742 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1743 _mesa_update_state(ctx
);
1745 ASSERT(ctx
->Driver
.TexImage2D
);
1747 /* Give the texture to the driver! <pixels> may be null! */
1748 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1749 width
, height
, border
, format
, type
, pixels
,
1750 &ctx
->Unpack
, texObj
, texImage
);
1752 ASSERT(texImage
->TexFormat
);
1753 if (!texImage
->FetchTexel
) {
1754 /* If driver didn't explicitly set this, use the default */
1755 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel2D
;
1757 ASSERT(texImage
->FetchTexel
);
1760 texObj
->Complete
= GL_FALSE
;
1761 ctx
->NewState
|= _NEW_TEXTURE
;
1763 else if (target
== GL_PROXY_TEXTURE_2D
||
1764 (target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
&&
1765 ctx
->Extensions
.ARB_texture_cube_map
) ||
1766 (target
== GL_PROXY_TEXTURE_RECTANGLE_NV
&&
1767 ctx
->Extensions
.NV_texture_rectangle
)) {
1768 /* Proxy texture: check for errors and update proxy state */
1769 GLboolean error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1770 format
, type
, 2, postConvWidth
, postConvHeight
, 1, border
);
1772 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1773 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1774 internalFormat
, format
, type
,
1775 postConvWidth
, postConvHeight
, 1, border
);
1778 /* if error, clear all proxy texture image parameters */
1779 const GLint maxLevels
= (target
== GL_PROXY_TEXTURE_2D
) ?
1780 ctx
->Const
.MaxTextureLevels
: ctx
->Const
.MaxCubeTextureLevels
;
1781 if (level
>= 0 && level
< maxLevels
) {
1782 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
1786 /* no error, set the tex image parameters */
1787 struct gl_texture_unit
*texUnit
;
1788 struct gl_texture_image
*texImage
;
1789 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1790 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1791 _mesa_init_teximage_fields(ctx
, target
, texImage
,
1792 postConvWidth
, postConvHeight
, 1,
1793 border
, internalFormat
);
1797 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1804 * Called by the API or display list executor.
1805 * Note that width and height include the border.
1808 _mesa_TexImage3D( GLenum target
, GLint level
, GLint internalFormat
,
1809 GLsizei width
, GLsizei height
, GLsizei depth
,
1810 GLint border
, GLenum format
, GLenum type
,
1811 const GLvoid
*pixels
)
1813 GET_CURRENT_CONTEXT(ctx
);
1814 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1816 if (target
== GL_TEXTURE_3D
) {
1817 struct gl_texture_unit
*texUnit
;
1818 struct gl_texture_object
*texObj
;
1819 struct gl_texture_image
*texImage
;
1821 if (texture_error_check(ctx
, target
, level
, (GLint
) internalFormat
,
1822 format
, type
, 3, width
, height
, depth
, border
)) {
1823 return; /* error was recorded */
1826 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1827 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1828 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1831 texImage
= _mesa_alloc_texture_image();
1832 texObj
->Image
[level
] = texImage
;
1834 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
1838 else if (texImage
->Data
) {
1839 MESA_PBUFFER_FREE(texImage
->Data
);
1840 texImage
->Data
= NULL
;
1842 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1843 _mesa_init_teximage_fields(ctx
, target
, texImage
,
1844 width
, height
, depth
,
1845 border
, internalFormat
);
1847 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1848 _mesa_update_state(ctx
);
1850 ASSERT(ctx
->Driver
.TexImage3D
);
1852 /* Give the texture to the driver! <pixels> may be null! */
1853 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, internalFormat
,
1854 width
, height
, depth
, border
, format
, type
,
1855 pixels
, &ctx
->Unpack
, texObj
, texImage
);
1857 ASSERT(texImage
->TexFormat
);
1858 if (!texImage
->FetchTexel
) {
1859 /* If driver didn't explicitly set this, use the default */
1860 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel3D
;
1862 ASSERT(texImage
->FetchTexel
);
1865 texObj
->Complete
= GL_FALSE
;
1866 ctx
->NewState
|= _NEW_TEXTURE
;
1868 else if (target
== GL_PROXY_TEXTURE_3D
) {
1869 /* Proxy texture: check for errors and update proxy state */
1870 GLboolean error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1871 format
, type
, 3, width
, height
, depth
, border
);
1873 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1874 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1875 internalFormat
, format
, type
,
1876 width
, height
, depth
, border
);
1879 /* if error, clear all proxy texture image parameters */
1880 if (level
>= 0 && level
< ctx
->Const
.Max3DTextureLevels
) {
1881 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
1885 /* no error, set the tex image parameters */
1886 struct gl_texture_unit
*texUnit
;
1887 struct gl_texture_image
*texImage
;
1888 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1889 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1890 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
, 1,
1891 border
, internalFormat
);
1895 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1902 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
1903 GLsizei width
, GLsizei height
, GLsizei depth
,
1904 GLint border
, GLenum format
, GLenum type
,
1905 const GLvoid
*pixels
)
1907 _mesa_TexImage3D(target
, level
, (GLint
) internalFormat
, width
, height
,
1908 depth
, border
, format
, type
, pixels
);
1914 _mesa_TexSubImage1D( GLenum target
, GLint level
,
1915 GLint xoffset
, GLsizei width
,
1916 GLenum format
, GLenum type
,
1917 const GLvoid
*pixels
)
1919 GLsizei postConvWidth
= width
;
1920 struct gl_texture_unit
*texUnit
;
1921 struct gl_texture_object
*texObj
;
1922 struct gl_texture_image
*texImage
;
1923 GET_CURRENT_CONTEXT(ctx
);
1924 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1926 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1927 _mesa_update_state(ctx
);
1929 /* XXX should test internal format */
1930 if (is_color_format(format
)) {
1931 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1934 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
1935 postConvWidth
, 1, 1, format
, type
)) {
1936 return; /* error was detected */
1939 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1940 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1941 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1944 if (width
== 0 || !pixels
)
1945 return; /* no-op, not an error */
1947 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1948 xoffset
+= texImage
->Border
;
1950 ASSERT(ctx
->Driver
.TexSubImage1D
);
1951 (*ctx
->Driver
.TexSubImage1D
)(ctx
, target
, level
, xoffset
, width
,
1952 format
, type
, pixels
, &ctx
->Unpack
,
1954 ctx
->NewState
|= _NEW_TEXTURE
;
1959 _mesa_TexSubImage2D( GLenum target
, GLint level
,
1960 GLint xoffset
, GLint yoffset
,
1961 GLsizei width
, GLsizei height
,
1962 GLenum format
, GLenum type
,
1963 const GLvoid
*pixels
)
1965 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1966 struct gl_texture_unit
*texUnit
;
1967 struct gl_texture_object
*texObj
;
1968 struct gl_texture_image
*texImage
;
1969 GET_CURRENT_CONTEXT(ctx
);
1970 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1972 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1973 _mesa_update_state(ctx
);
1975 /* XXX should test internal format */
1976 if (is_color_format(format
)) {
1977 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1981 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1982 postConvWidth
, postConvHeight
, 1, format
, type
)) {
1983 return; /* error was detected */
1986 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1987 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1988 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1991 if (width
== 0 || height
== 0 || !pixels
)
1992 return; /* no-op, not an error */
1994 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1995 xoffset
+= texImage
->Border
;
1996 yoffset
+= texImage
->Border
;
1998 ASSERT(ctx
->Driver
.TexSubImage2D
);
1999 (*ctx
->Driver
.TexSubImage2D
)(ctx
, target
, level
, xoffset
, yoffset
,
2000 width
, height
, format
, type
, pixels
,
2001 &ctx
->Unpack
, texObj
, texImage
);
2002 ctx
->NewState
|= _NEW_TEXTURE
;
2008 _mesa_TexSubImage3D( GLenum target
, GLint level
,
2009 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2010 GLsizei width
, GLsizei height
, GLsizei depth
,
2011 GLenum format
, GLenum type
,
2012 const GLvoid
*pixels
)
2014 struct gl_texture_unit
*texUnit
;
2015 struct gl_texture_object
*texObj
;
2016 struct gl_texture_image
*texImage
;
2017 GET_CURRENT_CONTEXT(ctx
);
2018 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2020 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2021 _mesa_update_state(ctx
);
2023 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2024 width
, height
, depth
, format
, type
)) {
2025 return; /* error was detected */
2028 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2029 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2030 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2033 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
2034 return; /* no-op, not an error */
2036 /* If we have a border, xoffset=-1 is legal. Bias by border width */
2037 xoffset
+= texImage
->Border
;
2038 yoffset
+= texImage
->Border
;
2039 zoffset
+= texImage
->Border
;
2041 ASSERT(ctx
->Driver
.TexSubImage3D
);
2042 (*ctx
->Driver
.TexSubImage3D
)(ctx
, target
, level
,
2043 xoffset
, yoffset
, zoffset
,
2044 width
, height
, depth
,
2045 format
, type
, pixels
,
2046 &ctx
->Unpack
, texObj
, texImage
);
2047 ctx
->NewState
|= _NEW_TEXTURE
;
2053 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
2054 GLenum internalFormat
,
2056 GLsizei width
, GLint border
)
2058 struct gl_texture_unit
*texUnit
;
2059 struct gl_texture_object
*texObj
;
2060 struct gl_texture_image
*texImage
;
2061 GLsizei postConvWidth
= width
;
2062 GET_CURRENT_CONTEXT(ctx
);
2063 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2065 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2066 _mesa_update_state(ctx
);
2068 if (is_color_format(internalFormat
)) {
2069 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
2072 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
2073 postConvWidth
, 1, border
))
2076 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2077 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2078 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2080 texImage
= _mesa_alloc_texture_image();
2081 _mesa_set_tex_image(texObj
, target
, level
, texImage
);
2083 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D");
2087 else if (texImage
->Data
) {
2088 /* free the old texture data */
2089 MESA_PBUFFER_FREE(texImage
->Data
);
2090 texImage
->Data
= NULL
;
2093 clear_teximage_fields(texImage
); /* not really needed, but helpful */
2094 _mesa_init_teximage_fields(ctx
, target
, texImage
, postConvWidth
, 1, 1,
2095 border
, internalFormat
);
2098 ASSERT(ctx
->Driver
.CopyTexImage1D
);
2099 (*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
, internalFormat
,
2100 x
, y
, width
, border
);
2102 ASSERT(texImage
->TexFormat
);
2103 if (!texImage
->FetchTexel
) {
2104 /* If driver didn't explicitly set this, use the default */
2105 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel1D
;
2107 ASSERT(texImage
->FetchTexel
);
2110 texObj
->Complete
= GL_FALSE
;
2111 ctx
->NewState
|= _NEW_TEXTURE
;
2117 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
2118 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
2121 struct gl_texture_unit
*texUnit
;
2122 struct gl_texture_object
*texObj
;
2123 struct gl_texture_image
*texImage
;
2124 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2125 GET_CURRENT_CONTEXT(ctx
);
2126 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2128 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2129 _mesa_update_state(ctx
);
2131 if (is_color_format(internalFormat
)) {
2132 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
2136 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
2137 postConvWidth
, postConvHeight
, border
))
2140 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2141 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2142 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2144 texImage
= _mesa_alloc_texture_image();
2145 _mesa_set_tex_image(texObj
, target
, level
, texImage
);
2147 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D");
2151 else if (texImage
->Data
) {
2152 /* free the old texture data */
2153 MESA_PBUFFER_FREE(texImage
->Data
);
2154 texImage
->Data
= NULL
;
2157 clear_teximage_fields(texImage
); /* not really needed, but helpful */
2158 _mesa_init_teximage_fields(ctx
, target
, texImage
,
2159 postConvWidth
, postConvHeight
, 1,
2160 border
, internalFormat
);
2162 ASSERT(ctx
->Driver
.CopyTexImage2D
);
2163 (*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
, internalFormat
,
2164 x
, y
, width
, height
, border
);
2166 ASSERT(texImage
->TexFormat
);
2167 if (!texImage
->FetchTexel
) {
2168 /* If driver didn't explicitly set this, use the default */
2169 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel2D
;
2171 ASSERT(texImage
->FetchTexel
);
2174 texObj
->Complete
= GL_FALSE
;
2175 ctx
->NewState
|= _NEW_TEXTURE
;
2181 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
2182 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
2184 struct gl_texture_unit
*texUnit
;
2185 struct gl_texture_object
*texObj
;
2186 struct gl_texture_image
*texImage
;
2187 GLsizei postConvWidth
= width
;
2188 GET_CURRENT_CONTEXT(ctx
);
2189 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2191 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2192 _mesa_update_state(ctx
);
2194 /* XXX should test internal format */
2195 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
2197 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
2198 xoffset
, 0, 0, postConvWidth
, 1))
2201 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2202 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2203 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2205 /* If we have a border, xoffset=-1 is legal. Bias by border width */
2206 xoffset
+= texImage
->Border
;
2208 ASSERT(ctx
->Driver
.CopyTexSubImage1D
);
2209 (*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
, xoffset
, x
, y
, width
);
2210 ctx
->NewState
|= _NEW_TEXTURE
;
2216 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
2217 GLint xoffset
, GLint yoffset
,
2218 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2220 struct gl_texture_unit
*texUnit
;
2221 struct gl_texture_object
*texObj
;
2222 struct gl_texture_image
*texImage
;
2223 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2224 GET_CURRENT_CONTEXT(ctx
);
2225 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2227 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2228 _mesa_update_state(ctx
);
2230 /* XXX should test internal format */
2231 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
2233 if (copytexsubimage_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2234 postConvWidth
, postConvHeight
))
2237 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2238 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2239 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2241 /* If we have a border, xoffset=-1 is legal. Bias by border width */
2242 xoffset
+= texImage
->Border
;
2243 yoffset
+= texImage
->Border
;
2245 ASSERT(ctx
->Driver
.CopyTexSubImage2D
);
2246 (*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
2247 xoffset
, yoffset
, x
, y
, width
, height
);
2248 ctx
->NewState
|= _NEW_TEXTURE
;
2254 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
2255 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2256 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2258 struct gl_texture_unit
*texUnit
;
2259 struct gl_texture_object
*texObj
;
2260 struct gl_texture_image
*texImage
;
2261 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2262 GET_CURRENT_CONTEXT(ctx
);
2263 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2265 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2266 _mesa_update_state(ctx
);
2268 /* XXX should test internal format */
2269 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
2271 if (copytexsubimage_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
,
2272 zoffset
, postConvWidth
, postConvHeight
))
2275 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2276 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2277 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2279 /* If we have a border, xoffset=-1 is legal. Bias by border width */
2280 xoffset
+= texImage
->Border
;
2281 yoffset
+= texImage
->Border
;
2282 zoffset
+= texImage
->Border
;
2284 ASSERT(ctx
->Driver
.CopyTexSubImage3D
);
2285 (*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
2286 xoffset
, yoffset
, zoffset
,
2287 x
, y
, width
, height
);
2288 ctx
->NewState
|= _NEW_TEXTURE
;
2294 /**********************************************************************/
2295 /****** Compressed Textures ******/
2296 /**********************************************************************/
2300 * Error checking for glCompressedTexImage[123]D().
2301 * \return error code or GL_NO_ERROR.
2304 compressed_texture_error_check(GLcontext
*ctx
, GLint dimensions
,
2305 GLenum target
, GLint level
,
2306 GLenum internalFormat
, GLsizei width
,
2307 GLsizei height
, GLsizei depth
, GLint border
,
2310 GLboolean isProxy
= GL_FALSE
;
2311 GLint expectedSize
, maxLevels
= 0, maxTextureSize
;
2313 if (dimensions
== 1) {
2314 /* 1D compressed textures not allowed */
2315 return GL_INVALID_ENUM
;
2317 else if (dimensions
== 2) {
2318 if (target
== GL_PROXY_TEXTURE_2D
) {
2319 maxLevels
= ctx
->Const
.MaxTextureLevels
;
2322 else if (target
== GL_TEXTURE_2D
) {
2323 maxLevels
= ctx
->Const
.MaxTextureLevels
;
2325 else if (target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
) {
2326 if (!ctx
->Extensions
.ARB_texture_cube_map
)
2327 return GL_INVALID_ENUM
; /*target*/
2328 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
2331 else if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2332 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
2333 if (!ctx
->Extensions
.ARB_texture_cube_map
)
2334 return GL_INVALID_ENUM
; /*target*/
2335 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
2338 return GL_INVALID_ENUM
; /*target*/
2341 else if (dimensions
== 3) {
2342 /* 3D compressed textures not allowed */
2343 return GL_INVALID_ENUM
;
2346 maxTextureSize
= 1 << (maxLevels
- 1);
2348 if (!is_compressed_format(internalFormat
))
2349 return GL_INVALID_ENUM
;
2352 return GL_INVALID_VALUE
;
2354 if (width
< 1 || width
> maxTextureSize
|| logbase2(width
) < 0)
2355 return GL_INVALID_VALUE
;
2357 if ((height
< 1 || height
> maxTextureSize
|| logbase2(height
) < 0)
2359 return GL_INVALID_VALUE
;
2361 if ((depth
< 1 || depth
> maxTextureSize
|| logbase2(depth
) < 0)
2363 return GL_INVALID_VALUE
;
2365 /* For cube map, width must equal height */
2366 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2367 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
&& width
!= height
)
2368 return GL_INVALID_VALUE
;
2370 if (level
< 0 || level
>= maxLevels
)
2371 return GL_INVALID_VALUE
;
2373 expectedSize
= _mesa_compressed_texture_size(ctx
, width
, height
, depth
,
2375 if (expectedSize
!= imageSize
)
2376 return GL_INVALID_VALUE
;
2383 * Error checking for glCompressedTexSubImage[123]D().
2384 * \return error code or GL_NO_ERROR.
2387 compressed_subtexture_error_check(GLcontext
*ctx
, GLint dimensions
,
2388 GLenum target
, GLint level
,
2389 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2390 GLsizei width
, GLsizei height
, GLsizei depth
,
2391 GLenum format
, GLsizei imageSize
)
2393 GLboolean isProxy
= GL_FALSE
;
2394 GLint expectedSize
, maxLevels
= 0, maxTextureSize
;
2396 if (dimensions
== 1) {
2397 /* 1D compressed textures not allowed */
2398 return GL_INVALID_ENUM
;
2400 else if (dimensions
== 2) {
2401 if (target
== GL_PROXY_TEXTURE_2D
) {
2402 maxLevels
= ctx
->Const
.MaxTextureLevels
;
2405 else if (target
== GL_TEXTURE_2D
) {
2406 maxLevels
= ctx
->Const
.MaxTextureLevels
;
2408 else if (target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
) {
2409 if (!ctx
->Extensions
.ARB_texture_cube_map
)
2410 return GL_INVALID_ENUM
; /*target*/
2411 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
2414 else if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2415 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
2416 if (!ctx
->Extensions
.ARB_texture_cube_map
)
2417 return GL_INVALID_ENUM
; /*target*/
2418 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
2421 return GL_INVALID_ENUM
; /*target*/
2424 else if (dimensions
== 3) {
2425 /* 3D compressed textures not allowed */
2426 return GL_INVALID_ENUM
;
2429 maxTextureSize
= 1 << (maxLevels
- 1);
2431 if (!is_compressed_format(format
))
2432 return GL_INVALID_ENUM
;
2434 if (width
< 1 || width
> maxTextureSize
|| logbase2(width
) < 0)
2435 return GL_INVALID_VALUE
;
2437 if ((height
< 1 || height
> maxTextureSize
|| logbase2(height
) < 0)
2439 return GL_INVALID_VALUE
;
2441 if (level
< 0 || level
>= maxLevels
)
2442 return GL_INVALID_VALUE
;
2444 if ((xoffset
& 3) != 0 || (yoffset
& 3) != 0)
2445 return GL_INVALID_VALUE
;
2447 if ((width
& 3) != 0 && width
!= 2 && width
!= 1)
2448 return GL_INVALID_VALUE
;
2450 if ((height
& 3) != 0 && height
!= 2 && height
!= 1)
2451 return GL_INVALID_VALUE
;
2453 expectedSize
= _mesa_compressed_texture_size(ctx
, width
, height
, depth
,
2455 if (expectedSize
!= imageSize
)
2456 return GL_INVALID_VALUE
;
2464 _mesa_CompressedTexImage1DARB(GLenum target
, GLint level
,
2465 GLenum internalFormat
, GLsizei width
,
2466 GLint border
, GLsizei imageSize
,
2469 GET_CURRENT_CONTEXT(ctx
);
2470 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2472 if (target
== GL_TEXTURE_1D
) {
2473 struct gl_texture_unit
*texUnit
;
2474 struct gl_texture_object
*texObj
;
2475 struct gl_texture_image
*texImage
;
2476 GLenum error
= compressed_texture_error_check(ctx
, 1, target
, level
,
2477 internalFormat
, width
, 1, 1, border
, imageSize
);
2479 _mesa_error(ctx
, error
, "glCompressedTexImage1D");
2483 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2484 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2485 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2488 texImage
= _mesa_alloc_texture_image();
2489 texObj
->Image
[level
] = texImage
;
2491 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage1D");
2495 else if (texImage
->Data
) {
2496 MESA_PBUFFER_FREE(texImage
->Data
);
2497 texImage
->Data
= NULL
;
2500 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, 1, 1,
2501 border
, internalFormat
);
2503 ASSERT(ctx
->Driver
.CompressedTexImage1D
);
2504 (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
,
2505 internalFormat
, width
, border
,
2510 texObj
->Complete
= GL_FALSE
;
2511 ctx
->NewState
|= _NEW_TEXTURE
;
2513 else if (target
== GL_PROXY_TEXTURE_1D
) {
2514 /* Proxy texture: check for errors and update proxy state */
2515 GLenum error
= compressed_texture_error_check(ctx
, 1, target
, level
,
2516 internalFormat
, width
, 1, 1, border
, imageSize
);
2518 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2519 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2520 internalFormat
, GL_NONE
, GL_NONE
,
2521 width
, 1, 1, border
);
2524 /* if error, clear all proxy texture image parameters */
2525 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2526 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
2530 /* store the teximage parameters */
2531 struct gl_texture_unit
*texUnit
;
2532 struct gl_texture_image
*texImage
;
2533 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2534 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2535 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, 1, 1,
2536 border
, internalFormat
);
2540 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1D(target)");
2547 _mesa_CompressedTexImage2DARB(GLenum target
, GLint level
,
2548 GLenum internalFormat
, GLsizei width
,
2549 GLsizei height
, GLint border
, GLsizei imageSize
,
2552 GET_CURRENT_CONTEXT(ctx
);
2553 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2555 if (target
== GL_TEXTURE_2D
||
2556 (ctx
->Extensions
.ARB_texture_cube_map
&&
2557 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2558 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
2559 struct gl_texture_unit
*texUnit
;
2560 struct gl_texture_object
*texObj
;
2561 struct gl_texture_image
*texImage
;
2562 GLenum error
= compressed_texture_error_check(ctx
, 2, target
, level
,
2563 internalFormat
, width
, height
, 1, border
, imageSize
);
2565 _mesa_error(ctx
, error
, "glCompressedTexImage2D");
2569 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2570 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2571 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2574 texImage
= _mesa_alloc_texture_image();
2575 texObj
->Image
[level
] = texImage
;
2577 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
2581 else if (texImage
->Data
) {
2582 MESA_PBUFFER_FREE(texImage
->Data
);
2583 texImage
->Data
= NULL
;
2586 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
, 1,
2587 border
, internalFormat
);
2589 ASSERT(ctx
->Driver
.CompressedTexImage2D
);
2590 (*ctx
->Driver
.CompressedTexImage2D
)(ctx
, target
, level
,
2591 internalFormat
, width
, height
,
2592 border
, imageSize
, data
,
2596 texObj
->Complete
= GL_FALSE
;
2597 ctx
->NewState
|= _NEW_TEXTURE
;
2599 else if (target
== GL_PROXY_TEXTURE_2D
||
2600 (target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
&&
2601 ctx
->Extensions
.ARB_texture_cube_map
)) {
2602 /* Proxy texture: check for errors and update proxy state */
2603 GLenum error
= compressed_texture_error_check(ctx
, 2, target
, level
,
2604 internalFormat
, width
, height
, 1, border
, imageSize
);
2606 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2607 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2608 internalFormat
, GL_NONE
, GL_NONE
,
2609 width
, height
, 1, border
);
2612 /* if error, clear all proxy texture image parameters */
2613 const GLint maxLevels
= (target
== GL_PROXY_TEXTURE_2D
) ?
2614 ctx
->Const
.MaxTextureLevels
: ctx
->Const
.MaxCubeTextureLevels
;
2615 if (level
>= 0 && level
< maxLevels
) {
2616 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
2620 /* store the teximage parameters */
2621 struct gl_texture_unit
*texUnit
;
2622 struct gl_texture_image
*texImage
;
2623 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2624 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2625 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
, 1,
2626 border
, internalFormat
);
2630 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2D(target)");
2637 _mesa_CompressedTexImage3DARB(GLenum target
, GLint level
,
2638 GLenum internalFormat
, GLsizei width
,
2639 GLsizei height
, GLsizei depth
, GLint border
,
2640 GLsizei imageSize
, const GLvoid
*data
)
2642 GET_CURRENT_CONTEXT(ctx
);
2643 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2645 if (target
== GL_TEXTURE_3D
) {
2646 struct gl_texture_unit
*texUnit
;
2647 struct gl_texture_object
*texObj
;
2648 struct gl_texture_image
*texImage
;
2649 GLenum error
= compressed_texture_error_check(ctx
, 3, target
, level
,
2650 internalFormat
, width
, height
, depth
, border
, imageSize
);
2652 _mesa_error(ctx
, error
, "glCompressedTexImage3D");
2656 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2657 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2658 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2661 texImage
= _mesa_alloc_texture_image();
2662 texObj
->Image
[level
] = texImage
;
2664 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage3D");
2668 else if (texImage
->Data
) {
2669 MESA_PBUFFER_FREE(texImage
->Data
);
2670 texImage
->Data
= NULL
;
2673 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
, depth
,
2674 border
, internalFormat
);
2676 ASSERT(ctx
->Driver
.CompressedTexImage3D
);
2677 (*ctx
->Driver
.CompressedTexImage3D
)(ctx
, target
, level
,
2679 width
, height
, depth
,
2680 border
, imageSize
, data
,
2684 texObj
->Complete
= GL_FALSE
;
2685 ctx
->NewState
|= _NEW_TEXTURE
;
2687 else if (target
== GL_PROXY_TEXTURE_3D
) {
2688 /* Proxy texture: check for errors and update proxy state */
2689 GLenum error
= compressed_texture_error_check(ctx
, 3, target
, level
,
2690 internalFormat
, width
, height
, depth
, border
, imageSize
);
2692 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2693 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2694 internalFormat
, GL_NONE
, GL_NONE
,
2695 width
, height
, depth
, border
);
2698 /* if error, clear all proxy texture image parameters */
2699 if (level
>= 0 && level
< ctx
->Const
.Max3DTextureLevels
) {
2700 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
2704 /* store the teximage parameters */
2705 struct gl_texture_unit
*texUnit
;
2706 struct gl_texture_image
*texImage
;
2707 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2708 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2709 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
,
2710 depth
, border
, internalFormat
);
2714 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3D(target)");
2721 _mesa_CompressedTexSubImage1DARB(GLenum target
, GLint level
, GLint xoffset
,
2722 GLsizei width
, GLenum format
,
2723 GLsizei imageSize
, const GLvoid
*data
)
2725 struct gl_texture_unit
*texUnit
;
2726 struct gl_texture_object
*texObj
;
2727 struct gl_texture_image
*texImage
;
2729 GET_CURRENT_CONTEXT(ctx
);
2730 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2732 error
= compressed_subtexture_error_check(ctx
, 1, target
, level
,
2733 xoffset
, 0, 0, width
, 1, 1, format
, imageSize
);
2735 _mesa_error(ctx
, error
, "glCompressedTexSubImage1D");
2739 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2740 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2741 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2744 if (format
!= texImage
->IntFormat
) {
2745 _mesa_error(ctx
, GL_INVALID_OPERATION
,
2746 "glCompressedTexSubImage1D(format)");
2750 if ((width
== 1 || width
== 2) && width
!= texImage
->Width
) {
2751 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexSubImage1D(width)");
2755 if (width
== 0 || !data
)
2756 return; /* no-op, not an error */
2758 if (ctx
->Driver
.CompressedTexSubImage1D
) {
2759 (*ctx
->Driver
.CompressedTexSubImage1D
)(ctx
, target
, level
,
2761 format
, imageSize
, data
,
2764 ctx
->NewState
|= _NEW_TEXTURE
;
2769 _mesa_CompressedTexSubImage2DARB(GLenum target
, GLint level
, GLint xoffset
,
2770 GLint yoffset
, GLsizei width
, GLsizei height
,
2771 GLenum format
, GLsizei imageSize
,
2774 struct gl_texture_unit
*texUnit
;
2775 struct gl_texture_object
*texObj
;
2776 struct gl_texture_image
*texImage
;
2778 GET_CURRENT_CONTEXT(ctx
);
2779 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2781 error
= compressed_subtexture_error_check(ctx
, 2, target
, level
,
2782 xoffset
, yoffset
, 0, width
, height
, 1, format
, imageSize
);
2784 _mesa_error(ctx
, error
, "glCompressedTexSubImage2D");
2788 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2789 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2790 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2793 if (format
!= texImage
->IntFormat
) {
2794 _mesa_error(ctx
, GL_INVALID_OPERATION
,
2795 "glCompressedTexSubImage2D(format)");
2799 if (((width
== 1 || width
== 2) && width
!= texImage
->Width
) ||
2800 ((height
== 1 || height
== 2) && height
!= texImage
->Height
)) {
2801 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexSubImage2D(size)");
2805 if (width
== 0 || height
== 0 || !data
)
2806 return; /* no-op, not an error */
2808 if (ctx
->Driver
.CompressedTexSubImage2D
) {
2809 (*ctx
->Driver
.CompressedTexSubImage2D
)(ctx
, target
, level
,
2810 xoffset
, yoffset
, width
, height
,
2811 format
, imageSize
, data
,
2814 ctx
->NewState
|= _NEW_TEXTURE
;
2819 _mesa_CompressedTexSubImage3DARB(GLenum target
, GLint level
, GLint xoffset
,
2820 GLint yoffset
, GLint zoffset
, GLsizei width
,
2821 GLsizei height
, GLsizei depth
, GLenum format
,
2822 GLsizei imageSize
, const GLvoid
*data
)
2824 struct gl_texture_unit
*texUnit
;
2825 struct gl_texture_object
*texObj
;
2826 struct gl_texture_image
*texImage
;
2828 GET_CURRENT_CONTEXT(ctx
);
2829 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2831 error
= compressed_subtexture_error_check(ctx
, 3, target
, level
,
2832 xoffset
, yoffset
, zoffset
, width
, height
, depth
, format
, imageSize
);
2834 _mesa_error(ctx
, error
, "glCompressedTexSubImage2D");
2838 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2839 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2840 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2843 if (format
!= texImage
->IntFormat
) {
2844 _mesa_error(ctx
, GL_INVALID_OPERATION
,
2845 "glCompressedTexSubImage3D(format)");
2849 if (((width
== 1 || width
== 2) && width
!= texImage
->Width
) ||
2850 ((height
== 1 || height
== 2) && height
!= texImage
->Height
) ||
2851 ((depth
== 1 || depth
== 2) && depth
!= texImage
->Depth
)) {
2852 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexSubImage3D(size)");
2856 if (width
== 0 || height
== 0 || depth
== 0 || !data
)
2857 return; /* no-op, not an error */
2859 if (ctx
->Driver
.CompressedTexSubImage3D
) {
2860 (*ctx
->Driver
.CompressedTexSubImage3D
)(ctx
, target
, level
,
2861 xoffset
, yoffset
, zoffset
,
2862 width
, height
, depth
,
2863 format
, imageSize
, data
,
2866 ctx
->NewState
|= _NEW_TEXTURE
;
2871 _mesa_GetCompressedTexImageARB(GLenum target
, GLint level
, GLvoid
*img
)
2873 const struct gl_texture_unit
*texUnit
;
2874 const struct gl_texture_object
*texObj
;
2875 struct gl_texture_image
*texImage
;
2877 GET_CURRENT_CONTEXT(ctx
);
2878 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2880 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2881 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2883 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB");
2887 if (target
== GL_TEXTURE_1D
|| target
== GL_TEXTURE_2D
) {
2888 maxLevels
= ctx
->Const
.MaxTextureLevels
;
2890 else if (target
== GL_TEXTURE_3D
) {
2891 maxLevels
= ctx
->Const
.Max3DTextureLevels
;
2894 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
2897 ASSERT(maxLevels
> 0);
2899 if (level
< 0 || level
>= maxLevels
) {
2900 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
2904 if (is_proxy_target(target
)) {
2905 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB(target)");
2909 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2911 /* probably invalid mipmap level */
2912 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
2916 if (!texImage
->IsCompressed
) {
2917 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetCompressedTexImageARB");
2924 /* just memcpy, no pixelstore or pixel transfer */
2925 MEMCPY(img
, texImage
->Data
, texImage
->CompressedSize
);