1 /* $Id: teximage.c,v 1.121 2002/10/18 13:24:08 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 if (ctx
->Extensions
.EXT_paletted_texture
)
216 return GL_COLOR_INDEX
;
219 case GL_DEPTH_COMPONENT
:
220 case GL_DEPTH_COMPONENT16_SGIX
:
221 case GL_DEPTH_COMPONENT24_SGIX
:
222 case GL_DEPTH_COMPONENT32_SGIX
:
223 if (ctx
->Extensions
.SGIX_depth_texture
)
224 return GL_DEPTH_COMPONENT
;
228 /* GL_ARB_texture_compression */
229 case GL_COMPRESSED_ALPHA
:
230 if (ctx
->Extensions
.ARB_texture_compression
)
234 case GL_COMPRESSED_LUMINANCE
:
235 if (ctx
->Extensions
.ARB_texture_compression
)
239 case GL_COMPRESSED_LUMINANCE_ALPHA
:
240 if (ctx
->Extensions
.ARB_texture_compression
)
241 return GL_LUMINANCE_ALPHA
;
244 case GL_COMPRESSED_INTENSITY
:
245 if (ctx
->Extensions
.ARB_texture_compression
)
249 case GL_COMPRESSED_RGB
:
250 if (ctx
->Extensions
.ARB_texture_compression
)
254 case GL_COMPRESSED_RGBA
:
255 if (ctx
->Extensions
.ARB_texture_compression
)
259 case GL_COMPRESSED_RGB_FXT1_3DFX
:
260 if (ctx
->Extensions
.TDFX_texture_compression_FXT1
)
264 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
265 if (ctx
->Extensions
.TDFX_texture_compression_FXT1
)
271 if (ctx
->Extensions
.MESA_ycbcr_texture
)
272 return GL_YCBCR_MESA
;
277 return -1; /* error */
283 * Test if the given image format is a color/rgba format. That is,
284 * not color index, depth, stencil, etc.
287 is_color_format(GLenum format
)
302 case GL_LUMINANCE_ALPHA
:
303 case GL_LUMINANCE4_ALPHA4
:
304 case GL_LUMINANCE6_ALPHA2
:
305 case GL_LUMINANCE8_ALPHA8
:
306 case GL_LUMINANCE12_ALPHA4
:
307 case GL_LUMINANCE12_ALPHA12
:
308 case GL_LUMINANCE16_ALPHA16
:
333 case GL_YCBCR_MESA
: /* not considered to be RGB */
341 is_index_format(GLenum format
)
345 case GL_COLOR_INDEX1_EXT
:
346 case GL_COLOR_INDEX2_EXT
:
347 case GL_COLOR_INDEX4_EXT
:
348 case GL_COLOR_INDEX8_EXT
:
349 case GL_COLOR_INDEX12_EXT
:
350 case GL_COLOR_INDEX16_EXT
:
359 * Return GL_TRUE if internalFormat is a supported compressed format,
360 * return GL_FALSE otherwise.
361 * \param - internalFormat - the internal format token provided by the user
364 is_compressed_format(GLenum internalFormat
)
366 switch (internalFormat
) {
367 case GL_COMPRESSED_RGB_FXT1_3DFX
:
368 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
377 * Store a gl_texture_image pointer in a gl_texture_object structure
378 * according to the target and level parameters.
379 * This was basically prompted by the introduction of cube maps.
382 _mesa_set_tex_image(struct gl_texture_object
*tObj
,
383 GLenum target
, GLint level
,
384 struct gl_texture_image
*texImage
)
392 tObj
->Image
[level
] = texImage
;
394 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
395 tObj
->Image
[level
] = texImage
;
397 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
398 tObj
->NegX
[level
] = texImage
;
400 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
401 tObj
->PosY
[level
] = texImage
;
403 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
404 tObj
->NegY
[level
] = texImage
;
406 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
407 tObj
->PosZ
[level
] = texImage
;
409 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
410 tObj
->NegZ
[level
] = texImage
;
412 case GL_TEXTURE_RECTANGLE_NV
:
414 tObj
->Image
[level
] = texImage
;
417 _mesa_problem(NULL
, "bad target in _mesa_set_tex_image()");
425 * Return new gl_texture_image struct with all fields initialized to zero.
427 struct gl_texture_image
*
428 _mesa_alloc_texture_image( void )
430 return CALLOC_STRUCT(gl_texture_image
);
436 _mesa_free_texture_image( struct gl_texture_image
*teximage
)
438 if (teximage
->Data
&& !teximage
->IsClientData
) {
439 MESA_PBUFFER_FREE( teximage
->Data
);
440 teximage
->Data
= NULL
;
447 * Return GL_TRUE if the target is a proxy target.
450 is_proxy_target(GLenum target
)
452 return (target
== GL_PROXY_TEXTURE_1D
||
453 target
== GL_PROXY_TEXTURE_2D
||
454 target
== GL_PROXY_TEXTURE_3D
||
455 target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
);
460 * Given a texture unit and a texture target, return the corresponding
463 struct gl_texture_object
*
464 _mesa_select_tex_object(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
469 return texUnit
->Current1D
;
470 case GL_PROXY_TEXTURE_1D
:
471 return ctx
->Texture
.Proxy1D
;
473 return texUnit
->Current2D
;
474 case GL_PROXY_TEXTURE_2D
:
475 return ctx
->Texture
.Proxy2D
;
477 return texUnit
->Current3D
;
478 case GL_PROXY_TEXTURE_3D
:
479 return ctx
->Texture
.Proxy3D
;
480 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
481 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
482 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
483 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
484 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
485 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
486 case GL_TEXTURE_CUBE_MAP_ARB
:
487 return ctx
->Extensions
.ARB_texture_cube_map
488 ? texUnit
->CurrentCubeMap
: NULL
;
489 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
490 return ctx
->Extensions
.ARB_texture_cube_map
491 ? ctx
->Texture
.ProxyCubeMap
: NULL
;
492 case GL_TEXTURE_RECTANGLE_NV
:
493 return ctx
->Extensions
.NV_texture_rectangle
494 ? texUnit
->CurrentRect
: NULL
;
495 case GL_PROXY_TEXTURE_RECTANGLE_NV
:
496 return ctx
->Extensions
.NV_texture_rectangle
497 ? ctx
->Texture
.ProxyRect
: NULL
;
499 _mesa_problem(NULL
, "bad target in _mesa_select_tex_object()");
506 * Return the texture image struct which corresponds to target and level
507 * for the given texture unit.
509 struct gl_texture_image
*
510 _mesa_select_tex_image(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
511 GLenum target
, GLint level
)
514 ASSERT(level
< MAX_TEXTURE_LEVELS
);
517 return texUnit
->Current1D
->Image
[level
];
518 case GL_PROXY_TEXTURE_1D
:
519 return ctx
->Texture
.Proxy1D
->Image
[level
];
521 return texUnit
->Current2D
->Image
[level
];
522 case GL_PROXY_TEXTURE_2D
:
523 return ctx
->Texture
.Proxy2D
->Image
[level
];
525 return texUnit
->Current3D
->Image
[level
];
526 case GL_PROXY_TEXTURE_3D
:
527 return ctx
->Texture
.Proxy3D
->Image
[level
];
528 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
529 if (ctx
->Extensions
.ARB_texture_cube_map
)
530 return texUnit
->CurrentCubeMap
->Image
[level
];
533 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
534 if (ctx
->Extensions
.ARB_texture_cube_map
)
535 return texUnit
->CurrentCubeMap
->NegX
[level
];
538 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
539 if (ctx
->Extensions
.ARB_texture_cube_map
)
540 return texUnit
->CurrentCubeMap
->PosY
[level
];
543 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
544 if (ctx
->Extensions
.ARB_texture_cube_map
)
545 return texUnit
->CurrentCubeMap
->NegY
[level
];
548 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
549 if (ctx
->Extensions
.ARB_texture_cube_map
)
550 return texUnit
->CurrentCubeMap
->PosZ
[level
];
553 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
554 if (ctx
->Extensions
.ARB_texture_cube_map
)
555 return texUnit
->CurrentCubeMap
->NegZ
[level
];
558 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
559 if (ctx
->Extensions
.ARB_texture_cube_map
)
560 return ctx
->Texture
.ProxyCubeMap
->Image
[level
];
563 case GL_TEXTURE_RECTANGLE_NV
:
564 if (ctx
->Extensions
.NV_texture_rectangle
) {
566 return texUnit
->CurrentRect
->Image
[level
];
571 case GL_PROXY_TEXTURE_RECTANGLE_NV
:
572 if (ctx
->Extensions
.NV_texture_rectangle
) {
574 return ctx
->Texture
.ProxyRect
->Image
[level
];
580 _mesa_problem(ctx
, "bad target in _mesa_select_tex_image()");
587 #if 000 /* not used anymore */
589 * glTexImage[123]D can accept a NULL image pointer. In this case we
590 * create a texture image with unspecified image contents per the OpenGL
594 make_null_texture(GLint width
, GLint height
, GLint depth
, GLenum format
)
596 const GLint components
= _mesa_components_in_format(format
);
597 const GLint numPixels
= width
* height
* depth
;
598 GLubyte
*data
= (GLubyte
*) MALLOC(numPixels
* components
* sizeof(GLubyte
));
602 * Let's see if anyone finds this. If glTexImage2D() is called with
603 * a NULL image pointer then load the texture image with something
604 * interesting instead of leaving it indeterminate.
607 static const char message
[8][32] = {
611 " X X XXXX XXX XXXXX ",
614 " X X XXXXX XXX X X ",
618 GLubyte
*imgPtr
= data
;
620 for (h
= 0; h
< depth
; h
++) {
621 for (i
= 0; i
< height
; i
++) {
622 GLint srcRow
= 7 - (i
% 8);
623 for (j
= 0; j
< width
; j
++) {
624 GLint srcCol
= j
% 32;
625 GLubyte texel
= (message
[srcRow
][srcCol
]=='X') ? 255 : 70;
626 for (k
= 0; k
< components
; k
++) {
642 * Reset the fields of a gl_texture_image struct to zero.
643 * This is called when a proxy texture test fails, we set all the
644 * image members (except DriverData) to zero.
645 * It's also used in glTexImage[123]D as a safeguard to be sure all
646 * required fields get initialized properly by the Driver.TexImage[123]D
650 clear_teximage_fields(struct gl_texture_image
*img
)
667 img
->TexFormat
= &_mesa_null_texformat
;
668 img
->FetchTexel
= NULL
;
669 img
->IsCompressed
= 0;
670 img
->CompressedSize
= 0;
675 * Initialize basic fields of the gl_texture_image struct.
678 _mesa_init_teximage_fields(GLcontext
*ctx
, GLenum target
,
679 struct gl_texture_image
*img
,
680 GLsizei width
, GLsizei height
, GLsizei depth
,
681 GLint border
, GLenum internalFormat
)
684 img
->Format
= _mesa_base_tex_format( ctx
, internalFormat
);
685 ASSERT(img
->Format
> 0);
686 img
->IntFormat
= internalFormat
;
687 img
->Border
= border
;
689 img
->Height
= height
;
691 img
->RowStride
= width
;
692 img
->WidthLog2
= logbase2(width
- 2 * border
);
693 if (height
== 1) /* 1-D texture */
696 img
->HeightLog2
= logbase2(height
- 2 * border
);
697 if (depth
== 1) /* 2-D texture */
700 img
->DepthLog2
= logbase2(depth
- 2 * border
);
701 img
->Width2
= 1 << img
->WidthLog2
;
702 img
->Height2
= 1 << img
->HeightLog2
;
703 img
->Depth2
= 1 << img
->DepthLog2
;
704 img
->MaxLog2
= MAX2(img
->WidthLog2
, img
->HeightLog2
);
705 img
->IsCompressed
= is_compressed_format(internalFormat
);
706 if (img
->IsCompressed
)
707 img
->CompressedSize
= _mesa_compressed_texture_size(ctx
, width
, height
,
708 depth
, internalFormat
);
710 img
->CompressedSize
= 0;
712 /* Compute Width/Height/DepthScale for mipmap lod computation */
713 if (target
== GL_TEXTURE_RECTANGLE_NV
) {
714 /* scale = 1.0 since texture coords directly map to texels */
715 img
->WidthScale
= 1.0;
716 img
->HeightScale
= 1.0;
717 img
->DepthScale
= 1.0;
720 img
->WidthScale
= (GLfloat
) img
->Width
;
721 img
->HeightScale
= (GLfloat
) img
->Height
;
722 img
->DepthScale
= (GLfloat
) img
->Depth
;
729 * Test glTexImage[123]D() parameters for errors.
731 * dimensions - must be 1 or 2 or 3
732 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
735 texture_error_check( GLcontext
*ctx
, GLenum target
,
736 GLint level
, GLint internalFormat
,
737 GLenum format
, GLenum type
,
739 GLint width
, GLint height
,
740 GLint depth
, GLint border
)
743 GLint maxLevels
= 0, maxTextureSize
;
745 if (dimensions
== 1) {
746 if (target
== GL_PROXY_TEXTURE_1D
) {
749 else if (target
== GL_TEXTURE_1D
) {
753 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
756 maxLevels
= ctx
->Const
.MaxTextureLevels
;
758 else if (dimensions
== 2) {
759 if (target
== GL_PROXY_TEXTURE_2D
) {
761 maxLevels
= ctx
->Const
.MaxTextureLevels
;
763 else if (target
== GL_TEXTURE_2D
) {
765 maxLevels
= ctx
->Const
.MaxTextureLevels
;
767 else if (target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
) {
768 if (!ctx
->Extensions
.ARB_texture_cube_map
) {
769 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
773 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
775 else if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
776 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
777 if (!ctx
->Extensions
.ARB_texture_cube_map
) {
778 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
782 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
784 else if (target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) {
785 if (!ctx
->Extensions
.NV_texture_rectangle
) {
786 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
792 else if (target
== GL_TEXTURE_RECTANGLE_NV
) {
793 if (!ctx
->Extensions
.NV_texture_rectangle
) {
794 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
801 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
805 else if (dimensions
== 3) {
806 if (target
== GL_PROXY_TEXTURE_3D
) {
809 else if (target
== GL_TEXTURE_3D
) {
813 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
816 maxLevels
= ctx
->Const
.Max3DTextureLevels
;
819 _mesa_problem( ctx
, "bad dims in texture_error_check" );
823 ASSERT(maxLevels
> 0);
824 maxTextureSize
= 1 << (maxLevels
- 1);
827 if (border
!= 0 && border
!= 1) {
829 _mesa_error(ctx
, GL_INVALID_VALUE
,
830 "glTexImage%dD(border=%d)", dimensions
, border
);
834 if ((target
== GL_TEXTURE_RECTANGLE_NV
||
835 target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) && border
!= 0) {
840 if (target
== GL_TEXTURE_RECTANGLE_NV
||
841 target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) {
842 if (width
< 1 || width
> ctx
->Const
.MaxTextureRectSize
) {
844 _mesa_error(ctx
, GL_INVALID_VALUE
,
845 "glTexImage%dD(width=%d)", dimensions
, width
);
850 else if (width
< 2 * border
|| width
> 2 + maxTextureSize
851 || logbase2( width
- 2 * border
) < 0) {
853 _mesa_error(ctx
, GL_INVALID_VALUE
,
854 "glTexImage%dD(width=%d)", dimensions
, width
);
860 if (target
== GL_TEXTURE_RECTANGLE_NV
||
861 target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) {
862 if (height
< 1 || height
> ctx
->Const
.MaxTextureRectSize
) {
864 _mesa_error(ctx
, GL_INVALID_VALUE
,
865 "glTexImage%dD(height=%d)", dimensions
, height
);
870 else if (dimensions
>= 2) {
871 if (height
< 2 * border
|| height
> 2 + maxTextureSize
872 || logbase2( height
- 2 * border
) < 0) {
874 _mesa_error(ctx
, GL_INVALID_VALUE
,
875 "glTexImage%dD(height=%d)", dimensions
, height
);
881 /* For cube map, width must equal height */
882 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
883 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
884 if (width
!= height
) {
886 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
893 if (dimensions
>= 3) {
894 if (depth
< 2 * border
|| depth
> 2 + maxTextureSize
895 || logbase2( depth
- 2 * border
) < 0) {
897 _mesa_error( ctx
, GL_INVALID_VALUE
,
898 "glTexImage3D(depth=%d)", depth
);
905 if (target
== GL_TEXTURE_RECTANGLE_NV
||
906 target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) {
909 _mesa_error(ctx
, GL_INVALID_VALUE
,
910 "glTexImage2D(level=%d)", level
);
915 else if (level
< 0 || level
>= maxLevels
) {
917 _mesa_error(ctx
, GL_INVALID_VALUE
,
918 "glTexImage%dD(level=%d)", dimensions
, level
);
923 /* For cube map, width must equal height */
924 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
925 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
926 if (width
!= height
) {
927 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
932 if (_mesa_base_tex_format(ctx
, internalFormat
) < 0) {
934 _mesa_error(ctx
, GL_INVALID_VALUE
,
935 "glTexImage%dD(internalFormat=0x%x)",
936 dimensions
, internalFormat
);
941 if (!_mesa_is_legal_format_and_type(format
, type
)) {
942 /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
943 * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
946 _mesa_error(ctx
, GL_INVALID_OPERATION
,
947 "glTexImage%dD(format or type)", dimensions
);
952 if (format
== GL_YCBCR_MESA
|| internalFormat
== GL_YCBCR_MESA
) {
953 ASSERT(ctx
->Extensions
.MESA_ycbcr_texture
);
954 if (format
!= GL_YCBCR_MESA
||
955 internalFormat
!= GL_YCBCR_MESA
||
956 (type
!= GL_UNSIGNED_SHORT_8_8_MESA
&&
957 type
!= GL_UNSIGNED_SHORT_8_8_REV_MESA
)) {
960 "glTexImage%d(format/type/internalFormat YCBCR mismatch",
962 _mesa_error(ctx
, GL_INVALID_ENUM
, message
);
963 return GL_TRUE
; /* error */
965 if (target
!= GL_TEXTURE_2D
&&
966 target
!= GL_PROXY_TEXTURE_2D
&&
967 target
!= GL_TEXTURE_RECTANGLE_NV
&&
968 target
!= GL_PROXY_TEXTURE_RECTANGLE_NV
) {
970 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage(target)");
977 "glTexImage%d(format=GL_YCBCR_MESA and border=%d)",
979 _mesa_error(ctx
, GL_INVALID_VALUE
, message
);
985 if (is_compressed_format(internalFormat
)) {
986 if (target
== GL_TEXTURE_2D
|| target
== GL_PROXY_TEXTURE_2D
) {
989 else if (ctx
->Extensions
.ARB_texture_cube_map
&&
990 (target
== GL_PROXY_TEXTURE_CUBE_MAP
||
991 (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X
&&
992 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
))) {
997 _mesa_error(ctx
, GL_INVALID_ENUM
,
998 "glTexImage%d(target)", dimensions
);
1004 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1005 "glTexImage%D(border!=0)", dimensions
);
1011 /* if we get here, the parameters are OK */
1018 * Test glTexSubImage[123]D() parameters for errors.
1020 * dimensions - must be 1 or 2 or 3
1021 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
1024 subtexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
1025 GLenum target
, GLint level
,
1026 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1027 GLint width
, GLint height
, GLint depth
,
1028 GLenum format
, GLenum type
)
1030 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1031 struct gl_texture_image
*destTex
;
1032 GLint maxLevels
= 0;
1034 if (dimensions
== 1) {
1035 if (target
== GL_TEXTURE_1D
) {
1036 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1039 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(target)" );
1043 else if (dimensions
== 2) {
1044 if (ctx
->Extensions
.ARB_texture_cube_map
&&
1045 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1046 target
<=GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
1047 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
1049 else if (ctx
->Extensions
.NV_texture_rectangle
&&
1050 target
== GL_TEXTURE_RECTANGLE_NV
) {
1053 else if (target
== GL_TEXTURE_2D
) {
1054 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1057 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
1061 else if (dimensions
== 3) {
1062 if (target
== GL_TEXTURE_3D
) {
1063 maxLevels
= ctx
->Const
.Max3DTextureLevels
;
1066 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3D(target)" );
1071 _mesa_problem( ctx
, "bad dims in texture_error_check" );
1075 ASSERT(maxLevels
> 0);
1077 if (level
< 0 || level
>= maxLevels
) {
1078 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(level=%d)", level
);
1083 _mesa_error(ctx
, GL_INVALID_VALUE
,
1084 "glTexSubImage%dD(width=%d)", dimensions
, width
);
1087 if (height
< 0 && dimensions
> 1) {
1088 _mesa_error(ctx
, GL_INVALID_VALUE
,
1089 "glTexSubImage%dD(height=%d)", dimensions
, height
);
1092 if (depth
< 0 && dimensions
> 2) {
1093 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage%dD(depth=%d)", dimensions
, depth
);
1097 destTex
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1100 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glTexSubImage2D");
1104 if (xoffset
< -((GLint
)destTex
->Border
)) {
1105 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset)");
1108 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
1109 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset+width)");
1112 if (dimensions
> 1) {
1113 if (yoffset
< -((GLint
)destTex
->Border
)) {
1114 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset)");
1117 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
1118 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset+height)");
1122 if (dimensions
> 2) {
1123 if (zoffset
< -((GLint
)destTex
->Border
)) {
1124 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset)");
1127 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+ destTex
->Border
)) {
1128 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset+depth)");
1133 if (!_mesa_is_legal_format_and_type(format
, type
)) {
1134 _mesa_error(ctx
, GL_INVALID_ENUM
,
1135 "glTexSubImage%dD(format or type)", dimensions
);
1139 if (destTex
->IsCompressed
) {
1140 const struct gl_texture_unit
*texUnit
;
1141 const struct gl_texture_object
*texObj
;
1142 const struct gl_texture_image
*texImage
;
1143 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1144 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1145 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1147 if (target
== GL_TEXTURE_2D
|| target
== GL_PROXY_TEXTURE_2D
) {
1150 else if (ctx
->Extensions
.ARB_texture_cube_map
&&
1151 (target
== GL_PROXY_TEXTURE_CUBE_MAP
||
1152 (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X
&&
1153 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
))) {
1157 _mesa_error(ctx
, GL_INVALID_ENUM
,
1158 "glTexSubImage%D(target)", dimensions
);
1161 /* offset must be multiple of 4 */
1162 if ((xoffset
& 3) || (yoffset
& 3)) {
1163 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1164 "glTexSubImage%D(xoffset or yoffset)", dimensions
);
1167 /* size must be multiple of 4 or equal to whole texture size */
1168 if ((width
& 3) && (GLuint
) width
!= texImage
->Width
) {
1169 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1170 "glTexSubImage%D(width)", dimensions
);
1173 if ((height
& 3) && (GLuint
) height
!= texImage
->Height
) {
1174 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1175 "glTexSubImage%D(width)", dimensions
);
1185 * Test glCopyTexImage[12]D() parameters for errors.
1186 * Input: dimensions - must be 1 or 2 or 3
1187 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
1190 copytexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
1191 GLenum target
, GLint level
, GLint internalFormat
,
1192 GLint width
, GLint height
, GLint border
)
1194 GLint maxLevels
= 0, maxTextureSize
;
1196 if (dimensions
== 1) {
1197 if (target
!= GL_TEXTURE_1D
) {
1198 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
1201 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1203 else if (dimensions
== 2) {
1204 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1205 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
1206 if (!ctx
->Extensions
.ARB_texture_cube_map
) {
1207 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1211 else if (target
== GL_TEXTURE_RECTANGLE_NV
) {
1212 if (!ctx
->Extensions
.NV_texture_rectangle
) {
1213 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1217 else if (target
!= GL_TEXTURE_2D
) {
1218 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1221 if (target
== GL_TEXTURE_2D
)
1222 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1223 else if (target
== GL_TEXTURE_RECTANGLE_NV
)
1226 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
1229 ASSERT(maxLevels
> 0);
1230 maxTextureSize
= 1 << (maxLevels
- 1);
1233 if (border
!= 0 && border
!= 1) {
1234 _mesa_error(ctx
, GL_INVALID_VALUE
,
1235 "glCopyTexImage%dD(border)", dimensions
);
1240 if (width
< 2 * border
|| width
> 2 + maxTextureSize
1241 || logbase2( width
- 2 * border
) < 0) {
1242 _mesa_error(ctx
, GL_INVALID_VALUE
,
1243 "glCopyTexImage%dD(width=%d)", dimensions
, width
);
1248 if (dimensions
>= 2) {
1249 if (height
< 2 * border
|| height
> 2 + maxTextureSize
1250 || logbase2( height
- 2 * border
) < 0) {
1251 _mesa_error(ctx
, GL_INVALID_VALUE
,
1252 "glCopyTexImage%dD(height=%d)", dimensions
, height
);
1257 /* For cube map, width must equal height */
1258 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1259 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
1260 if (width
!= height
) {
1261 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(width != height)");
1267 if (level
< 0 || level
>= maxLevels
) {
1268 _mesa_error(ctx
, GL_INVALID_VALUE
,
1269 "glCopyTexImage%dD(level=%d)", dimensions
, level
);
1273 if (_mesa_base_tex_format(ctx
, internalFormat
) < 0) {
1274 _mesa_error(ctx
, GL_INVALID_VALUE
,
1275 "glCopyTexImage%dD(internalFormat)", dimensions
);
1279 if (is_compressed_format(internalFormat
)) {
1280 if (target
!= GL_TEXTURE_2D
) {
1281 _mesa_error(ctx
, GL_INVALID_ENUM
,
1282 "glCopyTexImage%d(target)", dimensions
);
1286 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1287 "glCopyTexImage%D(border!=0)", dimensions
);
1292 /* if we get here, the parameters are OK */
1298 copytexsubimage_error_check( GLcontext
*ctx
, GLuint dimensions
,
1299 GLenum target
, GLint level
,
1300 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1301 GLsizei width
, GLsizei height
)
1303 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1304 struct gl_texture_image
*teximage
;
1305 GLint maxLevels
= 0;
1307 if (dimensions
== 1) {
1308 if (target
!= GL_TEXTURE_1D
) {
1309 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
1312 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1314 else if (dimensions
== 2) {
1315 if (ctx
->Extensions
.ARB_texture_cube_map
) {
1316 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1317 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1318 target
!= GL_TEXTURE_2D
) {
1319 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1323 else if (target
!= GL_TEXTURE_2D
) {
1324 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1327 if (target
== GL_PROXY_TEXTURE_2D
&& target
== GL_TEXTURE_2D
)
1328 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1330 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
1332 else if (dimensions
== 3) {
1333 if (target
!= GL_TEXTURE_3D
) {
1334 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3D(target)" );
1337 maxLevels
= ctx
->Const
.Max3DTextureLevels
;
1340 ASSERT(maxLevels
> 0);
1342 if (level
< 0 || level
>= maxLevels
) {
1343 _mesa_error(ctx
, GL_INVALID_VALUE
,
1344 "glCopyTexSubImage%dD(level=%d)", dimensions
, level
);
1349 _mesa_error(ctx
, GL_INVALID_VALUE
,
1350 "glCopyTexSubImage%dD(width=%d)", dimensions
, width
);
1353 if (dimensions
> 1 && height
< 0) {
1354 _mesa_error(ctx
, GL_INVALID_VALUE
,
1355 "glCopyTexSubImage%dD(height=%d)", dimensions
, height
);
1359 teximage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1361 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1362 "glCopyTexSubImage%dD(undefined texture level: %d)",
1367 if (xoffset
< -((GLint
)teximage
->Border
)) {
1368 _mesa_error(ctx
, GL_INVALID_VALUE
,
1369 "glCopyTexSubImage%dD(xoffset=%d)", dimensions
, xoffset
);
1372 if (xoffset
+ width
> (GLint
) (teximage
->Width
+ teximage
->Border
)) {
1373 _mesa_error(ctx
, GL_INVALID_VALUE
,
1374 "glCopyTexSubImage%dD(xoffset+width)", dimensions
);
1377 if (dimensions
> 1) {
1378 if (yoffset
< -((GLint
)teximage
->Border
)) {
1379 _mesa_error(ctx
, GL_INVALID_VALUE
,
1380 "glCopyTexSubImage%dD(yoffset=%d)", dimensions
, yoffset
);
1383 /* NOTE: we're adding the border here, not subtracting! */
1384 if (yoffset
+ height
> (GLint
) (teximage
->Height
+ teximage
->Border
)) {
1385 _mesa_error(ctx
, GL_INVALID_VALUE
,
1386 "glCopyTexSubImage%dD(yoffset+height)", dimensions
);
1391 if (dimensions
> 2) {
1392 if (zoffset
< -((GLint
)teximage
->Border
)) {
1393 _mesa_error(ctx
, GL_INVALID_VALUE
,
1394 "glCopyTexSubImage%dD(zoffset)", dimensions
);
1397 if (zoffset
> (GLint
) (teximage
->Depth
+ teximage
->Border
)) {
1398 _mesa_error(ctx
, GL_INVALID_VALUE
,
1399 "glCopyTexSubImage%dD(zoffset+depth)", dimensions
);
1404 if (teximage
->IsCompressed
) {
1405 if (target
!= GL_TEXTURE_2D
) {
1406 _mesa_error(ctx
, GL_INVALID_ENUM
,
1407 "glCopyTexSubImage%d(target)", dimensions
);
1410 /* offset must be multiple of 4 */
1411 if ((xoffset
& 3) || (yoffset
& 3)) {
1412 _mesa_error(ctx
, GL_INVALID_VALUE
,
1413 "glCopyTexSubImage%D(xoffset or yoffset)", dimensions
);
1416 /* size must be multiple of 4 */
1417 if ((width
& 3) != 0 && (GLuint
) width
!= teximage
->Width
) {
1418 _mesa_error(ctx
, GL_INVALID_VALUE
,
1419 "glCopyTexSubImage%D(width)", dimensions
);
1422 if ((height
& 3) != 0 && (GLuint
) height
!= teximage
->Height
) {
1423 _mesa_error(ctx
, GL_INVALID_VALUE
,
1424 "glCopyTexSubImage%D(height)", dimensions
);
1429 if (teximage
->IntFormat
== GL_YCBCR_MESA
) {
1430 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glCopyTexSubImage2D");
1434 /* if we get here, the parameters are OK */
1441 _mesa_GetTexImage( GLenum target
, GLint level
, GLenum format
,
1442 GLenum type
, GLvoid
*pixels
)
1444 const struct gl_texture_unit
*texUnit
;
1445 const struct gl_texture_object
*texObj
;
1446 const struct gl_texture_image
*texImage
;
1447 GLint maxLevels
= 0;
1448 GET_CURRENT_CONTEXT(ctx
);
1449 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1451 texUnit
= &(ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
]);
1452 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1453 if (!texObj
|| is_proxy_target(target
)) {
1454 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)");
1458 if (target
== GL_TEXTURE_1D
|| target
== GL_TEXTURE_2D
) {
1459 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1461 else if (target
== GL_TEXTURE_3D
) {
1462 maxLevels
= ctx
->Const
.Max3DTextureLevels
;
1464 else if (target
== GL_TEXTURE_RECTANGLE_NV
) {
1468 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
1471 ASSERT(maxLevels
> 0);
1473 if (level
< 0 || level
>= maxLevels
) {
1474 _mesa_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
1478 if (_mesa_sizeof_packed_type(type
) <= 0) {
1479 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
1483 if (_mesa_components_in_format(format
) <= 0 ||
1484 format
== GL_STENCIL_INDEX
) {
1485 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
1489 if (!ctx
->Extensions
.EXT_paletted_texture
&& is_index_format(format
)) {
1490 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1493 if (!ctx
->Extensions
.SGIX_depth_texture
&& format
== GL_DEPTH_COMPONENT
) {
1494 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1497 if (!ctx
->Extensions
.MESA_ycbcr_texture
&& format
== GL_YCBCR_MESA
) {
1498 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1501 /* XXX what if format/type doesn't match texture format/type? */
1506 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1508 /* invalid mipmap level, not an error */
1512 if (!texImage
->Data
) {
1513 /* no image data, not an error */
1518 const GLint width
= texImage
->Width
;
1519 const GLint height
= texImage
->Height
;
1520 const GLint depth
= texImage
->Depth
;
1522 for (img
= 0; img
< depth
; img
++) {
1523 for (row
= 0; row
< height
; row
++) {
1524 /* compute destination address in client memory */
1525 GLvoid
*dest
= _mesa_image_address( &ctx
->Pack
, pixels
,
1526 width
, height
, format
, type
,
1530 if (format
== GL_COLOR_INDEX
) {
1531 GLuint indexRow
[MAX_WIDTH
];
1533 for (col
= 0; col
< width
; col
++) {
1534 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1535 (GLvoid
*) &indexRow
[col
]);
1537 _mesa_pack_index_span(ctx
, width
, type
, dest
,
1538 indexRow
, &ctx
->Pack
,
1539 0 /* no image transfer */);
1541 else if (format
== GL_DEPTH_COMPONENT
) {
1542 GLfloat depthRow
[MAX_WIDTH
];
1544 for (col
= 0; col
< width
; col
++) {
1545 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1546 (GLvoid
*) &depthRow
[col
]);
1548 _mesa_pack_depth_span(ctx
, width
, dest
, type
,
1549 depthRow
, &ctx
->Pack
);
1551 else if (format
== GL_YCBCR_MESA
) {
1552 /* No pixel transfer */
1553 const GLint rowstride
= texImage
->RowStride
;
1555 (const GLushort
*) texImage
->Data
+ row
* rowstride
,
1556 width
* sizeof(GLushort
));
1557 /* check for byte swapping */
1558 if ((texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_YCBCR
1559 && type
== GL_UNSIGNED_SHORT_8_8_REV_MESA
) ||
1560 (texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_YCBCR_REV
1561 && type
== GL_UNSIGNED_SHORT_8_8_MESA
)) {
1562 if (!ctx
->Pack
.SwapBytes
)
1563 _mesa_swap2((GLushort
*) dest
, width
);
1565 else if (ctx
->Pack
.SwapBytes
) {
1566 _mesa_swap2((GLushort
*) dest
, width
);
1570 /* general case: convert row to RGBA format */
1571 GLchan rgba
[MAX_WIDTH
][4];
1573 for (col
= 0; col
< width
; col
++) {
1574 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1575 (GLvoid
*) rgba
[col
]);
1577 _mesa_pack_rgba_span(ctx
, width
, (const GLchan (*)[4])rgba
,
1578 format
, type
, dest
, &ctx
->Pack
,
1579 0 /* no image transfer */);
1589 * Called from the API. Note that width includes the border.
1592 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
1593 GLsizei width
, GLint border
, GLenum format
,
1594 GLenum type
, const GLvoid
*pixels
)
1596 GLsizei postConvWidth
= width
;
1597 GET_CURRENT_CONTEXT(ctx
);
1598 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1600 if (is_color_format(internalFormat
)) {
1601 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1604 if (target
== GL_TEXTURE_1D
) {
1605 struct gl_texture_unit
*texUnit
;
1606 struct gl_texture_object
*texObj
;
1607 struct gl_texture_image
*texImage
;
1609 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1610 format
, type
, 1, postConvWidth
, 1, 1, border
)) {
1611 return; /* error was recorded */
1614 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1615 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1616 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1619 texImage
= _mesa_alloc_texture_image();
1620 texObj
->Image
[level
] = texImage
;
1622 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
1626 else if (texImage
->Data
&& !texImage
->IsClientData
) {
1627 /* free the old texture data */
1628 MESA_PBUFFER_FREE(texImage
->Data
);
1630 texImage
->Data
= NULL
;
1631 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1632 _mesa_init_teximage_fields(ctx
, target
, texImage
,
1633 postConvWidth
, 1, 1,
1634 border
, internalFormat
);
1636 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1637 _mesa_update_state(ctx
);
1639 ASSERT(ctx
->Driver
.TexImage1D
);
1641 /* Give the texture to the driver! <pixels> may be null! */
1642 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1643 width
, border
, format
, type
, pixels
,
1644 &ctx
->Unpack
, texObj
, texImage
);
1646 ASSERT(texImage
->TexFormat
);
1647 if (!texImage
->FetchTexel
) {
1648 /* If driver didn't explicitly set this, use the default */
1649 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel1D
;
1651 ASSERT(texImage
->FetchTexel
);
1654 texObj
->Complete
= GL_FALSE
;
1655 ctx
->NewState
|= _NEW_TEXTURE
;
1657 else if (target
== GL_PROXY_TEXTURE_1D
) {
1658 /* Proxy texture: check for errors and update proxy state */
1659 GLboolean error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1660 format
, type
, 1, postConvWidth
, 1, 1, border
);
1662 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1663 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1664 internalFormat
, format
, type
,
1665 postConvWidth
, 1, 1, border
);
1668 /* if error, clear all proxy texture image parameters */
1669 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1670 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
1674 /* no error, set the tex image parameters */
1675 struct gl_texture_unit
*texUnit
;
1676 struct gl_texture_image
*texImage
;
1677 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1678 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1679 _mesa_init_teximage_fields(ctx
, target
, texImage
,
1680 postConvWidth
, 1, 1,
1681 border
, internalFormat
);
1685 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1692 _mesa_TexImage2D( GLenum target
, GLint level
, GLint internalFormat
,
1693 GLsizei width
, GLsizei height
, GLint border
,
1694 GLenum format
, GLenum type
,
1695 const GLvoid
*pixels
)
1697 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1698 GET_CURRENT_CONTEXT(ctx
);
1699 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1701 if (is_color_format(internalFormat
)) {
1702 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1706 if (target
== GL_TEXTURE_2D
||
1707 (ctx
->Extensions
.ARB_texture_cube_map
&&
1708 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1709 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) ||
1710 (ctx
->Extensions
.NV_texture_rectangle
&&
1711 target
== GL_TEXTURE_RECTANGLE_NV
)) {
1712 /* non-proxy target */
1713 struct gl_texture_unit
*texUnit
;
1714 struct gl_texture_object
*texObj
;
1715 struct gl_texture_image
*texImage
;
1717 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1718 format
, type
, 2, postConvWidth
, postConvHeight
,
1720 return; /* error was recorded */
1723 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1724 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1725 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1728 texImage
= _mesa_alloc_texture_image();
1729 _mesa_set_tex_image(texObj
, target
, level
, texImage
);
1731 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1735 else if (texImage
->Data
&& !texImage
->IsClientData
) {
1736 /* free the old texture data */
1737 MESA_PBUFFER_FREE(texImage
->Data
);
1739 texImage
->Data
= NULL
;
1740 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1741 _mesa_init_teximage_fields(ctx
, target
, texImage
,
1742 postConvWidth
, postConvHeight
, 1,
1743 border
, internalFormat
);
1745 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1746 _mesa_update_state(ctx
);
1748 ASSERT(ctx
->Driver
.TexImage2D
);
1750 /* Give the texture to the driver! <pixels> may be null! */
1751 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1752 width
, height
, border
, format
, type
, pixels
,
1753 &ctx
->Unpack
, texObj
, texImage
);
1755 ASSERT(texImage
->TexFormat
);
1756 if (!texImage
->FetchTexel
) {
1757 /* If driver didn't explicitly set this, use the default */
1758 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel2D
;
1760 ASSERT(texImage
->FetchTexel
);
1763 texObj
->Complete
= GL_FALSE
;
1764 ctx
->NewState
|= _NEW_TEXTURE
;
1766 else if (target
== GL_PROXY_TEXTURE_2D
||
1767 (target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
&&
1768 ctx
->Extensions
.ARB_texture_cube_map
) ||
1769 (target
== GL_PROXY_TEXTURE_RECTANGLE_NV
&&
1770 ctx
->Extensions
.NV_texture_rectangle
)) {
1771 /* Proxy texture: check for errors and update proxy state */
1772 GLboolean error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1773 format
, type
, 2, postConvWidth
, postConvHeight
, 1, border
);
1775 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1776 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1777 internalFormat
, format
, type
,
1778 postConvWidth
, postConvHeight
, 1, border
);
1781 /* if error, clear all proxy texture image parameters */
1782 const GLint maxLevels
= (target
== GL_PROXY_TEXTURE_2D
) ?
1783 ctx
->Const
.MaxTextureLevels
: ctx
->Const
.MaxCubeTextureLevels
;
1784 if (level
>= 0 && level
< maxLevels
) {
1785 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
1789 /* no error, set the tex image parameters */
1790 struct gl_texture_unit
*texUnit
;
1791 struct gl_texture_image
*texImage
;
1792 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1793 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1794 _mesa_init_teximage_fields(ctx
, target
, texImage
,
1795 postConvWidth
, postConvHeight
, 1,
1796 border
, internalFormat
);
1800 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1807 * Called by the API or display list executor.
1808 * Note that width and height include the border.
1811 _mesa_TexImage3D( GLenum target
, GLint level
, GLint internalFormat
,
1812 GLsizei width
, GLsizei height
, GLsizei depth
,
1813 GLint border
, GLenum format
, GLenum type
,
1814 const GLvoid
*pixels
)
1816 GET_CURRENT_CONTEXT(ctx
);
1817 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1819 if (target
== GL_TEXTURE_3D
) {
1820 struct gl_texture_unit
*texUnit
;
1821 struct gl_texture_object
*texObj
;
1822 struct gl_texture_image
*texImage
;
1824 if (texture_error_check(ctx
, target
, level
, (GLint
) internalFormat
,
1825 format
, type
, 3, width
, height
, depth
, border
)) {
1826 return; /* error was recorded */
1829 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1830 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1831 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1834 texImage
= _mesa_alloc_texture_image();
1835 texObj
->Image
[level
] = texImage
;
1837 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
1841 else if (texImage
->Data
&& !texImage
->IsClientData
) {
1842 MESA_PBUFFER_FREE(texImage
->Data
);
1844 texImage
->Data
= NULL
;
1845 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1846 _mesa_init_teximage_fields(ctx
, target
, texImage
,
1847 width
, height
, depth
,
1848 border
, internalFormat
);
1850 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1851 _mesa_update_state(ctx
);
1853 ASSERT(ctx
->Driver
.TexImage3D
);
1855 /* Give the texture to the driver! <pixels> may be null! */
1856 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, internalFormat
,
1857 width
, height
, depth
, border
, format
, type
,
1858 pixels
, &ctx
->Unpack
, texObj
, texImage
);
1860 ASSERT(texImage
->TexFormat
);
1861 if (!texImage
->FetchTexel
) {
1862 /* If driver didn't explicitly set this, use the default */
1863 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel3D
;
1865 ASSERT(texImage
->FetchTexel
);
1868 texObj
->Complete
= GL_FALSE
;
1869 ctx
->NewState
|= _NEW_TEXTURE
;
1871 else if (target
== GL_PROXY_TEXTURE_3D
) {
1872 /* Proxy texture: check for errors and update proxy state */
1873 GLboolean error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1874 format
, type
, 3, width
, height
, depth
, border
);
1876 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1877 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1878 internalFormat
, format
, type
,
1879 width
, height
, depth
, border
);
1882 /* if error, clear all proxy texture image parameters */
1883 if (level
>= 0 && level
< ctx
->Const
.Max3DTextureLevels
) {
1884 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
1888 /* no error, set the tex image parameters */
1889 struct gl_texture_unit
*texUnit
;
1890 struct gl_texture_image
*texImage
;
1891 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1892 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1893 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
, 1,
1894 border
, internalFormat
);
1898 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1905 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
1906 GLsizei width
, GLsizei height
, GLsizei depth
,
1907 GLint border
, GLenum format
, GLenum type
,
1908 const GLvoid
*pixels
)
1910 _mesa_TexImage3D(target
, level
, (GLint
) internalFormat
, width
, height
,
1911 depth
, border
, format
, type
, pixels
);
1917 _mesa_TexSubImage1D( GLenum target
, GLint level
,
1918 GLint xoffset
, GLsizei width
,
1919 GLenum format
, GLenum type
,
1920 const GLvoid
*pixels
)
1922 GLsizei postConvWidth
= width
;
1923 struct gl_texture_unit
*texUnit
;
1924 struct gl_texture_object
*texObj
;
1925 struct gl_texture_image
*texImage
;
1926 GET_CURRENT_CONTEXT(ctx
);
1927 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1929 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1930 _mesa_update_state(ctx
);
1932 /* XXX should test internal format */
1933 if (is_color_format(format
)) {
1934 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1937 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
1938 postConvWidth
, 1, 1, format
, type
)) {
1939 return; /* error was detected */
1942 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1943 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1944 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1947 if (width
== 0 || !pixels
)
1948 return; /* no-op, not an error */
1950 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1951 xoffset
+= texImage
->Border
;
1953 ASSERT(ctx
->Driver
.TexSubImage1D
);
1954 (*ctx
->Driver
.TexSubImage1D
)(ctx
, target
, level
, xoffset
, width
,
1955 format
, type
, pixels
, &ctx
->Unpack
,
1957 ctx
->NewState
|= _NEW_TEXTURE
;
1962 _mesa_TexSubImage2D( GLenum target
, GLint level
,
1963 GLint xoffset
, GLint yoffset
,
1964 GLsizei width
, GLsizei height
,
1965 GLenum format
, GLenum type
,
1966 const GLvoid
*pixels
)
1968 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1969 struct gl_texture_unit
*texUnit
;
1970 struct gl_texture_object
*texObj
;
1971 struct gl_texture_image
*texImage
;
1972 GET_CURRENT_CONTEXT(ctx
);
1973 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1975 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1976 _mesa_update_state(ctx
);
1978 /* XXX should test internal format */
1979 if (is_color_format(format
)) {
1980 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1984 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1985 postConvWidth
, postConvHeight
, 1, format
, type
)) {
1986 return; /* error was detected */
1989 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1990 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1991 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1994 if (width
== 0 || height
== 0 || !pixels
)
1995 return; /* no-op, not an error */
1997 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1998 xoffset
+= texImage
->Border
;
1999 yoffset
+= texImage
->Border
;
2001 ASSERT(ctx
->Driver
.TexSubImage2D
);
2002 (*ctx
->Driver
.TexSubImage2D
)(ctx
, target
, level
, xoffset
, yoffset
,
2003 width
, height
, format
, type
, pixels
,
2004 &ctx
->Unpack
, texObj
, texImage
);
2005 ctx
->NewState
|= _NEW_TEXTURE
;
2011 _mesa_TexSubImage3D( GLenum target
, GLint level
,
2012 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2013 GLsizei width
, GLsizei height
, GLsizei depth
,
2014 GLenum format
, GLenum type
,
2015 const GLvoid
*pixels
)
2017 struct gl_texture_unit
*texUnit
;
2018 struct gl_texture_object
*texObj
;
2019 struct gl_texture_image
*texImage
;
2020 GET_CURRENT_CONTEXT(ctx
);
2021 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2023 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2024 _mesa_update_state(ctx
);
2026 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2027 width
, height
, depth
, format
, type
)) {
2028 return; /* error was detected */
2031 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2032 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2033 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2036 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
2037 return; /* no-op, not an error */
2039 /* If we have a border, xoffset=-1 is legal. Bias by border width */
2040 xoffset
+= texImage
->Border
;
2041 yoffset
+= texImage
->Border
;
2042 zoffset
+= texImage
->Border
;
2044 ASSERT(ctx
->Driver
.TexSubImage3D
);
2045 (*ctx
->Driver
.TexSubImage3D
)(ctx
, target
, level
,
2046 xoffset
, yoffset
, zoffset
,
2047 width
, height
, depth
,
2048 format
, type
, pixels
,
2049 &ctx
->Unpack
, texObj
, texImage
);
2050 ctx
->NewState
|= _NEW_TEXTURE
;
2056 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
2057 GLenum internalFormat
,
2059 GLsizei width
, GLint border
)
2061 struct gl_texture_unit
*texUnit
;
2062 struct gl_texture_object
*texObj
;
2063 struct gl_texture_image
*texImage
;
2064 GLsizei postConvWidth
= width
;
2065 GET_CURRENT_CONTEXT(ctx
);
2066 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2068 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2069 _mesa_update_state(ctx
);
2071 if (is_color_format(internalFormat
)) {
2072 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
2075 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
2076 postConvWidth
, 1, border
))
2079 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2080 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2081 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2083 texImage
= _mesa_alloc_texture_image();
2084 _mesa_set_tex_image(texObj
, target
, level
, texImage
);
2086 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D");
2090 else if (texImage
->Data
&& !texImage
->IsClientData
) {
2091 /* free the old texture data */
2092 MESA_PBUFFER_FREE(texImage
->Data
);
2094 texImage
->Data
= NULL
;
2096 clear_teximage_fields(texImage
); /* not really needed, but helpful */
2097 _mesa_init_teximage_fields(ctx
, target
, texImage
, postConvWidth
, 1, 1,
2098 border
, internalFormat
);
2101 ASSERT(ctx
->Driver
.CopyTexImage1D
);
2102 (*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
, internalFormat
,
2103 x
, y
, width
, border
);
2105 ASSERT(texImage
->TexFormat
);
2106 if (!texImage
->FetchTexel
) {
2107 /* If driver didn't explicitly set this, use the default */
2108 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel1D
;
2110 ASSERT(texImage
->FetchTexel
);
2113 texObj
->Complete
= GL_FALSE
;
2114 ctx
->NewState
|= _NEW_TEXTURE
;
2120 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
2121 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
2124 struct gl_texture_unit
*texUnit
;
2125 struct gl_texture_object
*texObj
;
2126 struct gl_texture_image
*texImage
;
2127 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2128 GET_CURRENT_CONTEXT(ctx
);
2129 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2131 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2132 _mesa_update_state(ctx
);
2134 if (is_color_format(internalFormat
)) {
2135 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
2139 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
2140 postConvWidth
, postConvHeight
, border
))
2143 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2144 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2145 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2147 texImage
= _mesa_alloc_texture_image();
2148 _mesa_set_tex_image(texObj
, target
, level
, texImage
);
2150 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D");
2154 else if (texImage
->Data
&& !texImage
->IsClientData
) {
2155 /* free the old texture data */
2156 MESA_PBUFFER_FREE(texImage
->Data
);
2158 texImage
->Data
= NULL
;
2160 clear_teximage_fields(texImage
); /* not really needed, but helpful */
2161 _mesa_init_teximage_fields(ctx
, target
, texImage
,
2162 postConvWidth
, postConvHeight
, 1,
2163 border
, internalFormat
);
2165 ASSERT(ctx
->Driver
.CopyTexImage2D
);
2166 (*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
, internalFormat
,
2167 x
, y
, width
, height
, border
);
2169 ASSERT(texImage
->TexFormat
);
2170 if (!texImage
->FetchTexel
) {
2171 /* If driver didn't explicitly set this, use the default */
2172 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel2D
;
2174 ASSERT(texImage
->FetchTexel
);
2177 texObj
->Complete
= GL_FALSE
;
2178 ctx
->NewState
|= _NEW_TEXTURE
;
2184 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
2185 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
2187 struct gl_texture_unit
*texUnit
;
2188 struct gl_texture_object
*texObj
;
2189 struct gl_texture_image
*texImage
;
2190 GLsizei postConvWidth
= width
;
2191 GET_CURRENT_CONTEXT(ctx
);
2192 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2194 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2195 _mesa_update_state(ctx
);
2197 /* XXX should test internal format */
2198 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
2200 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
2201 xoffset
, 0, 0, postConvWidth
, 1))
2204 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2205 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2206 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2208 /* If we have a border, xoffset=-1 is legal. Bias by border width */
2209 xoffset
+= texImage
->Border
;
2211 ASSERT(ctx
->Driver
.CopyTexSubImage1D
);
2212 (*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
, xoffset
, x
, y
, width
);
2213 ctx
->NewState
|= _NEW_TEXTURE
;
2219 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
2220 GLint xoffset
, GLint yoffset
,
2221 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2223 struct gl_texture_unit
*texUnit
;
2224 struct gl_texture_object
*texObj
;
2225 struct gl_texture_image
*texImage
;
2226 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2227 GET_CURRENT_CONTEXT(ctx
);
2228 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2230 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2231 _mesa_update_state(ctx
);
2233 /* XXX should test internal format */
2234 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
2236 if (copytexsubimage_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2237 postConvWidth
, postConvHeight
))
2240 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2241 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2242 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2244 /* If we have a border, xoffset=-1 is legal. Bias by border width */
2245 xoffset
+= texImage
->Border
;
2246 yoffset
+= texImage
->Border
;
2248 ASSERT(ctx
->Driver
.CopyTexSubImage2D
);
2249 (*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
2250 xoffset
, yoffset
, x
, y
, width
, height
);
2251 ctx
->NewState
|= _NEW_TEXTURE
;
2257 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
2258 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2259 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2261 struct gl_texture_unit
*texUnit
;
2262 struct gl_texture_object
*texObj
;
2263 struct gl_texture_image
*texImage
;
2264 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2265 GET_CURRENT_CONTEXT(ctx
);
2266 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2268 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2269 _mesa_update_state(ctx
);
2271 /* XXX should test internal format */
2272 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
2274 if (copytexsubimage_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
,
2275 zoffset
, postConvWidth
, postConvHeight
))
2278 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2279 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2280 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2282 /* If we have a border, xoffset=-1 is legal. Bias by border width */
2283 xoffset
+= texImage
->Border
;
2284 yoffset
+= texImage
->Border
;
2285 zoffset
+= texImage
->Border
;
2287 ASSERT(ctx
->Driver
.CopyTexSubImage3D
);
2288 (*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
2289 xoffset
, yoffset
, zoffset
,
2290 x
, y
, width
, height
);
2291 ctx
->NewState
|= _NEW_TEXTURE
;
2297 /**********************************************************************/
2298 /****** Compressed Textures ******/
2299 /**********************************************************************/
2303 * Error checking for glCompressedTexImage[123]D().
2304 * \return error code or GL_NO_ERROR.
2307 compressed_texture_error_check(GLcontext
*ctx
, GLint dimensions
,
2308 GLenum target
, GLint level
,
2309 GLenum internalFormat
, GLsizei width
,
2310 GLsizei height
, GLsizei depth
, GLint border
,
2313 GLboolean isProxy
= GL_FALSE
;
2314 GLint expectedSize
, maxLevels
= 0, maxTextureSize
;
2316 if (dimensions
== 1) {
2317 /* 1D compressed textures not allowed */
2318 return GL_INVALID_ENUM
;
2320 else if (dimensions
== 2) {
2321 if (target
== GL_PROXY_TEXTURE_2D
) {
2322 maxLevels
= ctx
->Const
.MaxTextureLevels
;
2325 else if (target
== GL_TEXTURE_2D
) {
2326 maxLevels
= ctx
->Const
.MaxTextureLevels
;
2328 else if (target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
) {
2329 if (!ctx
->Extensions
.ARB_texture_cube_map
)
2330 return GL_INVALID_ENUM
; /*target*/
2331 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
2334 else if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2335 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
2336 if (!ctx
->Extensions
.ARB_texture_cube_map
)
2337 return GL_INVALID_ENUM
; /*target*/
2338 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
2341 return GL_INVALID_ENUM
; /*target*/
2344 else if (dimensions
== 3) {
2345 /* 3D compressed textures not allowed */
2346 return GL_INVALID_ENUM
;
2349 maxTextureSize
= 1 << (maxLevels
- 1);
2351 if (!is_compressed_format(internalFormat
))
2352 return GL_INVALID_ENUM
;
2355 return GL_INVALID_VALUE
;
2357 if (width
< 1 || width
> maxTextureSize
|| logbase2(width
) < 0)
2358 return GL_INVALID_VALUE
;
2360 if ((height
< 1 || height
> maxTextureSize
|| logbase2(height
) < 0)
2362 return GL_INVALID_VALUE
;
2364 if ((depth
< 1 || depth
> maxTextureSize
|| logbase2(depth
) < 0)
2366 return GL_INVALID_VALUE
;
2368 /* For cube map, width must equal height */
2369 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2370 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
&& width
!= height
)
2371 return GL_INVALID_VALUE
;
2373 if (level
< 0 || level
>= maxLevels
)
2374 return GL_INVALID_VALUE
;
2376 expectedSize
= _mesa_compressed_texture_size(ctx
, width
, height
, depth
,
2378 if (expectedSize
!= imageSize
)
2379 return GL_INVALID_VALUE
;
2386 * Error checking for glCompressedTexSubImage[123]D().
2387 * \return error code or GL_NO_ERROR.
2390 compressed_subtexture_error_check(GLcontext
*ctx
, GLint dimensions
,
2391 GLenum target
, GLint level
,
2392 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2393 GLsizei width
, GLsizei height
, GLsizei depth
,
2394 GLenum format
, GLsizei imageSize
)
2396 GLboolean isProxy
= GL_FALSE
;
2397 GLint expectedSize
, maxLevels
= 0, maxTextureSize
;
2399 if (dimensions
== 1) {
2400 /* 1D compressed textures not allowed */
2401 return GL_INVALID_ENUM
;
2403 else if (dimensions
== 2) {
2404 if (target
== GL_PROXY_TEXTURE_2D
) {
2405 maxLevels
= ctx
->Const
.MaxTextureLevels
;
2408 else if (target
== GL_TEXTURE_2D
) {
2409 maxLevels
= ctx
->Const
.MaxTextureLevels
;
2411 else if (target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
) {
2412 if (!ctx
->Extensions
.ARB_texture_cube_map
)
2413 return GL_INVALID_ENUM
; /*target*/
2414 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
2417 else if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2418 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
2419 if (!ctx
->Extensions
.ARB_texture_cube_map
)
2420 return GL_INVALID_ENUM
; /*target*/
2421 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
2424 return GL_INVALID_ENUM
; /*target*/
2427 else if (dimensions
== 3) {
2428 /* 3D compressed textures not allowed */
2429 return GL_INVALID_ENUM
;
2432 maxTextureSize
= 1 << (maxLevels
- 1);
2434 if (!is_compressed_format(format
))
2435 return GL_INVALID_ENUM
;
2437 if (width
< 1 || width
> maxTextureSize
|| logbase2(width
) < 0)
2438 return GL_INVALID_VALUE
;
2440 if ((height
< 1 || height
> maxTextureSize
|| logbase2(height
) < 0)
2442 return GL_INVALID_VALUE
;
2444 if (level
< 0 || level
>= maxLevels
)
2445 return GL_INVALID_VALUE
;
2447 if ((xoffset
& 3) != 0 || (yoffset
& 3) != 0)
2448 return GL_INVALID_VALUE
;
2450 if ((width
& 3) != 0 && width
!= 2 && width
!= 1)
2451 return GL_INVALID_VALUE
;
2453 if ((height
& 3) != 0 && height
!= 2 && height
!= 1)
2454 return GL_INVALID_VALUE
;
2456 expectedSize
= _mesa_compressed_texture_size(ctx
, width
, height
, depth
,
2458 if (expectedSize
!= imageSize
)
2459 return GL_INVALID_VALUE
;
2467 _mesa_CompressedTexImage1DARB(GLenum target
, GLint level
,
2468 GLenum internalFormat
, GLsizei width
,
2469 GLint border
, GLsizei imageSize
,
2472 GET_CURRENT_CONTEXT(ctx
);
2473 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2475 if (target
== GL_TEXTURE_1D
) {
2476 struct gl_texture_unit
*texUnit
;
2477 struct gl_texture_object
*texObj
;
2478 struct gl_texture_image
*texImage
;
2479 GLenum error
= compressed_texture_error_check(ctx
, 1, target
, level
,
2480 internalFormat
, width
, 1, 1, border
, imageSize
);
2482 _mesa_error(ctx
, error
, "glCompressedTexImage1D");
2486 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2487 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2488 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2491 texImage
= _mesa_alloc_texture_image();
2492 texObj
->Image
[level
] = texImage
;
2494 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage1D");
2498 else if (texImage
->Data
&& !texImage
->IsClientData
) {
2499 MESA_PBUFFER_FREE(texImage
->Data
);
2501 texImage
->Data
= NULL
;
2503 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, 1, 1,
2504 border
, internalFormat
);
2506 ASSERT(ctx
->Driver
.CompressedTexImage1D
);
2507 (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
,
2508 internalFormat
, width
, border
,
2513 texObj
->Complete
= GL_FALSE
;
2514 ctx
->NewState
|= _NEW_TEXTURE
;
2516 else if (target
== GL_PROXY_TEXTURE_1D
) {
2517 /* Proxy texture: check for errors and update proxy state */
2518 GLenum error
= compressed_texture_error_check(ctx
, 1, target
, level
,
2519 internalFormat
, width
, 1, 1, border
, imageSize
);
2521 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2522 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2523 internalFormat
, GL_NONE
, GL_NONE
,
2524 width
, 1, 1, border
);
2527 /* if error, clear all proxy texture image parameters */
2528 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2529 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
2533 /* store the teximage parameters */
2534 struct gl_texture_unit
*texUnit
;
2535 struct gl_texture_image
*texImage
;
2536 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2537 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2538 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, 1, 1,
2539 border
, internalFormat
);
2543 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1D(target)");
2550 _mesa_CompressedTexImage2DARB(GLenum target
, GLint level
,
2551 GLenum internalFormat
, GLsizei width
,
2552 GLsizei height
, GLint border
, GLsizei imageSize
,
2555 GET_CURRENT_CONTEXT(ctx
);
2556 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2558 if (target
== GL_TEXTURE_2D
||
2559 (ctx
->Extensions
.ARB_texture_cube_map
&&
2560 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2561 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
2562 struct gl_texture_unit
*texUnit
;
2563 struct gl_texture_object
*texObj
;
2564 struct gl_texture_image
*texImage
;
2565 GLenum error
= compressed_texture_error_check(ctx
, 2, target
, level
,
2566 internalFormat
, width
, height
, 1, border
, imageSize
);
2568 _mesa_error(ctx
, error
, "glCompressedTexImage2D");
2572 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2573 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2574 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2577 texImage
= _mesa_alloc_texture_image();
2578 texObj
->Image
[level
] = texImage
;
2580 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2D");
2584 else if (texImage
->Data
&& !texImage
->IsClientData
) {
2585 MESA_PBUFFER_FREE(texImage
->Data
);
2587 texImage
->Data
= NULL
;
2589 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
, 1,
2590 border
, internalFormat
);
2592 ASSERT(ctx
->Driver
.CompressedTexImage2D
);
2593 (*ctx
->Driver
.CompressedTexImage2D
)(ctx
, target
, level
,
2594 internalFormat
, width
, height
,
2595 border
, imageSize
, data
,
2599 texObj
->Complete
= GL_FALSE
;
2600 ctx
->NewState
|= _NEW_TEXTURE
;
2602 else if (target
== GL_PROXY_TEXTURE_2D
||
2603 (target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
&&
2604 ctx
->Extensions
.ARB_texture_cube_map
)) {
2605 /* Proxy texture: check for errors and update proxy state */
2606 GLenum error
= compressed_texture_error_check(ctx
, 2, target
, level
,
2607 internalFormat
, width
, height
, 1, border
, imageSize
);
2609 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2610 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2611 internalFormat
, GL_NONE
, GL_NONE
,
2612 width
, height
, 1, border
);
2615 /* if error, clear all proxy texture image parameters */
2616 const GLint maxLevels
= (target
== GL_PROXY_TEXTURE_2D
) ?
2617 ctx
->Const
.MaxTextureLevels
: ctx
->Const
.MaxCubeTextureLevels
;
2618 if (level
>= 0 && level
< maxLevels
) {
2619 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
2623 /* store the teximage parameters */
2624 struct gl_texture_unit
*texUnit
;
2625 struct gl_texture_image
*texImage
;
2626 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2627 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2628 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
, 1,
2629 border
, internalFormat
);
2633 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2D(target)");
2640 _mesa_CompressedTexImage3DARB(GLenum target
, GLint level
,
2641 GLenum internalFormat
, GLsizei width
,
2642 GLsizei height
, GLsizei depth
, GLint border
,
2643 GLsizei imageSize
, const GLvoid
*data
)
2645 GET_CURRENT_CONTEXT(ctx
);
2646 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2648 if (target
== GL_TEXTURE_3D
) {
2649 struct gl_texture_unit
*texUnit
;
2650 struct gl_texture_object
*texObj
;
2651 struct gl_texture_image
*texImage
;
2652 GLenum error
= compressed_texture_error_check(ctx
, 3, target
, level
,
2653 internalFormat
, width
, height
, depth
, border
, imageSize
);
2655 _mesa_error(ctx
, error
, "glCompressedTexImage3D");
2659 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2660 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2661 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2664 texImage
= _mesa_alloc_texture_image();
2665 texObj
->Image
[level
] = texImage
;
2667 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage3D");
2671 else if (texImage
->Data
&& !texImage
->IsClientData
) {
2672 MESA_PBUFFER_FREE(texImage
->Data
);
2674 texImage
->Data
= NULL
;
2676 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
, depth
,
2677 border
, internalFormat
);
2679 ASSERT(ctx
->Driver
.CompressedTexImage3D
);
2680 (*ctx
->Driver
.CompressedTexImage3D
)(ctx
, target
, level
,
2682 width
, height
, depth
,
2683 border
, imageSize
, data
,
2687 texObj
->Complete
= GL_FALSE
;
2688 ctx
->NewState
|= _NEW_TEXTURE
;
2690 else if (target
== GL_PROXY_TEXTURE_3D
) {
2691 /* Proxy texture: check for errors and update proxy state */
2692 GLenum error
= compressed_texture_error_check(ctx
, 3, target
, level
,
2693 internalFormat
, width
, height
, depth
, border
, imageSize
);
2695 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2696 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2697 internalFormat
, GL_NONE
, GL_NONE
,
2698 width
, height
, depth
, border
);
2701 /* if error, clear all proxy texture image parameters */
2702 if (level
>= 0 && level
< ctx
->Const
.Max3DTextureLevels
) {
2703 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
2707 /* store the teximage parameters */
2708 struct gl_texture_unit
*texUnit
;
2709 struct gl_texture_image
*texImage
;
2710 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2711 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2712 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
,
2713 depth
, border
, internalFormat
);
2717 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3D(target)");
2724 _mesa_CompressedTexSubImage1DARB(GLenum target
, GLint level
, GLint xoffset
,
2725 GLsizei width
, GLenum format
,
2726 GLsizei imageSize
, const GLvoid
*data
)
2728 struct gl_texture_unit
*texUnit
;
2729 struct gl_texture_object
*texObj
;
2730 struct gl_texture_image
*texImage
;
2732 GET_CURRENT_CONTEXT(ctx
);
2733 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2735 error
= compressed_subtexture_error_check(ctx
, 1, target
, level
,
2736 xoffset
, 0, 0, width
, 1, 1, format
, imageSize
);
2738 _mesa_error(ctx
, error
, "glCompressedTexSubImage1D");
2742 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2743 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2744 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2747 if ((GLint
) format
!= texImage
->IntFormat
) {
2748 _mesa_error(ctx
, GL_INVALID_OPERATION
,
2749 "glCompressedTexSubImage1D(format)");
2753 if ((width
== 1 || width
== 2) && (GLuint
) width
!= texImage
->Width
) {
2754 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexSubImage1D(width)");
2758 if (width
== 0 || !data
)
2759 return; /* no-op, not an error */
2761 if (ctx
->Driver
.CompressedTexSubImage1D
) {
2762 (*ctx
->Driver
.CompressedTexSubImage1D
)(ctx
, target
, level
,
2764 format
, imageSize
, data
,
2767 ctx
->NewState
|= _NEW_TEXTURE
;
2772 _mesa_CompressedTexSubImage2DARB(GLenum target
, GLint level
, GLint xoffset
,
2773 GLint yoffset
, GLsizei width
, GLsizei height
,
2774 GLenum format
, GLsizei imageSize
,
2777 struct gl_texture_unit
*texUnit
;
2778 struct gl_texture_object
*texObj
;
2779 struct gl_texture_image
*texImage
;
2781 GET_CURRENT_CONTEXT(ctx
);
2782 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2784 error
= compressed_subtexture_error_check(ctx
, 2, target
, level
,
2785 xoffset
, yoffset
, 0, width
, height
, 1, format
, imageSize
);
2787 _mesa_error(ctx
, error
, "glCompressedTexSubImage2D");
2791 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2792 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2793 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2796 if ((GLint
) format
!= texImage
->IntFormat
) {
2797 _mesa_error(ctx
, GL_INVALID_OPERATION
,
2798 "glCompressedTexSubImage2D(format)");
2802 if (((width
== 1 || width
== 2) && (GLuint
) width
!= texImage
->Width
) ||
2803 ((height
== 1 || height
== 2) && (GLuint
) height
!= texImage
->Height
)) {
2804 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexSubImage2D(size)");
2808 if (width
== 0 || height
== 0 || !data
)
2809 return; /* no-op, not an error */
2811 if (ctx
->Driver
.CompressedTexSubImage2D
) {
2812 (*ctx
->Driver
.CompressedTexSubImage2D
)(ctx
, target
, level
,
2813 xoffset
, yoffset
, width
, height
,
2814 format
, imageSize
, data
,
2817 ctx
->NewState
|= _NEW_TEXTURE
;
2822 _mesa_CompressedTexSubImage3DARB(GLenum target
, GLint level
, GLint xoffset
,
2823 GLint yoffset
, GLint zoffset
, GLsizei width
,
2824 GLsizei height
, GLsizei depth
, GLenum format
,
2825 GLsizei imageSize
, const GLvoid
*data
)
2827 struct gl_texture_unit
*texUnit
;
2828 struct gl_texture_object
*texObj
;
2829 struct gl_texture_image
*texImage
;
2831 GET_CURRENT_CONTEXT(ctx
);
2832 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2834 error
= compressed_subtexture_error_check(ctx
, 3, target
, level
,
2835 xoffset
, yoffset
, zoffset
, width
, height
, depth
, format
, imageSize
);
2837 _mesa_error(ctx
, error
, "glCompressedTexSubImage2D");
2841 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2842 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2843 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2846 if ((GLint
) format
!= texImage
->IntFormat
) {
2847 _mesa_error(ctx
, GL_INVALID_OPERATION
,
2848 "glCompressedTexSubImage3D(format)");
2852 if (((width
== 1 || width
== 2) && (GLuint
) width
!= texImage
->Width
) ||
2853 ((height
== 1 || height
== 2) && (GLuint
) height
!= texImage
->Height
) ||
2854 ((depth
== 1 || depth
== 2) && (GLuint
) depth
!= texImage
->Depth
)) {
2855 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexSubImage3D(size)");
2859 if (width
== 0 || height
== 0 || depth
== 0 || !data
)
2860 return; /* no-op, not an error */
2862 if (ctx
->Driver
.CompressedTexSubImage3D
) {
2863 (*ctx
->Driver
.CompressedTexSubImage3D
)(ctx
, target
, level
,
2864 xoffset
, yoffset
, zoffset
,
2865 width
, height
, depth
,
2866 format
, imageSize
, data
,
2869 ctx
->NewState
|= _NEW_TEXTURE
;
2874 _mesa_GetCompressedTexImageARB(GLenum target
, GLint level
, GLvoid
*img
)
2876 const struct gl_texture_unit
*texUnit
;
2877 const struct gl_texture_object
*texObj
;
2878 struct gl_texture_image
*texImage
;
2880 GET_CURRENT_CONTEXT(ctx
);
2881 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2883 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2884 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2886 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB");
2890 if (target
== GL_TEXTURE_1D
|| target
== GL_TEXTURE_2D
) {
2891 maxLevels
= ctx
->Const
.MaxTextureLevels
;
2893 else if (target
== GL_TEXTURE_3D
) {
2894 maxLevels
= ctx
->Const
.Max3DTextureLevels
;
2897 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
2900 ASSERT(maxLevels
> 0);
2902 if (level
< 0 || level
>= maxLevels
) {
2903 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
2907 if (is_proxy_target(target
)) {
2908 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB(target)");
2912 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2914 /* probably invalid mipmap level */
2915 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
2919 if (!texImage
->IsCompressed
) {
2920 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetCompressedTexImageARB");
2927 /* just memcpy, no pixelstore or pixel transfer */
2928 MEMCPY(img
, texImage
->Data
, texImage
->CompressedSize
);