3 * Mesa 3-D graphics library
6 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
45 * Mesa's native texture datatype is GLubyte. Native formats are
46 * GL_ALPHA, GL_LUMINANCE, GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, GL_RGBA,
48 * Device drivers are free to implement any internal format they want.
53 static void PrintTexture(const struct gl_texture_image
*img
)
56 GLubyte
*data
= img
->Data
;
59 printf("No texture data\n");
63 switch (img
->Format
) {
70 case GL_LUMINANCE_ALPHA
:
80 gl_problem(NULL
, "error in PrintTexture\n");
85 for (i
= 0; i
< img
->Height
; i
++) {
86 for (j
= 0; j
< img
->Width
; j
++) {
88 printf("%02x ", data
[0]);
90 printf("%02x%02x ", data
[0], data
[1]);
92 printf("%02x%02x%02x ", data
[0], data
[1], data
[2]);
94 printf("%02x%02x%02x%02x ", data
[0], data
[1], data
[2], data
[3]);
105 * Compute log base 2 of n.
106 * If n isn't an exact power of two return -1.
134 * Given an internal texture format enum or 1, 2, 3, 4 return the
135 * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE,
136 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.
137 * Return -1 if invalid enum.
140 _mesa_base_tex_format( GLint format
)
157 case GL_LUMINANCE_ALPHA
:
158 case GL_LUMINANCE4_ALPHA4
:
159 case GL_LUMINANCE6_ALPHA2
:
160 case GL_LUMINANCE8_ALPHA8
:
161 case GL_LUMINANCE12_ALPHA4
:
162 case GL_LUMINANCE12_ALPHA12
:
163 case GL_LUMINANCE16_ALPHA16
:
164 return GL_LUMINANCE_ALPHA
;
192 case GL_COLOR_INDEX1_EXT
:
193 case GL_COLOR_INDEX2_EXT
:
194 case GL_COLOR_INDEX4_EXT
:
195 case GL_COLOR_INDEX8_EXT
:
196 case GL_COLOR_INDEX12_EXT
:
197 case GL_COLOR_INDEX16_EXT
:
198 return GL_COLOR_INDEX
;
200 return -1; /* error */
207 * Given an internal texture format enum or 1, 2, 3, 4 return the
208 * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE,
209 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA. Return the
210 * number of components for the format. Return -1 if invalid enum.
213 components_in_intformat( GLint format
)
230 case GL_LUMINANCE_ALPHA
:
231 case GL_LUMINANCE4_ALPHA4
:
232 case GL_LUMINANCE6_ALPHA2
:
233 case GL_LUMINANCE8_ALPHA8
:
234 case GL_LUMINANCE12_ALPHA4
:
235 case GL_LUMINANCE12_ALPHA12
:
236 case GL_LUMINANCE16_ALPHA16
:
265 case GL_COLOR_INDEX1_EXT
:
266 case GL_COLOR_INDEX2_EXT
:
267 case GL_COLOR_INDEX4_EXT
:
268 case GL_COLOR_INDEX8_EXT
:
269 case GL_COLOR_INDEX12_EXT
:
270 case GL_COLOR_INDEX16_EXT
:
273 return -1; /* error */
280 * Examine the texImage->Format field and set the Red, Green, Blue, etc
281 * texel component sizes to default values.
282 * These fields are set only here by core Mesa but device drivers may
283 * overwritting these fields to indicate true texel resolution.
286 set_teximage_component_sizes( struct gl_texture_image
*texImage
)
288 switch (texImage
->Format
) {
290 texImage
->RedBits
= 0;
291 texImage
->GreenBits
= 0;
292 texImage
->BlueBits
= 0;
293 texImage
->AlphaBits
= 8;
294 texImage
->IntensityBits
= 0;
295 texImage
->LuminanceBits
= 0;
296 texImage
->IndexBits
= 0;
299 texImage
->RedBits
= 0;
300 texImage
->GreenBits
= 0;
301 texImage
->BlueBits
= 0;
302 texImage
->AlphaBits
= 0;
303 texImage
->IntensityBits
= 0;
304 texImage
->LuminanceBits
= 8;
305 texImage
->IndexBits
= 0;
307 case GL_LUMINANCE_ALPHA
:
308 texImage
->RedBits
= 0;
309 texImage
->GreenBits
= 0;
310 texImage
->BlueBits
= 0;
311 texImage
->AlphaBits
= 8;
312 texImage
->IntensityBits
= 0;
313 texImage
->LuminanceBits
= 8;
314 texImage
->IndexBits
= 0;
317 texImage
->RedBits
= 0;
318 texImage
->GreenBits
= 0;
319 texImage
->BlueBits
= 0;
320 texImage
->AlphaBits
= 0;
321 texImage
->IntensityBits
= 8;
322 texImage
->LuminanceBits
= 0;
323 texImage
->IndexBits
= 0;
326 texImage
->RedBits
= 8;
327 texImage
->GreenBits
= 0;
328 texImage
->BlueBits
= 0;
329 texImage
->AlphaBits
= 0;
330 texImage
->IntensityBits
= 0;
331 texImage
->LuminanceBits
= 0;
332 texImage
->IndexBits
= 0;
335 texImage
->RedBits
= 0;
336 texImage
->GreenBits
= 8;
337 texImage
->BlueBits
= 0;
338 texImage
->AlphaBits
= 0;
339 texImage
->IntensityBits
= 0;
340 texImage
->LuminanceBits
= 0;
341 texImage
->IndexBits
= 0;
344 texImage
->RedBits
= 0;
345 texImage
->GreenBits
= 0;
346 texImage
->BlueBits
= 8;
347 texImage
->AlphaBits
= 0;
348 texImage
->IntensityBits
= 0;
349 texImage
->LuminanceBits
= 0;
350 texImage
->IndexBits
= 0;
354 texImage
->RedBits
= 8;
355 texImage
->GreenBits
= 8;
356 texImage
->BlueBits
= 8;
357 texImage
->AlphaBits
= 0;
358 texImage
->IntensityBits
= 0;
359 texImage
->LuminanceBits
= 0;
360 texImage
->IndexBits
= 0;
365 texImage
->RedBits
= 8;
366 texImage
->GreenBits
= 8;
367 texImage
->BlueBits
= 8;
368 texImage
->AlphaBits
= 8;
369 texImage
->IntensityBits
= 0;
370 texImage
->LuminanceBits
= 0;
371 texImage
->IndexBits
= 0;
374 texImage
->RedBits
= 0;
375 texImage
->GreenBits
= 0;
376 texImage
->BlueBits
= 0;
377 texImage
->AlphaBits
= 0;
378 texImage
->IntensityBits
= 0;
379 texImage
->LuminanceBits
= 0;
380 texImage
->IndexBits
= 8;
383 gl_problem(NULL
, "unexpected format in set_teximage_component_sizes");
389 * Given a texture unit and a texture target, return the corresponding
392 static struct gl_texture_object
*
393 select_tex_object(struct gl_texture_unit
*unit
, GLenum target
)
397 return unit
->CurrentD
[1];
399 return unit
->CurrentD
[2];
401 return unit
->CurrentD
[3];
402 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
403 return unit
->CurrentPosX
;
404 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
405 return unit
->CurrentNegX
;
406 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
407 return unit
->CurrentPosY
;
408 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
409 return unit
->CurrentNegY
;
410 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
411 return unit
->CurrentPosZ
;
412 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
413 return unit
->CurrentNegZ
;
415 gl_problem(NULL
, "bad target in select_tex_object()");
422 * Return new gl_texture_image struct with all fields initialized to zero.
424 struct gl_texture_image
*
425 _mesa_alloc_texture_image( void )
427 return CALLOC_STRUCT(gl_texture_image
);
433 * Initialize most fields of a gl_texture_image struct.
436 init_texture_image( struct gl_texture_image
*img
,
437 GLsizei width
, GLsizei height
, GLsizei depth
,
438 GLint border
, GLenum internalFormat
)
442 img
->Format
= (GLenum
) _mesa_base_tex_format(internalFormat
);
443 set_teximage_component_sizes( img
);
444 img
->IntFormat
= (GLenum
) internalFormat
;
445 img
->Border
= border
;
447 img
->Height
= height
;
449 img
->WidthLog2
= logbase2(width
- 2 * border
);
450 if (height
== 1) /* 1-D texture */
453 img
->HeightLog2
= logbase2(height
- 2 * border
);
454 if (depth
== 1) /* 2-D texture */
457 img
->DepthLog2
= logbase2(depth
- 2 * border
);
458 img
->Width2
= 1 << img
->WidthLog2
;
459 img
->Height2
= 1 << img
->HeightLog2
;
460 img
->Depth2
= 1 << img
->DepthLog2
;
461 img
->MaxLog2
= MAX2(img
->WidthLog2
, img
->HeightLog2
);
467 _mesa_free_texture_image( struct gl_texture_image
*teximage
)
469 if (teximage
->Data
) {
470 FREE( teximage
->Data
);
471 teximage
->Data
= NULL
;
478 /* Need this to prevent an out-of-bounds memory access when using
479 * X86 optimized code.
482 # define EXTRA_BYTE 1
484 # define EXTRA_BYTE 0
490 * Called by glTexImage[123]D. Fill in a texture image with data given
491 * by the client. All pixel transfer and unpack modes are handled here.
492 * NOTE: All texture image parameters should have already been error checked.
495 make_texture_image( GLcontext
*ctx
,
496 struct gl_texture_image
*texImage
,
497 GLenum srcFormat
, GLenum srcType
, const GLvoid
*pixels
,
498 const struct gl_pixelstore_attrib
*unpacking
)
500 GLint components
, numPixels
;
501 GLint internalFormat
, width
, height
, depth
, border
;
505 ASSERT(!texImage
->Data
);
509 internalFormat
= texImage
->IntFormat
;
510 width
= texImage
->Width
;
511 height
= texImage
->Height
;
512 depth
= texImage
->Depth
;
513 border
= texImage
->Border
;
514 components
= components_in_intformat(internalFormat
);
519 ASSERT(border
== 0 || border
== 1);
524 numPixels
= width
* height
* depth
;
526 texImage
->Data
= (GLubyte
*) MALLOC(numPixels
* components
+ EXTRA_BYTE
);
528 return; /* out of memory */
531 * OK, the texture image struct has been initialized and the texture
532 * image memory has been allocated.
533 * Now fill in the texture image from the source data.
534 * This includes applying the pixel transfer operations.
537 /* try common 2D texture cases first */
538 if (!ctx
->Pixel
.ScaleOrBiasRGBA
&& !ctx
->Pixel
.MapColorFlag
539 && !ctx
->Pixel
.IndexOffset
&& !ctx
->Pixel
.IndexShift
540 && srcType
== GL_UNSIGNED_BYTE
&& depth
== 1) {
542 if (srcFormat
== internalFormat
||
543 (srcFormat
== GL_LUMINANCE
&& internalFormat
== 1) ||
544 (srcFormat
== GL_LUMINANCE_ALPHA
&& internalFormat
== 2) ||
545 (srcFormat
== GL_RGB
&& internalFormat
== 3) ||
546 (srcFormat
== GL_RGBA
&& internalFormat
== 4)) {
547 /* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA,
548 * GL_LUMINANCE_ALPHA, etc. texture formats.
550 const GLubyte
*src
= (const GLubyte
*) _mesa_image_address(
551 unpacking
, pixels
, width
, height
, srcFormat
, srcType
, 0, 0, 0);
552 const GLint srcStride
= _mesa_image_row_stride(unpacking
, width
,
554 GLubyte
*dst
= texImage
->Data
;
555 GLint dstBytesPerRow
= width
* components
* sizeof(GLubyte
);
556 if (srcStride
== dstBytesPerRow
) {
557 MEMCPY(dst
, src
, height
* dstBytesPerRow
);
561 for (i
= 0; i
< height
; i
++) {
562 MEMCPY(dst
, src
, dstBytesPerRow
);
564 dst
+= dstBytesPerRow
;
567 return; /* all done */
569 else if (srcFormat
== GL_RGBA
&& internalFormat
== GL_RGB
) {
570 /* commonly used by Quake */
571 const GLubyte
*src
= (const GLubyte
*) _mesa_image_address(
572 unpacking
, pixels
, width
, height
, srcFormat
, srcType
, 0, 0, 0);
573 const GLint srcStride
= _mesa_image_row_stride(unpacking
, width
,
575 GLubyte
*dst
= texImage
->Data
;
577 for (i
= 0; i
< height
; i
++) {
578 const GLubyte
*s
= src
;
579 for (j
= 0; j
< width
; j
++) {
580 *dst
++ = *s
++; /*red*/
581 *dst
++ = *s
++; /*green*/
582 *dst
++ = *s
++; /*blue*/
587 return; /* all done */
593 * General case solutions
595 if (texImage
->Format
== GL_COLOR_INDEX
) {
596 /* color index texture */
597 const GLint destBytesPerRow
= width
* components
* sizeof(GLubyte
);
598 const GLenum dstType
= GL_UNSIGNED_BYTE
;
599 GLubyte
*dest
= texImage
->Data
;
601 for (img
= 0; img
< depth
; img
++) {
602 for (row
= 0; row
< height
; row
++) {
603 const GLvoid
*source
= _mesa_image_address(unpacking
,
604 pixels
, width
, height
, srcFormat
, srcType
, img
, row
, 0);
605 _mesa_unpack_index_span(ctx
, width
, dstType
, dest
,
606 srcType
, source
, unpacking
, GL_TRUE
);
607 dest
+= destBytesPerRow
;
612 /* regular, color texture */
613 const GLint destBytesPerRow
= width
* components
* sizeof(GLubyte
);
614 const GLenum dstFormat
= texImage
->Format
;
615 GLubyte
*dest
= texImage
->Data
;
617 for (img
= 0; img
< depth
; img
++) {
618 for (row
= 0; row
< height
; row
++) {
619 const GLvoid
*source
= _mesa_image_address(unpacking
,
620 pixels
, width
, height
, srcFormat
, srcType
, img
, row
, 0);
621 _mesa_unpack_ubyte_color_span(ctx
, width
, dstFormat
, dest
,
622 srcFormat
, srcType
, source
, unpacking
, GL_TRUE
);
623 dest
+= destBytesPerRow
;
632 * glTexImage[123]D can accept a NULL image pointer. In this case we
633 * create a texture image with unspecified image contents per the OpenGL
634 * spec. This function creates an empty image for the given texture image.
637 make_null_texture( struct gl_texture_image
*texImage
)
643 ASSERT(!texImage
->Data
);
645 components
= components_in_intformat(texImage
->IntFormat
);
646 numPixels
= texImage
->Width
* texImage
->Height
* texImage
->Depth
;
648 texImage
->Data
= (GLubyte
*) MALLOC( numPixels
* components
+ EXTRA_BYTE
);
651 * Let's see if anyone finds this. If glTexImage2D() is called with
652 * a NULL image pointer then load the texture image with something
653 * interesting instead of leaving it indeterminate.
655 if (texImage
->Data
) {
656 static const char message
[8][32] = {
660 " X X XXXX XXX XXXXX ",
663 " X X XXXXX XXX X X ",
667 GLubyte
*imgPtr
= texImage
->Data
;
669 for (i
= 0; i
< texImage
->Height
; i
++) {
670 GLint srcRow
= 7 - i
% 8;
671 for (j
= 0; j
< texImage
->Width
; j
++) {
672 GLint srcCol
= j
% 32;
673 GLint texel
= (message
[srcRow
][srcCol
]=='X') ? 255 : 70;
674 for (k
=0;k
<components
;k
++) {
675 *imgPtr
++ = (GLubyte
) texel
;
685 * Test glTexImage[123]D() parameters for errors.
687 * dimensions - must be 1 or 2 or 3
688 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
691 texture_error_check( GLcontext
*ctx
, GLenum target
,
692 GLint level
, GLint internalFormat
,
693 GLenum format
, GLenum type
,
695 GLint width
, GLint height
,
696 GLint depth
, GLint border
)
701 if (dimensions
== 1) {
702 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_1D
);
703 if (target
!= GL_TEXTURE_1D
&& !isProxy
) {
704 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
708 else if (dimensions
== 2) {
709 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_2D
);
710 if (target
!= GL_TEXTURE_2D
&& !isProxy
) {
711 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
715 else if (dimensions
== 3) {
716 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_3D
);
717 if (target
!= GL_TEXTURE_3D
&& !isProxy
) {
718 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
723 gl_problem( ctx
, "bad dims in texture_error_check" );
728 if (border
!= 0 && border
!= 1) {
731 sprintf(message
, "glTexImage%dD(border)", dimensions
);
732 gl_error(ctx
, GL_INVALID_VALUE
, message
);
738 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
739 || logbase2( width
- 2 * border
) < 0) {
742 sprintf(message
, "glTexImage%dD(width)", dimensions
);
743 gl_error(ctx
, GL_INVALID_VALUE
, message
);
749 if (dimensions
>= 2) {
750 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
751 || logbase2( height
- 2 * border
) < 0) {
754 sprintf(message
, "glTexImage%dD(height)", dimensions
);
755 gl_error(ctx
, GL_INVALID_VALUE
, message
);
762 if (dimensions
>= 3) {
763 if (depth
< 2 * border
|| depth
> 2 + ctx
->Const
.MaxTextureSize
764 || logbase2( depth
- 2 * border
) < 0) {
766 gl_error( ctx
, GL_INVALID_VALUE
, "glTexImage3D(depth)" );
773 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
776 sprintf(message
, "glTexImage%dD(level)", dimensions
);
777 gl_error(ctx
, GL_INVALID_VALUE
, message
);
782 iformat
= _mesa_base_tex_format( internalFormat
);
786 sprintf(message
, "glTexImage%dD(internalFormat)", dimensions
);
787 gl_error(ctx
, GL_INVALID_VALUE
, message
);
792 if (!_mesa_is_legal_format_and_type( format
, type
)) {
793 /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
794 * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
798 sprintf(message
, "glTexImage%dD(format or type)", dimensions
);
799 gl_error(ctx
, GL_INVALID_OPERATION
, message
);
804 /* if we get here, the parameters are OK */
811 * Test glTexSubImage[123]D() parameters for errors.
813 * dimensions - must be 1 or 2 or 3
814 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
817 subtexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
818 GLenum target
, GLint level
,
819 GLint xoffset
, GLint yoffset
, GLint zoffset
,
820 GLint width
, GLint height
, GLint depth
,
821 GLenum format
, GLenum type
)
823 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
824 struct gl_texture_image
*destTex
;
826 if (dimensions
== 1) {
827 if (target
!= GL_TEXTURE_1D
) {
828 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(target)" );
832 else if (dimensions
== 2) {
833 if (target
!= GL_TEXTURE_2D
) {
834 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
838 else if (dimensions
== 3) {
839 if (target
!= GL_TEXTURE_3D
) {
840 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3D(target)" );
845 gl_problem( ctx
, "bad dims in texture_error_check" );
849 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
850 gl_error(ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(level)");
856 sprintf(message
, "glTexSubImage%dD(width)", dimensions
);
857 gl_error(ctx
, GL_INVALID_VALUE
, message
);
860 if (height
< 0 && dimensions
> 1) {
862 sprintf(message
, "glTexSubImage%dD(height)", dimensions
);
863 gl_error(ctx
, GL_INVALID_VALUE
, message
);
866 if (depth
< 0 && dimensions
> 2) {
868 sprintf(message
, "glTexSubImage%dD(depth)", dimensions
);
869 gl_error(ctx
, GL_INVALID_VALUE
, message
);
873 destTex
= texUnit
->CurrentD
[2]->Image
[level
];
875 gl_error(ctx
, GL_INVALID_OPERATION
, "glTexSubImage2D");
879 if (xoffset
< -((GLint
)destTex
->Border
)) {
880 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset)");
883 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
884 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset+width)");
887 if (dimensions
> 1) {
888 if (yoffset
< -((GLint
)destTex
->Border
)) {
889 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset)");
892 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
893 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset+height)");
897 if (dimensions
> 2) {
898 if (zoffset
< -((GLint
)destTex
->Border
)) {
899 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset)");
902 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+destTex
->Border
)) {
903 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset+depth)");
908 if (!_mesa_is_legal_format_and_type(format
, type
)) {
910 sprintf(message
, "glTexSubImage%dD(format or type)", dimensions
);
911 gl_error(ctx
, GL_INVALID_ENUM
, message
);
920 * Test glCopyTexImage[12]D() parameters for errors.
921 * Input: dimensions - must be 1 or 2 or 3
922 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
925 copytexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
926 GLenum target
, GLint level
, GLint internalFormat
,
927 GLint width
, GLint height
, GLint border
)
931 if (target
!= GL_TEXTURE_1D
&& target
!= GL_TEXTURE_2D
) {
932 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1/2D(target)" );
936 if (dimensions
== 1 && target
!= GL_TEXTURE_1D
) {
937 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
940 else if (dimensions
== 2 && target
!= GL_TEXTURE_2D
) {
941 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
946 if (border
!=0 && border
!=1) {
948 sprintf(message
, "glCopyTexImage%dD(border)", dimensions
);
949 gl_error(ctx
, GL_INVALID_VALUE
, message
);
954 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
955 || logbase2( width
- 2 * border
) < 0) {
957 sprintf(message
, "glCopyTexImage%dD(width)", dimensions
);
958 gl_error(ctx
, GL_INVALID_VALUE
, message
);
963 if (dimensions
>= 2) {
964 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
965 || logbase2( height
- 2 * border
) < 0) {
967 sprintf(message
, "glCopyTexImage%dD(height)", dimensions
);
968 gl_error(ctx
, GL_INVALID_VALUE
, message
);
974 if (level
<0 || level
>=ctx
->Const
.MaxTextureLevels
) {
976 sprintf(message
, "glCopyTexImage%dD(level)", dimensions
);
977 gl_error(ctx
, GL_INVALID_VALUE
, message
);
981 iformat
= _mesa_base_tex_format( internalFormat
);
984 sprintf(message
, "glCopyTexImage%dD(internalFormat)", dimensions
);
985 gl_error(ctx
, GL_INVALID_VALUE
, message
);
989 /* if we get here, the parameters are OK */
995 copytexsubimage_error_check( GLcontext
*ctx
, GLuint dimensions
,
996 GLenum target
, GLint level
,
997 GLint xoffset
, GLint yoffset
, GLint zoffset
,
998 GLsizei width
, GLsizei height
)
1000 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1001 struct gl_texture_image
*teximage
;
1003 if (dimensions
== 1 && target
!= GL_TEXTURE_1D
) {
1004 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
1007 else if (dimensions
== 2 && target
!= GL_TEXTURE_2D
) {
1008 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1011 else if (dimensions
== 3 && target
!= GL_TEXTURE_3D
) {
1012 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3D(target)" );
1016 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1018 sprintf(message
, "glCopyTexSubImage%dD(level)", dimensions
);
1019 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1025 sprintf(message
, "glCopyTexSubImage%dD(width)", dimensions
);
1026 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1029 if (dimensions
> 1 && height
< 0) {
1031 sprintf(message
, "glCopyTexSubImage%dD(height)", dimensions
);
1032 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1036 teximage
= texUnit
->CurrentD
[dimensions
]->Image
[level
];
1039 sprintf(message
, "glCopyTexSubImage%dD(undefined texture)", dimensions
);
1040 gl_error(ctx
, GL_INVALID_OPERATION
, message
);
1044 if (xoffset
< -((GLint
)teximage
->Border
)) {
1046 sprintf(message
, "glCopyTexSubImage%dD(xoffset)", dimensions
);
1047 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1050 if (xoffset
+width
> (GLint
) (teximage
->Width
+teximage
->Border
)) {
1052 sprintf(message
, "glCopyTexSubImage%dD(xoffset+width)", dimensions
);
1053 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1056 if (dimensions
> 1) {
1057 if (yoffset
< -((GLint
)teximage
->Border
)) {
1059 sprintf(message
, "glCopyTexSubImage%dD(yoffset)", dimensions
);
1060 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1063 /* NOTE: we're adding the border here, not subtracting! */
1064 if (yoffset
+height
> (GLint
) (teximage
->Height
+teximage
->Border
)) {
1066 sprintf(message
, "glCopyTexSubImage%dD(yoffset+height)", dimensions
);
1067 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1072 if (dimensions
> 2) {
1073 if (zoffset
< -((GLint
)teximage
->Border
)) {
1075 sprintf(message
, "glCopyTexSubImage%dD(zoffset)", dimensions
);
1076 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1079 if (zoffset
> (GLint
) (teximage
->Depth
+teximage
->Border
)) {
1081 sprintf(message
, "glCopyTexSubImage%dD(zoffset+depth)", dimensions
);
1082 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1087 /* if we get here, the parameters are OK */
1095 * Called from the API. Note that width includes the border.
1098 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
1099 GLsizei width
, GLint border
, GLenum format
,
1100 GLenum type
, const GLvoid
*pixels
)
1102 GET_CURRENT_CONTEXT(ctx
);
1103 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glTexImage1D");
1105 if (target
==GL_TEXTURE_1D
) {
1106 struct gl_texture_unit
*texUnit
;
1107 struct gl_texture_object
*texObj
;
1108 struct gl_texture_image
*texImage
;
1110 if (texture_error_check( ctx
, target
, level
, internalFormat
,
1111 format
, type
, 1, width
, 1, 1, border
)) {
1112 return; /* error in texture image was detected */
1115 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1116 texObj
= texUnit
->CurrentD
[1];
1117 texImage
= texObj
->Image
[level
];
1120 texImage
= _mesa_alloc_texture_image();
1121 texObj
->Image
[level
] = texImage
;
1123 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
1127 else if (texImage
->Data
) {
1128 FREE(texImage
->Data
);
1129 texImage
->Data
= NULL
;
1132 /* setup the teximage struct's fields */
1133 init_texture_image(texImage
, width
, 1, 1, border
, internalFormat
);
1135 /* process the texture image */
1137 GLboolean retain
= GL_TRUE
;
1138 GLboolean success
= GL_FALSE
;
1139 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
1140 && ctx
->Driver
.TexImage1D
) {
1141 /* let device driver try to use raw image */
1142 success
= (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, format
,
1143 type
, pixels
, &ctx
->Unpack
,
1144 texObj
, texImage
, &retain
);
1146 if (retain
|| !success
) {
1147 /* make internal copy of the texture image */
1148 make_texture_image(ctx
, texImage
, format
, type
,
1149 pixels
, &ctx
->Unpack
);
1150 if (!success
&& ctx
->Driver
.TexImage1D
) {
1151 /* let device driver try to use unpacked image */
1152 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
1153 GL_UNSIGNED_BYTE
, texImage
->Data
,
1154 &_mesa_native_packing
,
1155 texObj
, texImage
, &retain
);
1158 if (!retain
&& texImage
->Data
) {
1159 FREE(texImage
->Data
);
1160 texImage
->Data
= NULL
;
1164 make_null_texture(texImage
);
1165 if (ctx
->Driver
.TexImage1D
) {
1167 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
1168 GL_UNSIGNED_BYTE
, texImage
->Data
,
1169 &_mesa_native_packing
,
1170 texObj
, texImage
, &retain
);
1175 gl_put_texobj_on_dirty_list( ctx
, texObj
);
1176 ctx
->NewState
|= NEW_TEXTURING
;
1178 else if (target
==GL_PROXY_TEXTURE_1D
) {
1179 /* Proxy texture: check for errors and update proxy state */
1180 if (texture_error_check( ctx
, target
, level
, internalFormat
,
1181 format
, type
, 1, width
, 1, 1, border
)) {
1182 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1183 MEMSET( ctx
->Texture
.Proxy1D
->Image
[level
], 0,
1184 sizeof(struct gl_texture_image
) );
1188 ctx
->Texture
.Proxy1D
->Image
[level
]->Format
= (GLenum
) format
;
1189 set_teximage_component_sizes( ctx
->Texture
.Proxy1D
->Image
[level
] );
1190 ctx
->Texture
.Proxy1D
->Image
[level
]->IntFormat
= (GLenum
) internalFormat
;
1191 ctx
->Texture
.Proxy1D
->Image
[level
]->Border
= border
;
1192 ctx
->Texture
.Proxy1D
->Image
[level
]->Width
= width
;
1193 ctx
->Texture
.Proxy1D
->Image
[level
]->Height
= 1;
1194 ctx
->Texture
.Proxy1D
->Image
[level
]->Depth
= 1;
1198 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1205 _mesa_TexImage2D( GLenum target
, GLint level
, GLint internalFormat
,
1206 GLsizei width
, GLsizei height
, GLint border
,
1207 GLenum format
, GLenum type
,
1208 const GLvoid
*pixels
)
1210 GET_CURRENT_CONTEXT(ctx
);
1211 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glTexImage2D");
1213 if (target
==GL_TEXTURE_2D
) {
1214 struct gl_texture_unit
*texUnit
;
1215 struct gl_texture_object
*texObj
;
1216 struct gl_texture_image
*texImage
;
1218 if (texture_error_check( ctx
, target
, level
, internalFormat
,
1219 format
, type
, 2, width
, height
, 1, border
)) {
1220 return; /* error in texture image was detected */
1223 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1224 texObj
= select_tex_object(texUnit
, target
);
1225 texImage
= texObj
->Image
[level
];
1228 texImage
= _mesa_alloc_texture_image();
1229 texObj
->Image
[level
] = texImage
;
1231 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1235 else if (texImage
->Data
) {
1236 FREE(texImage
->Data
);
1237 texImage
->Data
= NULL
;
1240 /* setup the teximage struct's fields */
1241 init_texture_image(texImage
, width
, height
, 1, border
, internalFormat
);
1243 /* process the texture image */
1245 GLboolean retain
= GL_TRUE
;
1246 GLboolean success
= GL_FALSE
;
1247 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
1248 && ctx
->Driver
.TexImage2D
) {
1249 /* let device driver try to use raw image */
1250 success
= (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, format
,
1251 type
, pixels
, &ctx
->Unpack
,
1252 texObj
, texImage
, &retain
);
1254 if (retain
|| !success
) {
1255 /* make internal copy of the texture image */
1256 make_texture_image(ctx
, texImage
, format
, type
,
1257 pixels
, &ctx
->Unpack
);
1258 if (!success
&& ctx
->Driver
.TexImage2D
) {
1259 /* let device driver try to use unpacked image */
1260 (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, texImage
->Format
,
1261 GL_UNSIGNED_BYTE
, texImage
->Data
,
1262 &_mesa_native_packing
,
1263 texObj
, texImage
, &retain
);
1266 if (!retain
&& texImage
->Data
) {
1267 FREE(texImage
->Data
);
1268 texImage
->Data
= NULL
;
1272 make_null_texture(texImage
);
1273 if (ctx
->Driver
.TexImage2D
) {
1275 (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, texImage
->Format
,
1276 GL_UNSIGNED_BYTE
, texImage
->Data
,
1277 &_mesa_native_packing
,
1278 texObj
, texImage
, &retain
);
1282 #define OLD_DD_TEXTURE
1283 #ifdef OLD_DD_TEXTURE
1284 /* XXX this will be removed in the future */
1285 if (ctx
->Driver
.TexImage
) {
1286 (*ctx
->Driver
.TexImage
)( ctx
, target
, texObj
, level
, internalFormat
,
1292 gl_put_texobj_on_dirty_list( ctx
, texObj
);
1293 ctx
->NewState
|= NEW_TEXTURING
;
1295 else if (target
==GL_PROXY_TEXTURE_2D
) {
1296 /* Proxy texture: check for errors and update proxy state */
1297 if (texture_error_check( ctx
, target
, level
, internalFormat
,
1298 format
, type
, 2, width
, height
, 1, border
)) {
1299 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1300 MEMSET( ctx
->Texture
.Proxy2D
->Image
[level
], 0,
1301 sizeof(struct gl_texture_image
) );
1305 ctx
->Texture
.Proxy2D
->Image
[level
]->Format
= (GLenum
) format
;
1306 set_teximage_component_sizes( ctx
->Texture
.Proxy2D
->Image
[level
] );
1307 ctx
->Texture
.Proxy2D
->Image
[level
]->IntFormat
= (GLenum
) internalFormat
;
1308 ctx
->Texture
.Proxy2D
->Image
[level
]->Border
= border
;
1309 ctx
->Texture
.Proxy2D
->Image
[level
]->Width
= width
;
1310 ctx
->Texture
.Proxy2D
->Image
[level
]->Height
= height
;
1311 ctx
->Texture
.Proxy2D
->Image
[level
]->Depth
= 1;
1315 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1323 * Called by the API or display list executor.
1324 * Note that width and height include the border.
1327 _mesa_TexImage3D( GLenum target
, GLint level
, GLint internalFormat
,
1328 GLsizei width
, GLsizei height
, GLsizei depth
,
1329 GLint border
, GLenum format
, GLenum type
,
1330 const GLvoid
*pixels
)
1332 GET_CURRENT_CONTEXT(ctx
);
1333 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glTexImage3D");
1335 if (target
==GL_TEXTURE_3D_EXT
) {
1336 struct gl_texture_unit
*texUnit
;
1337 struct gl_texture_object
*texObj
;
1338 struct gl_texture_image
*texImage
;
1339 if (texture_error_check( ctx
, target
, level
, internalFormat
,
1340 format
, type
, 3, width
, height
, depth
,
1342 return; /* error in texture image was detected */
1345 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1346 texObj
= texUnit
->CurrentD
[3];
1347 texImage
= texObj
->Image
[level
];
1350 texImage
= _mesa_alloc_texture_image();
1351 texObj
->Image
[level
] = texImage
;
1353 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
1357 else if (texImage
->Data
) {
1358 FREE(texImage
->Data
);
1359 texImage
->Data
= NULL
;
1362 /* setup the teximage struct's fields */
1363 init_texture_image(texImage
, width
, height
, depth
,
1364 border
, internalFormat
);
1366 /* process the texture image */
1368 GLboolean retain
= GL_TRUE
;
1369 GLboolean success
= GL_FALSE
;
1370 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
1371 && ctx
->Driver
.TexImage3D
) {
1372 /* let device driver try to use raw image */
1373 success
= (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, format
,
1374 type
, pixels
, &ctx
->Unpack
,
1375 texObj
, texImage
, &retain
);
1377 if (retain
|| !success
) {
1378 /* make internal copy of the texture image */
1379 make_texture_image(ctx
, texImage
, format
, type
,
1380 pixels
, &ctx
->Unpack
);
1381 if (!success
&& ctx
->Driver
.TexImage3D
) {
1382 /* let device driver try to use unpacked image */
1383 (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, texImage
->Format
,
1384 GL_UNSIGNED_BYTE
, texImage
->Data
,
1385 &_mesa_native_packing
,
1386 texObj
, texImage
, &retain
);
1389 if (!retain
&& texImage
->Data
) {
1390 FREE(texImage
->Data
);
1391 texImage
->Data
= NULL
;
1395 make_null_texture(texImage
);
1396 if (ctx
->Driver
.TexImage3D
) {
1398 (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, texImage
->Format
,
1399 GL_UNSIGNED_BYTE
, texImage
->Data
,
1400 &_mesa_native_packing
,
1401 texObj
, texImage
, &retain
);
1406 gl_put_texobj_on_dirty_list( ctx
, texObj
);
1407 ctx
->NewState
|= NEW_TEXTURING
;
1409 else if (target
==GL_PROXY_TEXTURE_3D_EXT
) {
1410 /* Proxy texture: check for errors and update proxy state */
1411 if (texture_error_check( ctx
, target
, level
, internalFormat
,
1412 format
, type
, 3, width
, height
, depth
,
1414 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1415 MEMSET( ctx
->Texture
.Proxy3D
->Image
[level
], 0,
1416 sizeof(struct gl_texture_image
) );
1420 ctx
->Texture
.Proxy3D
->Image
[level
]->Format
= (GLenum
) format
;
1421 set_teximage_component_sizes( ctx
->Texture
.Proxy3D
->Image
[level
] );
1422 ctx
->Texture
.Proxy3D
->Image
[level
]->IntFormat
= (GLenum
) internalFormat
;
1423 ctx
->Texture
.Proxy3D
->Image
[level
]->Border
= border
;
1424 ctx
->Texture
.Proxy3D
->Image
[level
]->Width
= width
;
1425 ctx
->Texture
.Proxy3D
->Image
[level
]->Height
= height
;
1426 ctx
->Texture
.Proxy3D
->Image
[level
]->Depth
= depth
;
1430 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1437 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
1438 GLsizei width
, GLsizei height
, GLsizei depth
,
1439 GLint border
, GLenum format
, GLenum type
,
1440 const GLvoid
*pixels
)
1442 _mesa_TexImage3D(target
, level
, (GLint
) internalFormat
, width
, height
,
1443 depth
, border
, format
, type
, pixels
);
1448 * Fetch a texture image from the device driver.
1449 * Store the results in the given texture object at the given mipmap level.
1452 _mesa_get_teximage_from_driver( GLcontext
*ctx
, GLenum target
, GLint level
,
1453 const struct gl_texture_object
*texObj
)
1456 GLenum imgFormat
, imgType
;
1457 GLboolean freeImage
;
1458 struct gl_texture_image
*texImage
;
1459 GLint destComponents
, numPixels
, srcBytesPerTexel
;
1461 if (!ctx
->Driver
.GetTexImage
)
1464 image
= (*ctx
->Driver
.GetTexImage
)( ctx
, target
, level
, texObj
,
1465 &imgFormat
, &imgType
, &freeImage
);
1469 texImage
= texObj
->Image
[level
];
1474 destComponents
= components_in_intformat(texImage
->Format
);
1475 assert(destComponents
> 0);
1476 numPixels
= texImage
->Width
* texImage
->Height
* texImage
->Depth
;
1477 assert(numPixels
> 0);
1478 srcBytesPerTexel
= _mesa_bytes_per_pixel(imgFormat
, imgType
);
1479 assert(srcBytesPerTexel
> 0);
1481 if (!texImage
->Data
) {
1482 /* Allocate memory for the texture image data */
1483 texImage
->Data
= (GLubyte
*) MALLOC(numPixels
* destComponents
+ EXTRA_BYTE
);
1486 if (imgFormat
== texImage
->Format
&& imgType
== GL_UNSIGNED_BYTE
) {
1487 /* We got lucky! The driver's format and type match Mesa's format. */
1488 if (texImage
->Data
) {
1489 MEMCPY(texImage
->Data
, image
, numPixels
* destComponents
);
1493 /* Convert the texture image from the driver's format to Mesa's
1496 const GLint width
= texImage
->Width
;
1497 const GLint height
= texImage
->Height
;
1498 const GLint depth
= texImage
->Depth
;
1499 const GLint destBytesPerRow
= width
* destComponents
* sizeof(GLchan
);
1500 const GLint srcBytesPerRow
= width
* srcBytesPerTexel
;
1501 const GLenum dstType
= GL_UNSIGNED_BYTE
;
1502 const GLenum dstFormat
= texImage
->Format
;
1503 const GLubyte
*srcPtr
= (const GLubyte
*) image
;
1504 GLubyte
*destPtr
= texImage
->Data
;
1506 if (texImage
->Format
== GL_COLOR_INDEX
) {
1507 /* color index texture */
1509 assert(imgFormat
== GL_COLOR_INDEX
);
1510 for (img
= 0; img
< depth
; img
++) {
1511 for (row
= 0; row
< height
; row
++) {
1512 _mesa_unpack_index_span(ctx
, width
, dstType
, destPtr
,
1513 imgType
, srcPtr
, &_mesa_native_packing
, GL_FALSE
);
1514 destPtr
+= destBytesPerRow
;
1515 srcPtr
+= srcBytesPerRow
;
1522 for (img
= 0; img
< depth
; img
++) {
1523 for (row
= 0; row
< height
; row
++) {
1524 _mesa_unpack_ubyte_color_span(ctx
, width
, dstFormat
, destPtr
,
1525 imgFormat
, imgType
, srcPtr
, &_mesa_native_packing
, GL_FALSE
);
1526 destPtr
+= destBytesPerRow
;
1527 srcPtr
+= srcBytesPerRow
;
1539 _mesa_GetTexImage( GLenum target
, GLint level
, GLenum format
,
1540 GLenum type
, GLvoid
*pixels
)
1542 GET_CURRENT_CONTEXT(ctx
);
1543 const struct gl_texture_object
*texObj
;
1544 struct gl_texture_image
*texImage
;
1545 GLboolean discardImage
;
1547 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetTexImage");
1549 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1550 gl_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
1554 if (_mesa_sizeof_type(type
) <= 0) {
1555 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
1559 if (_mesa_components_in_format(format
) <= 0) {
1560 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
1569 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[1];
1572 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[2];
1575 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[3];
1578 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)" );
1582 texImage
= texObj
->Image
[level
];
1584 /* invalid mipmap level */
1588 if (!texImage
->Data
) {
1589 /* try to get the texture image from the device driver */
1590 _mesa_get_teximage_from_driver(ctx
, target
, level
, texObj
);
1591 discardImage
= GL_TRUE
;
1594 discardImage
= GL_FALSE
;
1597 if (texImage
->Data
) {
1598 GLint width
= texImage
->Width
;
1599 GLint height
= texImage
->Height
;
1602 for (row
= 0; row
< height
; row
++) {
1603 /* compute destination address in client memory */
1604 GLvoid
*dest
= _mesa_image_address( &ctx
->Unpack
, pixels
,
1606 format
, type
, 0, row
, 0);
1609 if (texImage
->Format
== GL_RGBA
) {
1610 const GLubyte
*src
= texImage
->Data
+ row
* width
* 4 * sizeof(GLubyte
);
1611 _mesa_pack_rgba_span( ctx
, width
, (CONST
GLubyte (*)[4]) src
,
1612 format
, type
, dest
, &ctx
->Pack
, GL_TRUE
);
1615 /* fetch RGBA row from texture image then pack it in client mem */
1616 GLubyte rgba
[MAX_WIDTH
][4];
1619 switch (texImage
->Format
) {
1621 src
= texImage
->Data
+ row
* width
* sizeof(GLubyte
);
1622 for (i
= 0; i
< width
; i
++) {
1623 rgba
[i
][RCOMP
] = 255;
1624 rgba
[i
][GCOMP
] = 255;
1625 rgba
[i
][BCOMP
] = 255;
1626 rgba
[i
][ACOMP
] = src
[i
];
1630 src
= texImage
->Data
+ row
* width
* sizeof(GLubyte
);
1631 for (i
= 0; i
< width
; i
++) {
1632 rgba
[i
][RCOMP
] = src
[i
];
1633 rgba
[i
][GCOMP
] = src
[i
];
1634 rgba
[i
][BCOMP
] = src
[i
];
1635 rgba
[i
][ACOMP
] = 255;
1638 case GL_LUMINANCE_ALPHA
:
1639 src
= texImage
->Data
+ row
* 2 * width
* sizeof(GLubyte
);
1640 for (i
= 0; i
< width
; i
++) {
1641 rgba
[i
][RCOMP
] = src
[i
*2+0];
1642 rgba
[i
][GCOMP
] = src
[i
*2+0];
1643 rgba
[i
][BCOMP
] = src
[i
*2+0];
1644 rgba
[i
][ACOMP
] = src
[i
*2+1];
1648 src
= texImage
->Data
+ row
* width
* sizeof(GLubyte
);
1649 for (i
= 0; i
< width
; i
++) {
1650 rgba
[i
][RCOMP
] = src
[i
];
1651 rgba
[i
][GCOMP
] = src
[i
];
1652 rgba
[i
][BCOMP
] = src
[i
];
1653 rgba
[i
][ACOMP
] = 255;
1657 src
= texImage
->Data
+ row
* 3 * width
* sizeof(GLubyte
);
1658 for (i
= 0; i
< width
; i
++) {
1659 rgba
[i
][RCOMP
] = src
[i
*3+0];
1660 rgba
[i
][GCOMP
] = src
[i
*3+1];
1661 rgba
[i
][BCOMP
] = src
[i
*3+2];
1662 rgba
[i
][ACOMP
] = 255;
1666 /* this special case should have been handled above! */
1667 gl_problem( ctx
, "error 1 in gl_GetTexImage" );
1669 case GL_COLOR_INDEX
:
1670 gl_problem( ctx
, "GL_COLOR_INDEX not implemented in gl_GetTexImage" );
1673 gl_problem( ctx
, "bad format in gl_GetTexImage" );
1675 _mesa_pack_rgba_span( ctx
, width
, (const GLubyte (*)[4])rgba
,
1676 format
, type
, dest
, &ctx
->Pack
, GL_TRUE
);
1680 /* if we got the teximage from the device driver we'll discard it now */
1682 FREE(texImage
->Data
);
1683 texImage
->Data
= NULL
;
1691 _mesa_TexSubImage1D( GLenum target
, GLint level
,
1692 GLint xoffset
, GLsizei width
,
1693 GLenum format
, GLenum type
,
1694 const GLvoid
*pixels
)
1696 GET_CURRENT_CONTEXT(ctx
);
1697 struct gl_texture_unit
*texUnit
;
1698 struct gl_texture_object
*texObj
;
1699 struct gl_texture_image
*texImage
;
1700 GLboolean success
= GL_FALSE
;
1702 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
1703 width
, 1, 1, format
, type
)) {
1704 return; /* error was detected */
1707 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1708 texObj
= texUnit
->CurrentD
[1];
1709 texImage
= texObj
->Image
[level
];
1712 if (width
== 0 || !pixels
)
1713 return; /* no-op, not an error */
1716 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
1717 && ctx
->Driver
.TexSubImage1D
) {
1718 success
= (*ctx
->Driver
.TexSubImage1D
)( ctx
, target
, level
, xoffset
,
1719 width
, format
, type
, pixels
,
1720 &ctx
->Unpack
, texObj
, texImage
);
1723 /* XXX if Driver.TexSubImage1D, unpack image and try again? */
1725 const GLint texComponents
= components_in_intformat(texImage
->Format
);
1726 const GLenum texFormat
= texImage
->Format
;
1727 const GLint xoffsetb
= xoffset
+ texImage
->Border
;
1728 GLboolean retain
= GL_TRUE
;
1729 if (!texImage
->Data
) {
1730 _mesa_get_teximage_from_driver( ctx
, target
, level
, texObj
);
1731 if (!texImage
->Data
) {
1732 make_null_texture(texImage
);
1734 if (!texImage
->Data
)
1735 return; /* we're really out of luck! */
1738 if (texFormat
== GL_COLOR_INDEX
) {
1739 /* color index texture */
1740 GLubyte
*dst
= texImage
->Data
+ xoffsetb
* texComponents
;
1741 const GLvoid
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
, width
,
1742 1, format
, type
, 0, 0, 0);
1743 _mesa_unpack_index_span(ctx
, width
, GL_UNSIGNED_BYTE
, dst
,
1744 type
, src
, &ctx
->Unpack
, GL_TRUE
);
1748 GLubyte
*dst
= texImage
->Data
+ xoffsetb
* texComponents
;
1749 const GLvoid
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
, width
,
1750 1, format
, type
, 0, 0, 0);
1751 _mesa_unpack_ubyte_color_span(ctx
, width
, texFormat
, dst
, format
,
1752 type
, src
, &ctx
->Unpack
, GL_TRUE
);
1755 if (ctx
->Driver
.TexImage1D
) {
1756 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
1757 GL_UNSIGNED_BYTE
, texImage
->Data
,
1758 &_mesa_native_packing
, texObj
, texImage
,
1762 if (!retain
&& texImage
->Data
) {
1763 FREE(texImage
->Data
);
1764 texImage
->Data
= NULL
;
1768 /*gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[1] );*/
1773 _mesa_TexSubImage2D( GLenum target
, GLint level
,
1774 GLint xoffset
, GLint yoffset
,
1775 GLsizei width
, GLsizei height
,
1776 GLenum format
, GLenum type
,
1777 const GLvoid
*pixels
)
1779 GET_CURRENT_CONTEXT(ctx
);
1780 struct gl_texture_unit
*texUnit
;
1781 struct gl_texture_object
*texObj
;
1782 struct gl_texture_image
*texImage
;
1783 GLboolean success
= GL_FALSE
;
1785 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1786 width
, height
, 1, format
, type
)) {
1787 return; /* error was detected */
1790 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1791 texObj
= select_tex_object(texUnit
, target
);
1792 texImage
= texObj
->Image
[level
];
1795 if (width
== 0 || height
== 0 || !pixels
)
1796 return; /* no-op, not an error */
1798 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
1799 && ctx
->Driver
.TexSubImage2D
) {
1800 success
= (*ctx
->Driver
.TexSubImage2D
)( ctx
, target
, level
, xoffset
,
1801 yoffset
, width
, height
, format
, type
,
1802 pixels
, &ctx
->Unpack
, texObj
, texImage
);
1805 /* XXX if Driver.TexSubImage2D, unpack image and try again? */
1807 const GLint texComponents
= components_in_intformat(texImage
->Format
);
1808 const GLenum texFormat
= texImage
->Format
;
1809 const GLint xoffsetb
= xoffset
+ texImage
->Border
;
1810 const GLint yoffsetb
= yoffset
+ texImage
->Border
;
1811 const GLint srcStride
= _mesa_image_row_stride(&ctx
->Unpack
, width
,
1813 const GLint dstStride
= texImage
->Width
* texComponents
*sizeof(GLubyte
);
1814 GLboolean retain
= GL_TRUE
;
1816 if (!texImage
->Data
) {
1817 _mesa_get_teximage_from_driver( ctx
, target
, level
, texObj
);
1818 if (!texImage
->Data
) {
1819 make_null_texture(texImage
);
1821 if (!texImage
->Data
)
1822 return; /* we're really out of luck! */
1825 if (texFormat
== GL_COLOR_INDEX
) {
1826 /* color index texture */
1827 GLubyte
*dst
= texImage
->Data
1828 + (yoffsetb
* texImage
->Width
+ xoffsetb
) * texComponents
;
1829 const GLubyte
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
,
1830 width
, height
, format
, type
, 0, 0, 0);
1832 for (row
= 0; row
< height
; row
++) {
1833 _mesa_unpack_index_span(ctx
, width
, GL_UNSIGNED_BYTE
, dst
, type
,
1834 (const GLvoid
*) src
, &ctx
->Unpack
, GL_TRUE
);
1841 GLubyte
*dst
= texImage
->Data
1842 + (yoffsetb
* texImage
->Width
+ xoffsetb
) * texComponents
;
1843 const GLubyte
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
,
1844 width
, height
, format
, type
, 0, 0, 0);
1846 for (row
= 0; row
< height
; row
++) {
1847 _mesa_unpack_ubyte_color_span(ctx
, width
, texFormat
, dst
, format
,
1848 type
, (const GLvoid
*) src
, &ctx
->Unpack
, GL_TRUE
);
1854 if (ctx
->Driver
.TexImage2D
) {
1855 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, texImage
->Format
,
1856 GL_UNSIGNED_BYTE
, texImage
->Data
,
1857 &_mesa_native_packing
, texObj
, texImage
,
1861 if (!retain
&& texImage
->Data
) {
1862 FREE(texImage
->Data
);
1863 texImage
->Data
= NULL
;
1866 #ifdef OLD_DD_TEXTURE
1867 /* XXX this will be removed in the future */
1868 if (ctx
->Driver
.TexSubImage
) {
1869 (*ctx
->Driver
.TexSubImage
)(ctx
, target
, texObj
, level
,
1870 xoffset
, yoffset
, width
, height
,
1871 texImage
->IntFormat
, texImage
);
1873 else if (ctx
->Driver
.TexImage
) {
1874 (*ctx
->Driver
.TexImage
)(ctx
, GL_TEXTURE_2D
, texObj
,
1875 level
, texImage
->IntFormat
, texImage
);
1884 _mesa_TexSubImage3D( GLenum target
, GLint level
,
1885 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1886 GLsizei width
, GLsizei height
, GLsizei depth
,
1887 GLenum format
, GLenum type
,
1888 const GLvoid
*pixels
)
1890 GET_CURRENT_CONTEXT(ctx
);
1891 struct gl_texture_unit
*texUnit
;
1892 struct gl_texture_object
*texObj
;
1893 struct gl_texture_image
*texImage
;
1894 GLboolean success
= GL_FALSE
;
1896 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
1897 width
, height
, depth
, format
, type
)) {
1898 return; /* error was detected */
1901 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1902 texObj
= texUnit
->CurrentD
[3];
1903 texImage
= texObj
->Image
[level
];
1906 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
1907 return; /* no-op, not an error */
1909 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
1910 && ctx
->Driver
.TexSubImage3D
) {
1911 success
= (*ctx
->Driver
.TexSubImage3D
)( ctx
, target
, level
, xoffset
,
1912 yoffset
, zoffset
, width
, height
, depth
, format
,
1913 type
, pixels
, &ctx
->Unpack
, texObj
, texImage
);
1916 /* XXX if Driver.TexSubImage3D, unpack image and try again? */
1918 const GLint texComponents
= components_in_intformat(texImage
->Format
);
1919 const GLenum texFormat
= texImage
->Format
;
1920 const GLint xoffsetb
= xoffset
+ texImage
->Border
;
1921 const GLint yoffsetb
= yoffset
+ texImage
->Border
;
1922 const GLint zoffsetb
= zoffset
+ texImage
->Border
;
1923 const GLint texWidth
= texImage
->Width
;
1924 const GLint dstRectArea
= texWidth
* texImage
->Height
;
1925 const GLint srcStride
= _mesa_image_row_stride(&ctx
->Unpack
,
1926 width
, format
, type
);
1927 const GLint dstStride
= texWidth
* texComponents
* sizeof(GLubyte
);
1928 GLboolean retain
= GL_TRUE
;
1930 if (texFormat
== GL_COLOR_INDEX
) {
1931 /* color index texture */
1933 for (img
= 0; img
< depth
; img
++) {
1934 const GLubyte
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
,
1935 width
, height
, format
, type
, img
, 0, 0);
1936 GLubyte
*dst
= texImage
->Data
+ ((zoffsetb
+ img
) * dstRectArea
1937 + yoffsetb
* texWidth
+ xoffsetb
) * texComponents
;
1938 for (row
= 0; row
< height
; row
++) {
1939 _mesa_unpack_index_span(ctx
, width
, GL_UNSIGNED_BYTE
, dst
,
1940 type
, (const GLvoid
*) src
, &ctx
->Unpack
, GL_TRUE
);
1949 for (img
= 0; img
< depth
; img
++) {
1950 const GLubyte
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
,
1951 width
, height
, format
, type
, img
, 0, 0);
1952 GLubyte
*dst
= texImage
->Data
+ ((zoffsetb
+ img
) * dstRectArea
1953 + yoffsetb
* texWidth
+ xoffsetb
) * texComponents
;
1954 for (row
= 0; row
< height
; row
++) {
1955 _mesa_unpack_ubyte_color_span(ctx
, width
, texFormat
, dst
,
1956 format
, type
, (const GLvoid
*) src
, &ctx
->Unpack
, GL_TRUE
);
1963 if (ctx
->Driver
.TexImage3D
) {
1964 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, texImage
->Format
,
1965 GL_UNSIGNED_BYTE
, texImage
->Data
,
1966 &_mesa_native_packing
, texObj
, texImage
,
1970 if (!retain
&& texImage
->Data
) {
1971 FREE(texImage
->Data
);
1972 texImage
->Data
= NULL
;
1980 * Read an RGBA image from the frame buffer.
1981 * This is used by glCopyTexSubImage[12]D().
1982 * Input: ctx - the context
1983 * x, y - lower left corner
1984 * width, height - size of region to read
1985 * Return: pointer to block of GL_RGBA, GLubyte data.
1988 read_color_image( GLcontext
*ctx
, GLint x
, GLint y
,
1989 GLsizei width
, GLsizei height
)
1992 GLubyte
*image
, *dst
;
1994 image
= (GLubyte
*) MALLOC(width
* height
* 4 * sizeof(GLubyte
));
1998 /* Select buffer to read from */
1999 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->ReadBuffer
,
2000 ctx
->Pixel
.DriverReadBuffer
);
2003 stride
= width
* 4 * sizeof(GLubyte
);
2004 for (i
= 0; i
< height
; i
++) {
2005 gl_read_rgba_span( ctx
, ctx
->ReadBuffer
, width
, x
, y
+ i
,
2006 (GLubyte (*)[4]) dst
);
2010 /* Read from draw buffer (the default) */
2011 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->DrawBuffer
,
2012 ctx
->Color
.DriverDrawBuffer
);
2020 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
2021 GLenum internalFormat
,
2023 GLsizei width
, GLint border
)
2025 GET_CURRENT_CONTEXT(ctx
);
2026 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexImage1D");
2028 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
2032 if (ctx
->Pixel
.MapColorFlag
|| ctx
->Pixel
.ScaleOrBiasRGBA
2033 || !ctx
->Driver
.CopyTexImage1D
2034 || !(*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
,
2035 internalFormat
, x
, y
, width
, border
))
2037 GLubyte
*image
= read_color_image( ctx
, x
, y
, width
, 1 );
2039 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D" );
2042 (*ctx
->Exec
->TexImage1D
)( target
, level
, internalFormat
, width
,
2043 border
, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2051 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
2052 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
2055 GET_CURRENT_CONTEXT(ctx
);
2056 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexImage2D");
2058 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
2059 width
, height
, border
))
2062 if (ctx
->Pixel
.MapColorFlag
|| ctx
->Pixel
.ScaleOrBiasRGBA
2063 || !ctx
->Driver
.CopyTexImage2D
2064 || !(*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
,
2065 internalFormat
, x
, y
, width
, height
, border
))
2067 GLubyte
*image
= read_color_image( ctx
, x
, y
, width
, height
);
2069 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D" );
2072 (ctx
->Exec
->TexImage2D
)( target
, level
, internalFormat
, width
,
2073 height
, border
, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2081 * Do the work of glCopyTexSubImage[123]D.
2084 copy_tex_sub_image( GLcontext
*ctx
, struct gl_texture_image
*dest
,
2085 GLint width
, GLint height
,
2086 GLint srcx
, GLint srcy
,
2087 GLint dstx
, GLint dsty
, GLint dstz
)
2090 GLint format
, components
, rectarea
;
2091 GLint texwidth
, texheight
, zoffset
;
2093 /* dst[xyz] may be negative if we have a texture border! */
2094 dstx
+= dest
->Border
;
2095 dsty
+= dest
->Border
;
2096 dstz
+= dest
->Border
;
2097 texwidth
= dest
->Width
;
2098 texheight
= dest
->Height
;
2099 rectarea
= texwidth
* texheight
;
2100 zoffset
= dstz
* rectarea
;
2101 format
= dest
->Format
;
2102 components
= components_in_intformat( format
);
2104 /* Select buffer to read from */
2105 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->ReadBuffer
,
2106 ctx
->Pixel
.DriverReadBuffer
);
2108 for (i
= 0;i
< height
; i
++) {
2109 GLubyte rgba
[MAX_WIDTH
][4];
2111 gl_read_rgba_span( ctx
, ctx
->ReadBuffer
, width
, srcx
, srcy
+ i
, rgba
);
2112 dst
= dest
->Data
+ ( zoffset
+ (dsty
+i
) * texwidth
+ dstx
) * components
;
2113 _mesa_unpack_ubyte_color_span(ctx
, width
, format
, dst
,
2114 GL_RGBA
, GL_UNSIGNED_BYTE
, rgba
,
2115 &_mesa_native_packing
, GL_TRUE
);
2118 /* Read from draw buffer (the default) */
2119 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->DrawBuffer
,
2120 ctx
->Color
.DriverDrawBuffer
);
2127 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
2128 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
2130 GET_CURRENT_CONTEXT(ctx
);
2131 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexSubImage1D");
2133 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
2134 xoffset
, 0, 0, width
, 1))
2137 if (ctx
->Pixel
.MapColorFlag
|| ctx
->Pixel
.ScaleOrBiasRGBA
2138 || !ctx
->Driver
.CopyTexSubImage1D
2139 || !(*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
,
2140 xoffset
, x
, y
, width
)) {
2141 struct gl_texture_unit
*texUnit
;
2142 struct gl_texture_image
*teximage
;
2143 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2144 teximage
= texUnit
->CurrentD
[1]->Image
[level
];
2146 if (teximage
->Data
) {
2147 copy_tex_sub_image(ctx
, teximage
, width
, 1, x
, y
, xoffset
, 0, 0);
2148 /* tell driver about the change */
2149 /* XXX this is obsolete */
2150 if (ctx
->Driver
.TexImage
) {
2151 (*ctx
->Driver
.TexImage
)( ctx
, GL_TEXTURE_1D
,
2152 texUnit
->CurrentD
[1],
2153 level
, teximage
->IntFormat
, teximage
);
2162 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
2163 GLint xoffset
, GLint yoffset
,
2164 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2166 GET_CURRENT_CONTEXT(ctx
);
2167 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexSubImage2D");
2169 if (copytexsubimage_error_check(ctx
, 2, target
, level
,
2170 xoffset
, yoffset
, 0, width
, height
))
2173 if (ctx
->Pixel
.MapColorFlag
|| ctx
->Pixel
.ScaleOrBiasRGBA
2174 || !ctx
->Driver
.CopyTexSubImage2D
2175 || !(*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
2176 xoffset
, yoffset
, x
, y
, width
, height
)) {
2177 struct gl_texture_unit
*texUnit
;
2178 struct gl_texture_image
*teximage
;
2179 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2180 teximage
= texUnit
->CurrentD
[2]->Image
[level
];
2182 if (teximage
->Data
) {
2183 copy_tex_sub_image(ctx
, teximage
, width
, height
,
2184 x
, y
, xoffset
, yoffset
, 0);
2185 /* tell driver about the change */
2186 /* XXX this is obsolete */
2187 if (ctx
->Driver
.TexImage
) {
2188 (*ctx
->Driver
.TexImage
)( ctx
, GL_TEXTURE_2D
,
2189 texUnit
->CurrentD
[2],
2190 level
, teximage
->IntFormat
, teximage
);
2199 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
2200 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2201 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2203 GET_CURRENT_CONTEXT(ctx
);
2204 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexSubImage3D");
2206 if (copytexsubimage_error_check(ctx
, 3, target
, level
,
2207 xoffset
, yoffset
, zoffset
, width
, height
))
2210 if (ctx
->Pixel
.MapColorFlag
|| ctx
->Pixel
.ScaleOrBiasRGBA
2211 || !ctx
->Driver
.CopyTexSubImage3D
2212 || !(*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
2213 xoffset
, yoffset
, zoffset
, x
, y
, width
, height
)) {
2214 struct gl_texture_unit
*texUnit
;
2215 struct gl_texture_image
*teximage
;
2216 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2217 teximage
= texUnit
->CurrentD
[3]->Image
[level
];
2219 if (teximage
->Data
) {
2220 copy_tex_sub_image(ctx
, teximage
, width
, height
,
2221 x
, y
, xoffset
, yoffset
, zoffset
);
2222 /* tell driver about the change */
2223 /* XXX this is obsolete */
2224 if (ctx
->Driver
.TexImage
) {
2225 (*ctx
->Driver
.TexImage
)( ctx
, GL_TEXTURE_3D
,
2226 texUnit
->CurrentD
[3],
2227 level
, teximage
->IntFormat
, teximage
);