1 /* $Id: teximage.c,v 1.71 2001/02/06 21:42:48 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 #include "swrast/s_span.h" /* XXX SWRAST hack */
49 * Mesa's native texture datatype is GLchan. Native formats are
50 * GL_ALPHA, GL_LUMINANCE, GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, GL_RGBA,
52 * Device drivers are free to implement any internal format they want.
57 static void PrintTexture(const struct gl_texture_image
*img
)
60 GLchan
*data
= img
->Data
;
63 printf("No texture data\n");
67 switch (img
->Format
) {
74 case GL_LUMINANCE_ALPHA
:
84 gl_problem(NULL
, "error in PrintTexture\n");
89 for (i
= 0; i
< img
->Height
; i
++) {
90 for (j
= 0; j
< img
->Width
; j
++) {
92 printf("%02x ", data
[0]);
94 printf("%02x%02x ", data
[0], data
[1]);
96 printf("%02x%02x%02x ", data
[0], data
[1], data
[2]);
98 printf("%02x%02x%02x%02x ", data
[0], data
[1], data
[2], data
[3]);
109 * Compute log base 2 of n.
110 * If n isn't an exact power of two return -1.
138 * Given an internal texture format enum or 1, 2, 3, 4 return the
139 * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE,
140 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.
141 * Return -1 if invalid enum.
144 _mesa_base_tex_format( GLcontext
*ctx
, GLint format
)
147 * Ask the driver for the base format, if it doesn't
148 * know, it will return -1;
150 if (ctx
->Driver
.BaseCompressedTexFormat
) {
151 GLint ifmt
= (*ctx
->Driver
.BaseCompressedTexFormat
)(ctx
, format
);
171 case GL_LUMINANCE_ALPHA
:
172 case GL_LUMINANCE4_ALPHA4
:
173 case GL_LUMINANCE6_ALPHA2
:
174 case GL_LUMINANCE8_ALPHA8
:
175 case GL_LUMINANCE12_ALPHA4
:
176 case GL_LUMINANCE12_ALPHA12
:
177 case GL_LUMINANCE16_ALPHA16
:
178 return GL_LUMINANCE_ALPHA
;
206 case GL_COLOR_INDEX1_EXT
:
207 case GL_COLOR_INDEX2_EXT
:
208 case GL_COLOR_INDEX4_EXT
:
209 case GL_COLOR_INDEX8_EXT
:
210 case GL_COLOR_INDEX12_EXT
:
211 case GL_COLOR_INDEX16_EXT
:
212 return GL_COLOR_INDEX
;
214 return -1; /* error */
221 * Return GL_TRUE if internalFormat is a compressed format, return GL_FALSE
225 is_compressed_format(GLcontext
*ctx
, GLenum internalFormat
)
227 if (ctx
->Driver
.IsCompressedFormat
) {
228 return (*ctx
->Driver
.IsCompressedFormat
)(ctx
, internalFormat
);
236 * Store a gl_texture_image pointer in a gl_texture_object structure
237 * according to the target and level parameters.
238 * This was basically prompted by the introduction of cube maps.
241 set_tex_image(struct gl_texture_object
*tObj
,
242 GLenum target
, GLint level
,
243 struct gl_texture_image
*texImage
)
249 tObj
->Image
[level
] = texImage
;
251 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
252 tObj
->Image
[level
] = texImage
;
254 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
255 tObj
->NegX
[level
] = texImage
;
257 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
258 tObj
->PosY
[level
] = texImage
;
260 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
261 tObj
->NegY
[level
] = texImage
;
263 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
264 tObj
->PosZ
[level
] = texImage
;
266 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
267 tObj
->NegZ
[level
] = texImage
;
270 gl_problem(NULL
, "bad target in set_tex_image()");
278 * Return new gl_texture_image struct with all fields initialized to zero.
280 struct gl_texture_image
*
281 _mesa_alloc_texture_image( void )
283 return CALLOC_STRUCT(gl_texture_image
);
289 _mesa_free_texture_image( struct gl_texture_image
*teximage
)
291 if (teximage
->Data
) {
292 FREE( teximage
->Data
);
293 teximage
->Data
= NULL
;
300 * Return GL_TRUE if the target is a proxy target.
303 is_proxy_target(GLenum target
)
305 return (target
== GL_PROXY_TEXTURE_1D
||
306 target
== GL_PROXY_TEXTURE_2D
||
307 target
== GL_PROXY_TEXTURE_3D
||
308 target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
);
313 * Given a texture unit and a texture target, return the corresponding
316 struct gl_texture_object
*
317 _mesa_select_tex_object(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
322 return texUnit
->Current1D
;
323 case GL_PROXY_TEXTURE_1D
:
324 return ctx
->Texture
.Proxy1D
;
326 return texUnit
->Current2D
;
327 case GL_PROXY_TEXTURE_2D
:
328 return ctx
->Texture
.Proxy2D
;
330 return texUnit
->Current3D
;
331 case GL_PROXY_TEXTURE_3D
:
332 return ctx
->Texture
.Proxy3D
;
333 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
334 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
335 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
336 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
337 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
338 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
339 return ctx
->Extensions
.ARB_texture_cube_map
340 ? texUnit
->CurrentCubeMap
: NULL
;
341 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
342 return ctx
->Extensions
.ARB_texture_cube_map
343 ? ctx
->Texture
.ProxyCubeMap
: NULL
;
345 gl_problem(NULL
, "bad target in _mesa_select_tex_object()");
352 * Return the texture image struct which corresponds to target and level
353 * for the given texture unit.
355 struct gl_texture_image
*
356 _mesa_select_tex_image(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
357 GLenum target
, GLint level
)
362 return texUnit
->Current1D
->Image
[level
];
363 case GL_PROXY_TEXTURE_1D
:
364 return ctx
->Texture
.Proxy1D
->Image
[level
];
366 return texUnit
->Current2D
->Image
[level
];
367 case GL_PROXY_TEXTURE_2D
:
368 return ctx
->Texture
.Proxy2D
->Image
[level
];
370 return texUnit
->Current3D
->Image
[level
];
371 case GL_PROXY_TEXTURE_3D
:
372 return ctx
->Texture
.Proxy3D
->Image
[level
];
373 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
374 if (ctx
->Extensions
.ARB_texture_cube_map
)
375 return texUnit
->CurrentCubeMap
->Image
[level
];
378 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
379 if (ctx
->Extensions
.ARB_texture_cube_map
)
380 return texUnit
->CurrentCubeMap
->NegX
[level
];
383 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
384 if (ctx
->Extensions
.ARB_texture_cube_map
)
385 return texUnit
->CurrentCubeMap
->PosY
[level
];
388 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
389 if (ctx
->Extensions
.ARB_texture_cube_map
)
390 return texUnit
->CurrentCubeMap
->NegY
[level
];
393 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
394 if (ctx
->Extensions
.ARB_texture_cube_map
)
395 return texUnit
->CurrentCubeMap
->PosZ
[level
];
398 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
399 if (ctx
->Extensions
.ARB_texture_cube_map
)
400 return texUnit
->CurrentCubeMap
->NegZ
[level
];
403 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
404 if (ctx
->Extensions
.ARB_texture_cube_map
)
405 return ctx
->Texture
.ProxyCubeMap
->Image
[level
];
409 gl_problem(ctx
, "bad target in _mesa_select_tex_image()");
417 * glTexImage[123]D can accept a NULL image pointer. In this case we
418 * create a texture image with unspecified image contents per the OpenGL
422 make_null_texture(GLint width
, GLint height
, GLint depth
, GLenum format
)
424 const GLint components
= _mesa_components_in_format(format
);
425 const GLint numPixels
= width
* height
* depth
;
426 GLubyte
*data
= (GLubyte
*) MALLOC(numPixels
* components
* sizeof(GLubyte
));
429 * Let's see if anyone finds this. If glTexImage2D() is called with
430 * a NULL image pointer then load the texture image with something
431 * interesting instead of leaving it indeterminate.
434 static const char message
[8][32] = {
438 " X X XXXX XXX XXXXX ",
441 " X X XXXXX XXX X X ",
445 GLubyte
*imgPtr
= data
;
447 for (h
= 0; h
< depth
; h
++) {
448 for (i
= 0; i
< height
; i
++) {
449 GLint srcRow
= 7 - (i
% 8);
450 for (j
= 0; j
< width
; j
++) {
451 GLint srcCol
= j
% 32;
452 GLubyte texel
= (message
[srcRow
][srcCol
]=='X') ? 255 : 70;
453 for (k
= 0; k
< components
; k
++) {
467 * This is called when a proxy texture test fails, we set all the
468 * image members (except DriverData) to zero.
471 clear_proxy_teximage(struct gl_texture_image
*img
)
480 img
->IntensityBits
= 0;
481 img
->LuminanceBits
= 0;
494 img
->IsCompressed
= 0;
495 img
->CompressedSize
= 0;
501 * Test glTexImage[123]D() parameters for errors.
503 * dimensions - must be 1 or 2 or 3
504 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
507 texture_error_check( GLcontext
*ctx
, GLenum target
,
508 GLint level
, GLint internalFormat
,
509 GLenum format
, GLenum type
,
511 GLint width
, GLint height
,
512 GLint depth
, GLint border
)
517 if (dimensions
== 1) {
518 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_1D
);
519 if (target
!= GL_TEXTURE_1D
&& !isProxy
) {
520 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
524 else if (dimensions
== 2) {
525 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_2D
||
526 target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
);
527 if (target
!= GL_TEXTURE_2D
&& !isProxy
&&
528 !(ctx
->Extensions
.ARB_texture_cube_map
&&
529 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
530 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
531 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
535 else if (dimensions
== 3) {
536 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_3D
);
537 if (target
!= GL_TEXTURE_3D
&& !isProxy
) {
538 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
543 gl_problem( ctx
, "bad dims in texture_error_check" );
548 if (border
!= 0 && border
!= 1) {
551 sprintf(message
, "glTexImage%dD(border=%d)", dimensions
, border
);
552 gl_error(ctx
, GL_INVALID_VALUE
, message
);
558 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
559 || logbase2( width
- 2 * border
) < 0) {
562 sprintf(message
, "glTexImage%dD(width=%d)", dimensions
, width
);
563 gl_error(ctx
, GL_INVALID_VALUE
, message
);
569 if (dimensions
>= 2) {
570 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
571 || logbase2( height
- 2 * border
) < 0) {
574 sprintf(message
, "glTexImage%dD(height=%d)", dimensions
, height
);
575 gl_error(ctx
, GL_INVALID_VALUE
, message
);
581 /* For cube map, width must equal height */
582 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
583 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
584 if (width
!= height
) {
586 gl_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
593 if (dimensions
>= 3) {
594 if (depth
< 2 * border
|| depth
> 2 + ctx
->Const
.MaxTextureSize
595 || logbase2( depth
- 2 * border
) < 0) {
598 sprintf(message
, "glTexImage3D(depth=%d)", depth
);
599 gl_error( ctx
, GL_INVALID_VALUE
, message
);
606 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
609 sprintf(message
, "glTexImage%dD(level=%d)", dimensions
, level
);
610 gl_error(ctx
, GL_INVALID_VALUE
, message
);
615 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
619 sprintf(message
, "glTexImage%dD(internalFormat=0x%x)", dimensions
,
621 gl_error(ctx
, GL_INVALID_VALUE
, message
);
626 if (!is_compressed_format(ctx
, internalFormat
)) {
627 if (!_mesa_is_legal_format_and_type( format
, type
)) {
628 /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
629 * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
633 sprintf(message
, "glTexImage%dD(format or type)", dimensions
);
634 gl_error(ctx
, GL_INVALID_OPERATION
, message
);
640 /* if we get here, the parameters are OK */
647 * Test glTexSubImage[123]D() parameters for errors.
649 * dimensions - must be 1 or 2 or 3
650 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
653 subtexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
654 GLenum target
, GLint level
,
655 GLint xoffset
, GLint yoffset
, GLint zoffset
,
656 GLint width
, GLint height
, GLint depth
,
657 GLenum format
, GLenum type
)
659 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
660 struct gl_texture_image
*destTex
;
662 if (dimensions
== 1) {
663 if (target
!= GL_TEXTURE_1D
) {
664 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(target)" );
668 else if (dimensions
== 2) {
669 if (ctx
->Extensions
.ARB_texture_cube_map
) {
670 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
671 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
672 target
!= GL_TEXTURE_2D
) {
673 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
677 else if (target
!= GL_TEXTURE_2D
) {
678 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
682 else if (dimensions
== 3) {
683 if (target
!= GL_TEXTURE_3D
) {
684 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3D(target)" );
689 gl_problem( ctx
, "bad dims in texture_error_check" );
693 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
695 sprintf(message
, "glTexSubImage2D(level=%d)", level
);
696 gl_error(ctx
, GL_INVALID_ENUM
, message
);
702 sprintf(message
, "glTexSubImage%dD(width=%d)", dimensions
, width
);
703 gl_error(ctx
, GL_INVALID_VALUE
, message
);
706 if (height
< 0 && dimensions
> 1) {
708 sprintf(message
, "glTexSubImage%dD(height=%d)", dimensions
, height
);
709 gl_error(ctx
, GL_INVALID_VALUE
, message
);
712 if (depth
< 0 && dimensions
> 2) {
714 sprintf(message
, "glTexSubImage%dD(depth=%d)", dimensions
, depth
);
715 gl_error(ctx
, GL_INVALID_VALUE
, message
);
719 destTex
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
722 gl_error(ctx
, GL_INVALID_OPERATION
, "glTexSubImage2D");
726 if (xoffset
< -((GLint
)destTex
->Border
)) {
727 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset)");
730 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
731 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset+width)");
734 if (dimensions
> 1) {
735 if (yoffset
< -((GLint
)destTex
->Border
)) {
736 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset)");
739 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
740 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset+height)");
744 if (dimensions
> 2) {
745 if (zoffset
< -((GLint
)destTex
->Border
)) {
746 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset)");
749 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+destTex
->Border
)) {
750 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset+depth)");
755 if (!is_compressed_format(ctx
, destTex
->IntFormat
)) {
756 if (!_mesa_is_legal_format_and_type(format
, type
)) {
758 sprintf(message
, "glTexSubImage%dD(format or type)", dimensions
);
759 gl_error(ctx
, GL_INVALID_ENUM
, message
);
769 * Test glCopyTexImage[12]D() parameters for errors.
770 * Input: dimensions - must be 1 or 2 or 3
771 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
774 copytexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
775 GLenum target
, GLint level
, GLint internalFormat
,
776 GLint width
, GLint height
, GLint border
)
780 if (dimensions
== 1) {
781 if (target
!= GL_TEXTURE_1D
) {
782 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
786 else if (dimensions
== 2) {
787 if (ctx
->Extensions
.ARB_texture_cube_map
) {
788 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
789 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
790 target
!= GL_TEXTURE_2D
) {
791 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
795 else if (target
!= GL_TEXTURE_2D
) {
796 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
802 if (border
!=0 && border
!=1) {
804 sprintf(message
, "glCopyTexImage%dD(border)", dimensions
);
805 gl_error(ctx
, GL_INVALID_VALUE
, message
);
810 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
811 || logbase2( width
- 2 * border
) < 0) {
813 sprintf(message
, "glCopyTexImage%dD(width=%d)", dimensions
, width
);
814 gl_error(ctx
, GL_INVALID_VALUE
, message
);
819 if (dimensions
>= 2) {
820 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
821 || logbase2( height
- 2 * border
) < 0) {
823 sprintf(message
, "glCopyTexImage%dD(height=%d)", dimensions
, height
);
824 gl_error(ctx
, GL_INVALID_VALUE
, message
);
829 /* For cube map, width must equal height */
830 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
831 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
832 if (width
!= height
) {
833 gl_error(ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(width != height)");
839 if (level
<0 || level
>=ctx
->Const
.MaxTextureLevels
) {
841 sprintf(message
, "glCopyTexImage%dD(level=%d)", dimensions
, level
);
842 gl_error(ctx
, GL_INVALID_VALUE
, message
);
846 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
849 sprintf(message
, "glCopyTexImage%dD(internalFormat)", dimensions
);
850 gl_error(ctx
, GL_INVALID_VALUE
, message
);
854 /* if we get here, the parameters are OK */
860 copytexsubimage_error_check( GLcontext
*ctx
, GLuint dimensions
,
861 GLenum target
, GLint level
,
862 GLint xoffset
, GLint yoffset
, GLint zoffset
,
863 GLsizei width
, GLsizei height
)
865 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
866 struct gl_texture_image
*teximage
;
868 if (dimensions
== 1) {
869 if (target
!= GL_TEXTURE_1D
) {
870 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
874 else if (dimensions
== 2) {
875 if (ctx
->Extensions
.ARB_texture_cube_map
) {
876 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
877 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
878 target
!= GL_TEXTURE_2D
) {
879 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
883 else if (target
!= GL_TEXTURE_2D
) {
884 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
888 else if (dimensions
== 3) {
889 if (target
!= GL_TEXTURE_3D
) {
890 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3D(target)" );
895 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
897 sprintf(message
, "glCopyTexSubImage%dD(level=%d)", dimensions
, level
);
898 gl_error(ctx
, GL_INVALID_VALUE
, message
);
904 sprintf(message
, "glCopyTexSubImage%dD(width=%d)", dimensions
, width
);
905 gl_error(ctx
, GL_INVALID_VALUE
, message
);
908 if (dimensions
> 1 && height
< 0) {
910 sprintf(message
, "glCopyTexSubImage%dD(height=%d)", dimensions
, height
);
911 gl_error(ctx
, GL_INVALID_VALUE
, message
);
915 teximage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
918 sprintf(message
, "glCopyTexSubImage%dD(undefined texture)", dimensions
);
919 gl_error(ctx
, GL_INVALID_OPERATION
, message
);
923 if (xoffset
< -((GLint
)teximage
->Border
)) {
925 sprintf(message
, "glCopyTexSubImage%dD(xoffset=%d)", dimensions
, xoffset
);
926 gl_error(ctx
, GL_INVALID_VALUE
, message
);
929 if (xoffset
+width
> (GLint
) (teximage
->Width
+teximage
->Border
)) {
931 sprintf(message
, "glCopyTexSubImage%dD(xoffset+width)", dimensions
);
932 gl_error(ctx
, GL_INVALID_VALUE
, message
);
935 if (dimensions
> 1) {
936 if (yoffset
< -((GLint
)teximage
->Border
)) {
938 sprintf(message
, "glCopyTexSubImage%dD(yoffset=%d)", dimensions
, yoffset
);
939 gl_error(ctx
, GL_INVALID_VALUE
, message
);
942 /* NOTE: we're adding the border here, not subtracting! */
943 if (yoffset
+height
> (GLint
) (teximage
->Height
+teximage
->Border
)) {
945 sprintf(message
, "glCopyTexSubImage%dD(yoffset+height)", dimensions
);
946 gl_error(ctx
, GL_INVALID_VALUE
, message
);
951 if (dimensions
> 2) {
952 if (zoffset
< -((GLint
)teximage
->Border
)) {
954 sprintf(message
, "glCopyTexSubImage%dD(zoffset)", dimensions
);
955 gl_error(ctx
, GL_INVALID_VALUE
, message
);
958 if (zoffset
> (GLint
) (teximage
->Depth
+teximage
->Border
)) {
960 sprintf(message
, "glCopyTexSubImage%dD(zoffset+depth)", dimensions
);
961 gl_error(ctx
, GL_INVALID_VALUE
, message
);
966 /* if we get here, the parameters are OK */
973 _mesa_GetTexImage( GLenum target
, GLint level
, GLenum format
,
974 GLenum type
, GLvoid
*pixels
)
976 GET_CURRENT_CONTEXT(ctx
);
977 const struct gl_texture_unit
*texUnit
;
978 const struct gl_texture_object
*texObj
;
979 struct gl_texture_image
*texImage
;
981 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
983 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
984 gl_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
988 if (_mesa_sizeof_type(type
) <= 0) {
989 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
993 if (_mesa_components_in_format(format
) <= 0) {
994 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
1001 texUnit
= &(ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
]);
1002 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1003 if (!texObj
|| is_proxy_target(target
)) {
1004 gl_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)");
1008 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1010 /* invalid mipmap level, not an error */
1014 if (!texImage
->Data
) {
1015 /* no image data, not an error */
1019 if (ctx
->NewState
& _NEW_PIXEL
)
1020 gl_update_state(ctx
);
1022 if (ctx
->_ImageTransferState
& IMAGE_CONVOLUTION_BIT
) {
1023 /* convert texture image to GL_RGBA, GL_FLOAT */
1024 GLint width
= texImage
->Width
;
1025 GLint height
= texImage
->Height
;
1026 GLint depth
= texImage
->Depth
;
1028 GLfloat
*tmpImage
, *convImage
;
1029 tmpImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
1031 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
1034 convImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
1037 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
1041 for (img
= 0; img
< depth
; img
++) {
1042 GLint convWidth
, convHeight
;
1044 /* convert texture data to GLfloat/GL_RGBA */
1045 for (row
= 0; row
< height
; row
++) {
1046 GLchan texels
[1 << MAX_TEXTURE_LEVELS
][4];
1048 GLfloat
*dst
= tmpImage
+ row
* width
* 4;
1049 for (col
= 0; col
< width
; col
++) {
1050 (*texImage
->FetchTexel
)(ctx
, texObj
, texImage
, col
, row
, img
,
1053 _mesa_unpack_float_color_span(ctx
, width
, GL_RGBA
, dst
,
1054 GL_RGBA
, CHAN_TYPE
, texels
,
1055 &_mesa_native_packing
,
1056 ctx
->_ImageTransferState
& IMAGE_PRE_CONVOLUTION_BITS
,
1061 convHeight
= height
;
1064 if (target
== GL_TEXTURE_1D
) {
1065 if (ctx
->Pixel
.Convolution1DEnabled
) {
1066 _mesa_convolve_1d_image(ctx
, &convWidth
, tmpImage
, convImage
);
1070 if (ctx
->Pixel
.Convolution2DEnabled
) {
1071 _mesa_convolve_2d_image(ctx
, &convWidth
, &convHeight
,
1072 tmpImage
, convImage
);
1074 else if (ctx
->Pixel
.Separable2DEnabled
) {
1075 _mesa_convolve_sep_image(ctx
, &convWidth
, &convHeight
,
1076 tmpImage
, convImage
);
1080 /* pack convolved image */
1081 for (row
= 0; row
< convHeight
; row
++) {
1082 const GLfloat
*src
= convImage
+ row
* convWidth
* 4;
1083 GLvoid
*dest
= _mesa_image_address(&ctx
->Pack
, pixels
,
1084 convWidth
, convHeight
,
1085 format
, type
, img
, row
, 0);
1086 _mesa_pack_float_rgba_span(ctx
, convWidth
,
1087 (const GLfloat(*)[4]) src
,
1088 format
, type
, dest
, &ctx
->Pack
,
1089 ctx
->_ImageTransferState
& IMAGE_POST_CONVOLUTION_BITS
);
1097 /* no convolution */
1098 GLint width
= texImage
->Width
;
1099 GLint height
= texImage
->Height
;
1100 GLint depth
= texImage
->Depth
;
1102 for (img
= 0; img
< depth
; img
++) {
1103 for (row
= 0; row
< height
; row
++) {
1104 /* compute destination address in client memory */
1105 GLvoid
*dest
= _mesa_image_address( &ctx
->Unpack
, pixels
,
1106 width
, height
, format
, type
, img
, row
, 0);
1110 /* general case: convert row to RGBA format */
1111 GLchan rgba
[MAX_WIDTH
][4];
1113 for (col
= 0; col
< width
; col
++) {
1114 (*texImage
->FetchTexel
)(ctx
, texObj
, texImage
,
1115 img
, row
, col
, rgba
[col
]);
1118 _mesa_pack_rgba_span( ctx
, width
, (const GLchan (*)[4])rgba
,
1119 format
, type
, dest
, &ctx
->Pack
,
1120 ctx
->_ImageTransferState
);
1130 * Called from the API. Note that width includes the border.
1133 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
1134 GLsizei width
, GLint border
, GLenum format
,
1135 GLenum type
, const GLvoid
*pixels
)
1137 GLsizei postConvWidth
= width
;
1138 GET_CURRENT_CONTEXT(ctx
);
1139 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1141 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1143 if (target
== GL_TEXTURE_1D
) {
1144 struct gl_texture_unit
*texUnit
;
1145 struct gl_texture_object
*texObj
;
1146 struct gl_texture_image
*texImage
;
1148 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1149 format
, type
, 1, postConvWidth
, 1, 1, border
)) {
1150 return; /* error was recorded */
1153 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1154 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1155 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1158 texImage
= _mesa_alloc_texture_image();
1159 texObj
->Image
[level
] = texImage
;
1161 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
1165 else if (texImage
->Data
) {
1166 /* free the old texture data */
1167 FREE(texImage
->Data
);
1168 texImage
->Data
= NULL
;
1171 if (ctx
->NewState
& _NEW_PIXEL
)
1172 gl_update_state(ctx
);
1174 ASSERT(ctx
->Driver
.TexImage1D
);
1176 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1177 width
, border
, format
, type
, pixels
,
1178 &ctx
->Unpack
, texObj
, texImage
);
1181 GLubyte
*dummy
= make_null_texture(width
, 1, 1, format
);
1183 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1185 format
, GL_UNSIGNED_BYTE
, dummy
,
1186 &_mesa_native_packing
, texObj
, texImage
);
1192 texObj
->Complete
= GL_FALSE
;
1193 ctx
->NewState
|= _NEW_TEXTURE
;
1195 else if (target
== GL_PROXY_TEXTURE_1D
) {
1196 /* Proxy texture: check for errors and update proxy state */
1197 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1199 postConvWidth
, 1, 1, border
);
1201 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1202 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1203 internalFormat
, format
, type
,
1204 postConvWidth
, 1, 1, border
);
1207 /* if error, clear all proxy texture image parameters */
1208 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1209 clear_proxy_teximage(ctx
->Texture
.Proxy1D
->Image
[level
]);
1214 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1221 _mesa_TexImage2D( GLenum target
, GLint level
, GLint internalFormat
,
1222 GLsizei width
, GLsizei height
, GLint border
,
1223 GLenum format
, GLenum type
,
1224 const GLvoid
*pixels
)
1226 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1227 GET_CURRENT_CONTEXT(ctx
);
1228 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1230 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,&postConvHeight
);
1232 if (target
== GL_TEXTURE_2D
||
1233 (ctx
->Extensions
.ARB_texture_cube_map
&&
1234 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1235 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
1236 /* non-proxy target */
1237 struct gl_texture_unit
*texUnit
;
1238 struct gl_texture_object
*texObj
;
1239 struct gl_texture_image
*texImage
;
1241 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1242 format
, type
, 2, postConvWidth
, postConvHeight
,
1244 return; /* error was recorded */
1247 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1248 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1249 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1252 texImage
= _mesa_alloc_texture_image();
1253 set_tex_image(texObj
, target
, level
, texImage
);
1255 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1259 else if (texImage
->Data
) {
1260 /* free the old texture data */
1261 FREE(texImage
->Data
);
1262 texImage
->Data
= NULL
;
1265 if (ctx
->NewState
& _NEW_PIXEL
)
1266 gl_update_state(ctx
);
1268 ASSERT(ctx
->Driver
.TexImage2D
);
1270 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1271 width
, height
, border
, format
, type
, pixels
,
1272 &ctx
->Unpack
, texObj
, texImage
);
1275 GLubyte
*dummy
= make_null_texture(width
, height
, 1, format
);
1277 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1278 width
, height
, border
,
1279 format
, GL_UNSIGNED_BYTE
, dummy
,
1280 &_mesa_native_packing
, texObj
, texImage
);
1286 texObj
->Complete
= GL_FALSE
;
1287 ctx
->NewState
|= _NEW_TEXTURE
;
1289 else if (target
== GL_PROXY_TEXTURE_2D
) {
1290 /* Proxy texture: check for errors and update proxy state */
1291 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1293 postConvWidth
, postConvHeight
, 1, border
);
1295 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1296 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1297 internalFormat
, format
, type
,
1298 postConvWidth
, postConvHeight
, 1, border
);
1301 /* if error, clear all proxy texture image parameters */
1302 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1303 clear_proxy_teximage(ctx
->Texture
.Proxy2D
->Image
[level
]);
1308 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1315 * Called by the API or display list executor.
1316 * Note that width and height include the border.
1319 _mesa_TexImage3D( GLenum target
, GLint level
, GLint internalFormat
,
1320 GLsizei width
, GLsizei height
, GLsizei depth
,
1321 GLint border
, GLenum format
, GLenum type
,
1322 const GLvoid
*pixels
)
1324 GET_CURRENT_CONTEXT(ctx
);
1325 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1327 if (target
== GL_TEXTURE_3D
) {
1328 struct gl_texture_unit
*texUnit
;
1329 struct gl_texture_object
*texObj
;
1330 struct gl_texture_image
*texImage
;
1332 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1333 format
, type
, 3, width
, height
, depth
, border
)) {
1334 return; /* error was recorded */
1337 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1338 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1339 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1342 texImage
= _mesa_alloc_texture_image();
1343 texObj
->Image
[level
] = texImage
;
1345 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
1349 else if (texImage
->Data
) {
1350 FREE(texImage
->Data
);
1351 texImage
->Data
= NULL
;
1354 if (ctx
->NewState
& _NEW_PIXEL
)
1355 gl_update_state(ctx
);
1357 ASSERT(ctx
->Driver
.TexImage3D
);
1359 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, internalFormat
,
1360 width
, height
, depth
, border
,
1361 format
, type
, pixels
,
1362 &ctx
->Unpack
, texObj
, texImage
);
1365 GLubyte
*dummy
= make_null_texture(width
, height
, depth
, format
);
1367 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, internalFormat
,
1368 width
, height
, depth
, border
,
1369 format
, GL_UNSIGNED_BYTE
, dummy
,
1370 &_mesa_native_packing
, texObj
, texImage
);
1376 texObj
->Complete
= GL_FALSE
;
1377 ctx
->NewState
|= _NEW_TEXTURE
;
1379 else if (target
== GL_PROXY_TEXTURE_3D
) {
1380 /* Proxy texture: check for errors and update proxy state */
1381 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1382 format
, type
, 3, width
, height
, depth
, border
);
1384 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1385 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1386 internalFormat
, format
, type
,
1387 width
, height
, depth
, border
);
1390 /* if error, clear all proxy texture image parameters */
1391 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1392 clear_proxy_teximage(ctx
->Texture
.Proxy3D
->Image
[level
]);
1397 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1404 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
1405 GLsizei width
, GLsizei height
, GLsizei depth
,
1406 GLint border
, GLenum format
, GLenum type
,
1407 const GLvoid
*pixels
)
1409 _mesa_TexImage3D(target
, level
, (GLint
) internalFormat
, width
, height
,
1410 depth
, border
, format
, type
, pixels
);
1416 _mesa_TexSubImage1D( GLenum target
, GLint level
,
1417 GLint xoffset
, GLsizei width
,
1418 GLenum format
, GLenum type
,
1419 const GLvoid
*pixels
)
1421 GLsizei postConvWidth
= width
;
1422 GET_CURRENT_CONTEXT(ctx
);
1423 struct gl_texture_unit
*texUnit
;
1424 struct gl_texture_object
*texObj
;
1425 struct gl_texture_image
*texImage
;
1427 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1429 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
1430 postConvWidth
, 1, 1, format
, type
)) {
1431 return; /* error was detected */
1434 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1435 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1436 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1439 if (width
== 0 || !pixels
)
1440 return; /* no-op, not an error */
1442 if (ctx
->NewState
& _NEW_PIXEL
)
1443 gl_update_state(ctx
);
1445 ASSERT(ctx
->Driver
.TexSubImage1D
);
1446 (*ctx
->Driver
.TexSubImage1D
)(ctx
, target
, level
, xoffset
, width
,
1447 format
, type
, pixels
, &ctx
->Unpack
,
1453 _mesa_TexSubImage2D( GLenum target
, GLint level
,
1454 GLint xoffset
, GLint yoffset
,
1455 GLsizei width
, GLsizei height
,
1456 GLenum format
, GLenum type
,
1457 const GLvoid
*pixels
)
1459 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1460 GET_CURRENT_CONTEXT(ctx
);
1461 struct gl_texture_unit
*texUnit
;
1462 struct gl_texture_object
*texObj
;
1463 struct gl_texture_image
*texImage
;
1465 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,&postConvHeight
);
1467 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1468 postConvWidth
, postConvHeight
, 1, format
, type
)) {
1469 return; /* error was detected */
1472 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1473 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1474 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1477 if (width
== 0 || height
== 0 || !pixels
)
1478 return; /* no-op, not an error */
1480 if (ctx
->NewState
& _NEW_PIXEL
)
1481 gl_update_state(ctx
);
1483 ASSERT(ctx
->Driver
.TexSubImage2D
);
1484 (*ctx
->Driver
.TexSubImage2D
)(ctx
, target
, level
, xoffset
, yoffset
,
1485 width
, height
, format
, type
, pixels
,
1486 &ctx
->Unpack
, texObj
, texImage
);
1492 _mesa_TexSubImage3D( GLenum target
, GLint level
,
1493 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1494 GLsizei width
, GLsizei height
, GLsizei depth
,
1495 GLenum format
, GLenum type
,
1496 const GLvoid
*pixels
)
1498 GET_CURRENT_CONTEXT(ctx
);
1499 struct gl_texture_unit
*texUnit
;
1500 struct gl_texture_object
*texObj
;
1501 struct gl_texture_image
*texImage
;
1503 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
1504 width
, height
, depth
, format
, type
)) {
1505 return; /* error was detected */
1508 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1509 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1510 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1513 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
1514 return; /* no-op, not an error */
1516 if (ctx
->NewState
& _NEW_PIXEL
)
1517 gl_update_state(ctx
);
1519 ASSERT(ctx
->Driver
.TexSubImage3D
);
1520 (*ctx
->Driver
.TexSubImage3D
)(ctx
, target
, level
,
1521 xoffset
, yoffset
, zoffset
,
1522 width
, height
, depth
,
1523 format
, type
, pixels
,
1524 &ctx
->Unpack
, texObj
, texImage
);
1530 * Read an RGBA image from the frame buffer.
1531 * This is used by glCopyTex[Sub]Image[12]D().
1532 * Input: ctx - the context
1533 * x, y - lower left corner
1534 * width, height - size of region to read
1535 * Return: pointer to block of GL_RGBA, GLchan data.
1538 read_color_image( GLcontext
*ctx
, GLint x
, GLint y
,
1539 GLsizei width
, GLsizei height
)
1542 GLchan
*image
, *dst
;
1544 image
= (GLchan
*) MALLOC(width
* height
* 4 * sizeof(GLchan
));
1548 /* Select buffer to read from */
1549 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->ReadBuffer
,
1550 ctx
->Pixel
.DriverReadBuffer
);
1556 for (i
= 0; i
< height
; i
++) {
1557 gl_read_rgba_span( ctx
, ctx
->ReadBuffer
, width
, x
, y
+ i
,
1558 (GLchan (*)[4]) dst
);
1564 /* Read from draw buffer (the default) */
1565 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->DrawBuffer
,
1566 ctx
->Color
.DriverDrawBuffer
);
1574 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
1575 GLenum internalFormat
,
1577 GLsizei width
, GLint border
)
1579 GLsizei postConvWidth
= width
;
1580 GET_CURRENT_CONTEXT(ctx
);
1581 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1583 if (ctx
->NewState
& _NEW_PIXEL
)
1584 gl_update_state(ctx
);
1586 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1588 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
1589 postConvWidth
, 1, border
))
1592 if (ctx
->_ImageTransferState
|| !ctx
->Driver
.CopyTexImage1D
1593 || !(*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
,
1594 internalFormat
, x
, y
, width
, border
)) {
1595 struct gl_pixelstore_attrib unpackSave
;
1597 /* get image from framebuffer */
1598 GLchan
*image
= read_color_image( ctx
, x
, y
, width
, 1 );
1600 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D" );
1604 /* call glTexImage1D to redefine the texture */
1605 unpackSave
= ctx
->Unpack
;
1606 ctx
->Unpack
= _mesa_native_packing
;
1607 (*ctx
->Exec
->TexImage1D
)( target
, level
, internalFormat
, width
,
1608 border
, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
1609 ctx
->Unpack
= unpackSave
;
1618 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
1619 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1622 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1623 GET_CURRENT_CONTEXT(ctx
);
1624 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1626 if (ctx
->NewState
& _NEW_PIXEL
)
1627 gl_update_state(ctx
);
1629 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,&postConvHeight
);
1631 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
1632 postConvWidth
, postConvHeight
, border
))
1635 if (ctx
->_ImageTransferState
|| !ctx
->Driver
.CopyTexImage2D
1636 || !(*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
,
1637 internalFormat
, x
, y
, width
, height
, border
)) {
1638 struct gl_pixelstore_attrib unpackSave
;
1640 /* get image from framebuffer */
1641 GLchan
*image
= read_color_image( ctx
, x
, y
, width
, height
);
1643 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D" );
1647 /* call glTexImage2D to redefine the texture */
1648 unpackSave
= ctx
->Unpack
;
1649 ctx
->Unpack
= _mesa_native_packing
;
1650 (ctx
->Exec
->TexImage2D
)( target
, level
, internalFormat
, width
,
1651 height
, border
, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
1652 ctx
->Unpack
= unpackSave
;
1661 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
1662 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
1664 GLsizei postConvWidth
= width
;
1665 GET_CURRENT_CONTEXT(ctx
);
1666 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1668 if (ctx
->NewState
& _NEW_PIXEL
)
1669 gl_update_state(ctx
);
1671 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1673 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
1674 xoffset
, 0, 0, postConvWidth
, 1))
1677 if (ctx
->_ImageTransferState
|| !ctx
->Driver
.CopyTexSubImage1D
1678 || !(*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
,
1679 xoffset
, x
, y
, width
)) {
1680 struct gl_texture_unit
*texUnit
;
1681 struct gl_texture_image
*teximage
;
1682 struct gl_pixelstore_attrib unpackSave
;
1685 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1686 teximage
= texUnit
->Current1D
->Image
[level
];
1689 /* get image from frame buffer */
1690 image
= read_color_image(ctx
, x
, y
, width
, 1);
1692 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage1D" );
1696 /* now call glTexSubImage1D to do the real work */
1697 unpackSave
= ctx
->Unpack
;
1698 ctx
->Unpack
= _mesa_native_packing
;
1699 _mesa_TexSubImage1D(target
, level
, xoffset
, width
,
1700 GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
1701 ctx
->Unpack
= unpackSave
;
1710 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
1711 GLint xoffset
, GLint yoffset
,
1712 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1714 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1715 GET_CURRENT_CONTEXT(ctx
);
1716 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1718 if (ctx
->NewState
& _NEW_PIXEL
)
1719 gl_update_state(ctx
);
1721 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,&postConvHeight
);
1723 if (copytexsubimage_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1724 postConvWidth
, postConvHeight
))
1727 if (ctx
->_ImageTransferState
|| !ctx
->Driver
.CopyTexSubImage2D
1728 || !(*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
1729 xoffset
, yoffset
, x
, y
, width
, height
)) {
1730 struct gl_texture_unit
*texUnit
;
1731 struct gl_texture_image
*teximage
;
1732 struct gl_pixelstore_attrib unpackSave
;
1735 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1736 teximage
= texUnit
->Current2D
->Image
[level
];
1739 /* get image from frame buffer */
1740 image
= read_color_image(ctx
, x
, y
, width
, height
);
1742 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage2D" );
1746 /* now call glTexSubImage2D to do the real work */
1747 unpackSave
= ctx
->Unpack
;
1748 ctx
->Unpack
= _mesa_native_packing
;
1749 _mesa_TexSubImage2D(target
, level
, xoffset
, yoffset
, width
, height
,
1750 GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
1751 ctx
->Unpack
= unpackSave
;
1760 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
1761 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1762 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1764 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1765 GET_CURRENT_CONTEXT(ctx
);
1766 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1768 if (ctx
->NewState
& _NEW_PIXEL
)
1769 gl_update_state(ctx
);
1771 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,&postConvHeight
);
1773 if (copytexsubimage_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
,
1774 zoffset
, postConvWidth
, postConvHeight
))
1777 if (ctx
->_ImageTransferState
|| !ctx
->Driver
.CopyTexSubImage3D
1778 || !(*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
1779 xoffset
, yoffset
, zoffset
, x
, y
, width
, height
)) {
1780 struct gl_texture_unit
*texUnit
;
1781 struct gl_texture_image
*teximage
;
1782 struct gl_pixelstore_attrib unpackSave
;
1785 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1786 teximage
= texUnit
->Current3D
->Image
[level
];
1789 /* get image from frame buffer */
1790 image
= read_color_image(ctx
, x
, y
, width
, height
);
1792 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage2D" );
1796 /* now call glTexSubImage2D to do the real work */
1797 unpackSave
= ctx
->Unpack
;
1798 ctx
->Unpack
= _mesa_native_packing
;
1799 _mesa_TexSubImage3D(target
, level
, xoffset
, yoffset
, zoffset
,
1800 width
, height
, 1, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
1801 ctx
->Unpack
= unpackSave
;
1810 _mesa_CompressedTexImage1DARB(GLenum target
, GLint level
,
1811 GLenum internalFormat
, GLsizei width
,
1812 GLint border
, GLsizei imageSize
,
1815 GET_CURRENT_CONTEXT(ctx
);
1816 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1818 switch (internalFormat
) {
1819 case GL_COMPRESSED_ALPHA_ARB
:
1820 case GL_COMPRESSED_LUMINANCE_ARB
:
1821 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
1822 case GL_COMPRESSED_INTENSITY_ARB
:
1823 case GL_COMPRESSED_RGB_ARB
:
1824 case GL_COMPRESSED_RGBA_ARB
:
1825 gl_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB");
1828 /* silence compiler warning */
1832 if (target
== GL_TEXTURE_1D
) {
1833 struct gl_texture_unit
*texUnit
;
1834 struct gl_texture_object
*texObj
;
1835 struct gl_texture_image
*texImage
;
1837 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1838 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
1839 return; /* error in texture image was detected */
1842 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1843 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1844 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1847 texImage
= _mesa_alloc_texture_image();
1848 texObj
->Image
[level
] = texImage
;
1850 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage1DARB");
1854 else if (texImage
->Data
) {
1855 FREE(texImage
->Data
);
1856 texImage
->Data
= NULL
;
1859 if (ctx
->Extensions
.ARB_texture_compression
) {
1860 ASSERT(ctx
->Driver
.CompressedTexImage1D
);
1861 (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
,
1862 internalFormat
, width
, border
,
1865 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
1869 texObj
->Complete
= GL_FALSE
;
1870 ctx
->NewState
|= _NEW_TEXTURE
;
1872 else if (target
== GL_PROXY_TEXTURE_1D
) {
1873 /* Proxy texture: check for errors and update proxy state */
1874 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1875 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
);
1877 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1878 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1879 internalFormat
, GL_NONE
, GL_NONE
,
1880 width
, 1, 1, border
);
1883 /* if error, clear all proxy texture image parameters */
1884 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1885 clear_proxy_teximage(ctx
->Texture
.Proxy1D
->Image
[level
]);
1890 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB(target)" );
1897 _mesa_CompressedTexImage2DARB(GLenum target
, GLint level
,
1898 GLenum internalFormat
, GLsizei width
,
1899 GLsizei height
, GLint border
, GLsizei imageSize
,
1902 GET_CURRENT_CONTEXT(ctx
);
1903 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1905 switch (internalFormat
) {
1906 case GL_COMPRESSED_ALPHA_ARB
:
1907 case GL_COMPRESSED_LUMINANCE_ARB
:
1908 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
1909 case GL_COMPRESSED_INTENSITY_ARB
:
1910 case GL_COMPRESSED_RGB_ARB
:
1911 case GL_COMPRESSED_RGBA_ARB
:
1912 gl_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB");
1915 /* silence compiler warning */
1919 if (target
== GL_TEXTURE_2D
||
1920 (ctx
->Extensions
.ARB_texture_cube_map
&&
1921 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1922 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
1923 struct gl_texture_unit
*texUnit
;
1924 struct gl_texture_object
*texObj
;
1925 struct gl_texture_image
*texImage
;
1927 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1928 GL_NONE
, GL_NONE
, 1, width
, height
, 1, border
)) {
1929 return; /* error in texture image was detected */
1932 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1933 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1934 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1937 texImage
= _mesa_alloc_texture_image();
1938 texObj
->Image
[level
] = texImage
;
1940 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
1944 else if (texImage
->Data
) {
1945 FREE(texImage
->Data
);
1946 texImage
->Data
= NULL
;
1949 if (ctx
->Extensions
.ARB_texture_compression
) {
1950 ASSERT(ctx
->Driver
.CompressedTexImage2D
);
1951 (*ctx
->Driver
.CompressedTexImage2D
)(ctx
, target
, level
,
1952 internalFormat
, width
, height
,
1953 border
, imageSize
, data
,
1955 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
1959 texObj
->Complete
= GL_FALSE
;
1960 ctx
->NewState
|= _NEW_TEXTURE
;
1962 else if (target
== GL_PROXY_TEXTURE_2D
) {
1963 /* Proxy texture: check for errors and update proxy state */
1964 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1965 GL_NONE
, GL_NONE
, 2, width
, height
, 1, border
);
1967 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1968 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1969 internalFormat
, GL_NONE
, GL_NONE
,
1970 width
, height
, 1, border
);
1973 /* if error, clear all proxy texture image parameters */
1974 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1975 clear_proxy_teximage(ctx
->Texture
.Proxy2D
->Image
[level
]);
1980 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB(target)" );
1987 _mesa_CompressedTexImage3DARB(GLenum target
, GLint level
,
1988 GLenum internalFormat
, GLsizei width
,
1989 GLsizei height
, GLsizei depth
, GLint border
,
1990 GLsizei imageSize
, const GLvoid
*data
)
1992 GET_CURRENT_CONTEXT(ctx
);
1993 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1995 switch (internalFormat
) {
1996 case GL_COMPRESSED_ALPHA_ARB
:
1997 case GL_COMPRESSED_LUMINANCE_ARB
:
1998 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
1999 case GL_COMPRESSED_INTENSITY_ARB
:
2000 case GL_COMPRESSED_RGB_ARB
:
2001 case GL_COMPRESSED_RGBA_ARB
:
2002 gl_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB");
2005 /* silence compiler warning */
2009 if (target
== GL_TEXTURE_3D
) {
2010 struct gl_texture_unit
*texUnit
;
2011 struct gl_texture_object
*texObj
;
2012 struct gl_texture_image
*texImage
;
2014 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2015 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
)) {
2016 return; /* error in texture image was detected */
2019 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2020 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2021 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2024 texImage
= _mesa_alloc_texture_image();
2025 texObj
->Image
[level
] = texImage
;
2027 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage3DARB");
2031 else if (texImage
->Data
) {
2032 FREE(texImage
->Data
);
2033 texImage
->Data
= NULL
;
2036 if (ctx
->Extensions
.ARB_texture_compression
) {
2037 ASSERT(ctx
->Driver
.CompressedTexImage3D
);
2038 (*ctx
->Driver
.CompressedTexImage3D
)(ctx
, target
, level
,
2040 width
, height
, depth
,
2041 border
, imageSize
, data
,
2043 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2047 texObj
->Complete
= GL_FALSE
;
2048 ctx
->NewState
|= _NEW_TEXTURE
;
2050 else if (target
== GL_PROXY_TEXTURE_3D
) {
2051 /* Proxy texture: check for errors and update proxy state */
2052 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2053 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
);
2055 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2056 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2057 internalFormat
, GL_NONE
, GL_NONE
,
2058 width
, height
, depth
, border
);
2061 /* if error, clear all proxy texture image parameters */
2062 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
2063 clear_proxy_teximage(ctx
->Texture
.Proxy3D
->Image
[level
]);
2068 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB(target)" );
2075 _mesa_CompressedTexSubImage1DARB(GLenum target
, GLint level
, GLint xoffset
,
2076 GLsizei width
, GLenum format
,
2077 GLsizei imageSize
, const GLvoid
*data
)
2079 GET_CURRENT_CONTEXT(ctx
);
2080 struct gl_texture_unit
*texUnit
;
2081 struct gl_texture_object
*texObj
;
2082 struct gl_texture_image
*texImage
;
2084 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
2085 width
, 1, 1, format
, GL_NONE
)) {
2086 return; /* error was detected */
2089 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2090 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2091 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2094 if (width
== 0 || !data
)
2095 return; /* no-op, not an error */
2097 if (ctx
->Driver
.CompressedTexSubImage1D
) {
2098 (*ctx
->Driver
.CompressedTexSubImage1D
)(ctx
, target
, level
,
2100 format
, imageSize
, data
,
2107 _mesa_CompressedTexSubImage2DARB(GLenum target
, GLint level
, GLint xoffset
,
2108 GLint yoffset
, GLsizei width
, GLsizei height
,
2109 GLenum format
, GLsizei imageSize
,
2112 GET_CURRENT_CONTEXT(ctx
);
2113 struct gl_texture_unit
*texUnit
;
2114 struct gl_texture_object
*texObj
;
2115 struct gl_texture_image
*texImage
;
2117 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2118 width
, height
, 1, format
, GL_NONE
)) {
2119 return; /* error was detected */
2122 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2123 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2124 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2127 if (width
== 0 || height
== 0 || !data
)
2128 return; /* no-op, not an error */
2130 if (ctx
->Driver
.CompressedTexSubImage2D
) {
2131 (*ctx
->Driver
.CompressedTexSubImage2D
)(ctx
, target
, level
,
2132 xoffset
, yoffset
, width
, height
,
2133 format
, imageSize
, data
,
2140 _mesa_CompressedTexSubImage3DARB(GLenum target
, GLint level
, GLint xoffset
,
2141 GLint yoffset
, GLint zoffset
, GLsizei width
,
2142 GLsizei height
, GLsizei depth
, GLenum format
,
2143 GLsizei imageSize
, const GLvoid
*data
)
2145 GET_CURRENT_CONTEXT(ctx
);
2146 struct gl_texture_unit
*texUnit
;
2147 struct gl_texture_object
*texObj
;
2148 struct gl_texture_image
*texImage
;
2150 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2151 width
, height
, depth
, format
, GL_NONE
)) {
2152 return; /* error was detected */
2155 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2156 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2157 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2160 if (width
== 0 || height
== 0 || depth
== 0 || !data
)
2161 return; /* no-op, not an error */
2163 if (ctx
->Driver
.CompressedTexSubImage3D
) {
2164 (*ctx
->Driver
.CompressedTexSubImage3D
)(ctx
, target
, level
,
2165 xoffset
, yoffset
, zoffset
,
2166 width
, height
, depth
,
2167 format
, imageSize
, data
,
2174 _mesa_GetCompressedTexImageARB(GLenum target
, GLint level
, GLvoid
*img
)
2176 GET_CURRENT_CONTEXT(ctx
);
2177 const struct gl_texture_unit
*texUnit
;
2178 const struct gl_texture_object
*texObj
;
2179 struct gl_texture_image
*texImage
;
2181 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2183 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
2184 gl_error( ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)" );
2188 if (is_proxy_target(target
)) {
2189 gl_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB(target)");
2193 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2194 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2195 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2198 /* invalid mipmap level */
2199 gl_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
2203 if (!texImage
->IsCompressed
) {
2204 gl_error(ctx
, GL_INVALID_OPERATION
, "glGetCompressedTexImageARB");
2211 if (ctx
->Extensions
.ARB_texture_compression
) {
2212 ASSERT(ctx
->Driver
.GetCompressedTexImage
);
2213 (*ctx
->Driver
.GetCompressedTexImage
)(ctx
, target
, level
, img
, texObj
,