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");
390 * Return new gl_texture_image struct with all fields initialized to zero.
392 struct gl_texture_image
*
393 _mesa_alloc_texture_image( void )
395 return CALLOC_STRUCT(gl_texture_image
);
401 * Initialize most fields of a gl_texture_image struct.
404 init_texture_image( struct gl_texture_image
*img
,
405 GLsizei width
, GLsizei height
, GLsizei depth
,
406 GLint border
, GLenum internalFormat
)
410 img
->Format
= (GLenum
) _mesa_base_tex_format(internalFormat
);
411 set_teximage_component_sizes( img
);
412 img
->IntFormat
= (GLenum
) internalFormat
;
413 img
->Border
= border
;
415 img
->Height
= height
;
417 img
->WidthLog2
= logbase2(width
- 2 * border
);
418 if (height
== 1) /* 1-D texture */
421 img
->HeightLog2
= logbase2(height
- 2 * border
);
422 if (depth
== 1) /* 2-D texture */
425 img
->DepthLog2
= logbase2(depth
- 2 * border
);
426 img
->Width2
= 1 << img
->WidthLog2
;
427 img
->Height2
= 1 << img
->HeightLog2
;
428 img
->Depth2
= 1 << img
->DepthLog2
;
429 img
->MaxLog2
= MAX2(img
->WidthLog2
, img
->HeightLog2
);
435 _mesa_free_texture_image( struct gl_texture_image
*teximage
)
437 if (teximage
->Data
) {
438 FREE( teximage
->Data
);
439 teximage
->Data
= NULL
;
446 /* Need this to prevent an out-of-bounds memory access when using
447 * X86 optimized code.
450 # define EXTRA_BYTE 1
452 # define EXTRA_BYTE 0
458 * Called by glTexImage[123]D. Fill in a texture image with data given
459 * by the client. All pixel transfer and unpack modes are handled here.
460 * NOTE: All texture image parameters should have already been error checked.
463 make_texture_image( GLcontext
*ctx
,
464 struct gl_texture_image
*texImage
,
465 GLenum srcFormat
, GLenum srcType
, const GLvoid
*pixels
,
466 const struct gl_pixelstore_attrib
*unpacking
)
468 GLint components
, numPixels
;
469 GLint internalFormat
, width
, height
, depth
, border
;
473 ASSERT(!texImage
->Data
);
477 internalFormat
= texImage
->IntFormat
;
478 width
= texImage
->Width
;
479 height
= texImage
->Height
;
480 depth
= texImage
->Depth
;
481 border
= texImage
->Border
;
482 components
= components_in_intformat(internalFormat
);
487 ASSERT(border
== 0 || border
== 1);
492 numPixels
= width
* height
* depth
;
494 texImage
->Data
= (GLubyte
*) MALLOC(numPixels
* components
+ EXTRA_BYTE
);
496 return; /* out of memory */
499 * OK, the texture image struct has been initialized and the texture
500 * image memory has been allocated.
501 * Now fill in the texture image from the source data.
502 * This includes applying the pixel transfer operations.
505 /* try common 2D texture cases first */
506 if (!ctx
->Pixel
.ScaleOrBiasRGBA
&& !ctx
->Pixel
.MapColorFlag
507 && !ctx
->Pixel
.IndexOffset
&& !ctx
->Pixel
.IndexShift
508 && srcType
== GL_UNSIGNED_BYTE
&& depth
== 1) {
510 if (srcFormat
== internalFormat
||
511 (srcFormat
== GL_LUMINANCE
&& internalFormat
== 1) ||
512 (srcFormat
== GL_LUMINANCE_ALPHA
&& internalFormat
== 2) ||
513 (srcFormat
== GL_RGB
&& internalFormat
== 3) ||
514 (srcFormat
== GL_RGBA
&& internalFormat
== 4)) {
515 /* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA,
516 * GL_LUMINANCE_ALPHA, etc. texture formats.
518 const GLubyte
*src
= (const GLubyte
*) _mesa_image_address(
519 unpacking
, pixels
, width
, height
, srcFormat
, srcType
, 0, 0, 0);
520 const GLint srcStride
= _mesa_image_row_stride(unpacking
, width
,
522 GLubyte
*dst
= texImage
->Data
;
523 GLint dstBytesPerRow
= width
* components
* sizeof(GLubyte
);
524 if (srcStride
== dstBytesPerRow
) {
525 MEMCPY(dst
, src
, height
* dstBytesPerRow
);
529 for (i
= 0; i
< height
; i
++) {
530 MEMCPY(dst
, src
, dstBytesPerRow
);
532 dst
+= dstBytesPerRow
;
535 return; /* all done */
537 else if (srcFormat
== GL_RGBA
&& internalFormat
== GL_RGB
) {
538 /* commonly used by Quake */
539 const GLubyte
*src
= (const GLubyte
*) _mesa_image_address(
540 unpacking
, pixels
, width
, height
, srcFormat
, srcType
, 0, 0, 0);
541 const GLint srcStride
= _mesa_image_row_stride(unpacking
, width
,
543 GLubyte
*dst
= texImage
->Data
;
545 for (i
= 0; i
< height
; i
++) {
546 const GLubyte
*s
= src
;
547 for (j
= 0; j
< width
; j
++) {
548 *dst
++ = *s
++; /*red*/
549 *dst
++ = *s
++; /*green*/
550 *dst
++ = *s
++; /*blue*/
555 return; /* all done */
561 * General case solutions
563 if (texImage
->Format
== GL_COLOR_INDEX
) {
564 /* color index texture */
565 const GLint destBytesPerRow
= width
* components
* sizeof(GLubyte
);
566 const GLenum dstType
= GL_UNSIGNED_BYTE
;
567 GLubyte
*dest
= texImage
->Data
;
569 for (img
= 0; img
< depth
; img
++) {
570 for (row
= 0; row
< height
; row
++) {
571 const GLvoid
*source
= _mesa_image_address(unpacking
,
572 pixels
, width
, height
, srcFormat
, srcType
, img
, row
, 0);
573 _mesa_unpack_index_span(ctx
, width
, dstType
, dest
,
574 srcType
, source
, unpacking
, GL_TRUE
);
575 dest
+= destBytesPerRow
;
580 /* regular, color texture */
581 const GLint destBytesPerRow
= width
* components
* sizeof(GLubyte
);
582 const GLenum dstFormat
= texImage
->Format
;
583 GLubyte
*dest
= texImage
->Data
;
585 for (img
= 0; img
< depth
; img
++) {
586 for (row
= 0; row
< height
; row
++) {
587 const GLvoid
*source
= _mesa_image_address(unpacking
,
588 pixels
, width
, height
, srcFormat
, srcType
, img
, row
, 0);
589 _mesa_unpack_ubyte_color_span(ctx
, width
, dstFormat
, dest
,
590 srcFormat
, srcType
, source
, unpacking
, GL_TRUE
);
591 dest
+= destBytesPerRow
;
600 * glTexImage[123]D can accept a NULL image pointer. In this case we
601 * create a texture image with unspecified image contents per the OpenGL
602 * spec. This function creates an empty image for the given texture image.
605 make_null_texture( struct gl_texture_image
*texImage
)
611 ASSERT(!texImage
->Data
);
613 components
= components_in_intformat(texImage
->IntFormat
);
614 numPixels
= texImage
->Width
* texImage
->Height
* texImage
->Depth
;
616 texImage
->Data
= (GLubyte
*) MALLOC( numPixels
* components
+ EXTRA_BYTE
);
619 * Let's see if anyone finds this. If glTexImage2D() is called with
620 * a NULL image pointer then load the texture image with something
621 * interesting instead of leaving it indeterminate.
623 if (texImage
->Data
) {
624 static const char message
[8][32] = {
628 " X X XXXX XXX XXXXX ",
631 " X X XXXXX XXX X X ",
635 GLubyte
*imgPtr
= texImage
->Data
;
637 for (i
= 0; i
< texImage
->Height
; i
++) {
638 GLint srcRow
= 7 - i
% 8;
639 for (j
= 0; j
< texImage
->Width
; j
++) {
640 GLint srcCol
= j
% 32;
641 GLint texel
= (message
[srcRow
][srcCol
]=='X') ? 255 : 70;
642 for (k
=0;k
<components
;k
++) {
643 *imgPtr
++ = (GLubyte
) texel
;
653 * Test glTexImage[123]D() parameters for errors.
655 * dimensions - must be 1 or 2 or 3
656 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
659 texture_error_check( GLcontext
*ctx
, GLenum target
,
660 GLint level
, GLint internalFormat
,
661 GLenum format
, GLenum type
,
663 GLint width
, GLint height
,
664 GLint depth
, GLint border
)
669 if (dimensions
== 1) {
670 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_1D
);
671 if (target
!= GL_TEXTURE_1D
&& !isProxy
) {
672 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
676 else if (dimensions
== 2) {
677 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_2D
);
678 if (target
!= GL_TEXTURE_2D
&& !isProxy
) {
679 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
683 else if (dimensions
== 3) {
684 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_3D
);
685 if (target
!= GL_TEXTURE_3D
&& !isProxy
) {
686 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
691 gl_problem( ctx
, "bad dims in texture_error_check" );
696 if (border
!= 0 && border
!= 1) {
699 sprintf(message
, "glTexImage%dD(border)", dimensions
);
700 gl_error(ctx
, GL_INVALID_VALUE
, message
);
706 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
707 || logbase2( width
- 2 * border
) < 0) {
710 sprintf(message
, "glTexImage%dD(width)", dimensions
);
711 gl_error(ctx
, GL_INVALID_VALUE
, message
);
717 if (dimensions
>= 2) {
718 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
719 || logbase2( height
- 2 * border
) < 0) {
722 sprintf(message
, "glTexImage%dD(height)", dimensions
);
723 gl_error(ctx
, GL_INVALID_VALUE
, message
);
730 if (dimensions
>= 3) {
731 if (depth
< 2 * border
|| depth
> 2 + ctx
->Const
.MaxTextureSize
732 || logbase2( depth
- 2 * border
) < 0) {
734 gl_error( ctx
, GL_INVALID_VALUE
, "glTexImage3D(depth)" );
741 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
744 sprintf(message
, "glTexImage%dD(level)", dimensions
);
745 gl_error(ctx
, GL_INVALID_VALUE
, message
);
750 iformat
= _mesa_base_tex_format( internalFormat
);
754 sprintf(message
, "glTexImage%dD(internalFormat)", dimensions
);
755 gl_error(ctx
, GL_INVALID_VALUE
, message
);
760 if (!_mesa_is_legal_format_and_type( format
, type
)) {
761 /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
762 * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
766 sprintf(message
, "glTexImage%dD(format or type)", dimensions
);
767 gl_error(ctx
, GL_INVALID_OPERATION
, message
);
772 /* if we get here, the parameters are OK */
779 * Test glTexSubImage[123]D() parameters for errors.
781 * dimensions - must be 1 or 2 or 3
782 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
785 subtexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
786 GLenum target
, GLint level
,
787 GLint xoffset
, GLint yoffset
, GLint zoffset
,
788 GLint width
, GLint height
, GLint depth
,
789 GLenum format
, GLenum type
)
791 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
792 struct gl_texture_image
*destTex
;
794 if (dimensions
== 1) {
795 if (target
!= GL_TEXTURE_1D
) {
796 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(target)" );
800 else if (dimensions
== 2) {
801 if (target
!= GL_TEXTURE_2D
) {
802 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
806 else if (dimensions
== 3) {
807 if (target
!= GL_TEXTURE_3D
) {
808 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3D(target)" );
813 gl_problem( ctx
, "bad dims in texture_error_check" );
817 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
818 gl_error(ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(level)");
824 sprintf(message
, "glTexSubImage%dD(width)", dimensions
);
825 gl_error(ctx
, GL_INVALID_VALUE
, message
);
828 if (height
< 0 && dimensions
> 1) {
830 sprintf(message
, "glTexSubImage%dD(height)", dimensions
);
831 gl_error(ctx
, GL_INVALID_VALUE
, message
);
834 if (depth
< 0 && dimensions
> 2) {
836 sprintf(message
, "glTexSubImage%dD(depth)", dimensions
);
837 gl_error(ctx
, GL_INVALID_VALUE
, message
);
841 destTex
= texUnit
->CurrentD
[2]->Image
[level
];
843 gl_error(ctx
, GL_INVALID_OPERATION
, "glTexSubImage2D");
847 if (xoffset
< -((GLint
)destTex
->Border
)) {
848 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset)");
851 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
852 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset+width)");
855 if (dimensions
> 1) {
856 if (yoffset
< -((GLint
)destTex
->Border
)) {
857 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset)");
860 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
861 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset+height)");
865 if (dimensions
> 2) {
866 if (zoffset
< -((GLint
)destTex
->Border
)) {
867 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset)");
870 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+destTex
->Border
)) {
871 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset+depth)");
876 if (!_mesa_is_legal_format_and_type(format
, type
)) {
878 sprintf(message
, "glTexSubImage%dD(format or type)", dimensions
);
879 gl_error(ctx
, GL_INVALID_ENUM
, message
);
888 * Test glCopyTexImage[12]D() parameters for errors.
889 * Input: dimensions - must be 1 or 2 or 3
890 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
893 copytexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
894 GLenum target
, GLint level
, GLint internalFormat
,
895 GLint width
, GLint height
, GLint border
)
899 if (target
!= GL_TEXTURE_1D
&& target
!= GL_TEXTURE_2D
) {
900 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1/2D(target)" );
904 if (dimensions
== 1 && target
!= GL_TEXTURE_1D
) {
905 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
908 else if (dimensions
== 2 && target
!= GL_TEXTURE_2D
) {
909 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
914 if (border
!=0 && border
!=1) {
916 sprintf(message
, "glCopyTexImage%dD(border)", dimensions
);
917 gl_error(ctx
, GL_INVALID_VALUE
, message
);
922 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
923 || logbase2( width
- 2 * border
) < 0) {
925 sprintf(message
, "glCopyTexImage%dD(width)", dimensions
);
926 gl_error(ctx
, GL_INVALID_VALUE
, message
);
931 if (dimensions
>= 2) {
932 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
933 || logbase2( height
- 2 * border
) < 0) {
935 sprintf(message
, "glCopyTexImage%dD(height)", dimensions
);
936 gl_error(ctx
, GL_INVALID_VALUE
, message
);
942 if (level
<0 || level
>=ctx
->Const
.MaxTextureLevels
) {
944 sprintf(message
, "glCopyTexImage%dD(level)", dimensions
);
945 gl_error(ctx
, GL_INVALID_VALUE
, message
);
949 iformat
= _mesa_base_tex_format( internalFormat
);
952 sprintf(message
, "glCopyTexImage%dD(internalFormat)", dimensions
);
953 gl_error(ctx
, GL_INVALID_VALUE
, message
);
957 /* if we get here, the parameters are OK */
963 copytexsubimage_error_check( GLcontext
*ctx
, GLuint dimensions
,
964 GLenum target
, GLint level
,
965 GLint xoffset
, GLint yoffset
, GLint zoffset
,
966 GLsizei width
, GLsizei height
)
968 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
969 struct gl_texture_image
*teximage
;
971 if (dimensions
== 1 && target
!= GL_TEXTURE_1D
) {
972 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
975 else if (dimensions
== 2 && target
!= GL_TEXTURE_2D
) {
976 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
979 else if (dimensions
== 3 && target
!= GL_TEXTURE_3D
) {
980 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3D(target)" );
984 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
986 sprintf(message
, "glCopyTexSubImage%dD(level)", dimensions
);
987 gl_error(ctx
, GL_INVALID_VALUE
, message
);
993 sprintf(message
, "glCopyTexSubImage%dD(width)", dimensions
);
994 gl_error(ctx
, GL_INVALID_VALUE
, message
);
997 if (dimensions
> 1 && height
< 0) {
999 sprintf(message
, "glCopyTexSubImage%dD(height)", dimensions
);
1000 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1004 teximage
= texUnit
->CurrentD
[dimensions
]->Image
[level
];
1007 sprintf(message
, "glCopyTexSubImage%dD(undefined texture)", dimensions
);
1008 gl_error(ctx
, GL_INVALID_OPERATION
, message
);
1012 if (xoffset
< -((GLint
)teximage
->Border
)) {
1014 sprintf(message
, "glCopyTexSubImage%dD(xoffset)", dimensions
);
1015 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1018 if (xoffset
+width
> (GLint
) (teximage
->Width
+teximage
->Border
)) {
1020 sprintf(message
, "glCopyTexSubImage%dD(xoffset+width)", dimensions
);
1021 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1024 if (dimensions
> 1) {
1025 if (yoffset
< -((GLint
)teximage
->Border
)) {
1027 sprintf(message
, "glCopyTexSubImage%dD(yoffset)", dimensions
);
1028 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1031 /* NOTE: we're adding the border here, not subtracting! */
1032 if (yoffset
+height
> (GLint
) (teximage
->Height
+teximage
->Border
)) {
1034 sprintf(message
, "glCopyTexSubImage%dD(yoffset+height)", dimensions
);
1035 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1040 if (dimensions
> 2) {
1041 if (zoffset
< -((GLint
)teximage
->Border
)) {
1043 sprintf(message
, "glCopyTexSubImage%dD(zoffset)", dimensions
);
1044 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1047 if (zoffset
> (GLint
) (teximage
->Depth
+teximage
->Border
)) {
1049 sprintf(message
, "glCopyTexSubImage%dD(zoffset+depth)", dimensions
);
1050 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1055 /* if we get here, the parameters are OK */
1063 * Called from the API. Note that width includes the border.
1066 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
1067 GLsizei width
, GLint border
, GLenum format
,
1068 GLenum type
, const GLvoid
*pixels
)
1070 GET_CURRENT_CONTEXT(ctx
);
1071 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glTexImage1D");
1073 if (target
==GL_TEXTURE_1D
) {
1074 struct gl_texture_unit
*texUnit
;
1075 struct gl_texture_object
*texObj
;
1076 struct gl_texture_image
*texImage
;
1078 if (texture_error_check( ctx
, target
, level
, internalFormat
,
1079 format
, type
, 1, width
, 1, 1, border
)) {
1080 return; /* error in texture image was detected */
1083 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1084 texObj
= texUnit
->CurrentD
[1];
1085 texImage
= texObj
->Image
[level
];
1088 texImage
= _mesa_alloc_texture_image();
1089 texObj
->Image
[level
] = texImage
;
1091 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
1095 else if (texImage
->Data
) {
1096 FREE(texImage
->Data
);
1097 texImage
->Data
= NULL
;
1100 /* setup the teximage struct's fields */
1101 init_texture_image(texImage
, width
, 1, 1, border
, internalFormat
);
1103 /* process the texture image */
1105 GLboolean retain
= GL_TRUE
;
1106 GLboolean success
= GL_FALSE
;
1107 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
1108 && ctx
->Driver
.TexImage1D
) {
1109 /* let device driver try to use raw image */
1110 success
= (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, format
,
1111 type
, pixels
, &ctx
->Unpack
,
1112 texObj
, texImage
, &retain
);
1114 if (retain
|| !success
) {
1115 /* make internal copy of the texture image */
1116 make_texture_image(ctx
, texImage
, format
, type
,
1117 pixels
, &ctx
->Unpack
);
1118 if (!success
&& ctx
->Driver
.TexImage1D
) {
1119 /* let device driver try to use unpacked image */
1120 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
1121 GL_UNSIGNED_BYTE
, texImage
->Data
,
1122 &_mesa_native_packing
,
1123 texObj
, texImage
, &retain
);
1126 if (!retain
&& texImage
->Data
) {
1127 FREE(texImage
->Data
);
1128 texImage
->Data
= NULL
;
1132 make_null_texture(texImage
);
1133 if (ctx
->Driver
.TexImage1D
) {
1135 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
1136 GL_UNSIGNED_BYTE
, texImage
->Data
,
1137 &_mesa_native_packing
,
1138 texObj
, texImage
, &retain
);
1143 gl_put_texobj_on_dirty_list( ctx
, texObj
);
1144 ctx
->NewState
|= NEW_TEXTURING
;
1146 else if (target
==GL_PROXY_TEXTURE_1D
) {
1147 /* Proxy texture: check for errors and update proxy state */
1148 if (texture_error_check( ctx
, target
, level
, internalFormat
,
1149 format
, type
, 1, width
, 1, 1, border
)) {
1150 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1151 MEMSET( ctx
->Texture
.Proxy1D
->Image
[level
], 0,
1152 sizeof(struct gl_texture_image
) );
1156 ctx
->Texture
.Proxy1D
->Image
[level
]->Format
= (GLenum
) format
;
1157 set_teximage_component_sizes( ctx
->Texture
.Proxy1D
->Image
[level
] );
1158 ctx
->Texture
.Proxy1D
->Image
[level
]->IntFormat
= (GLenum
) internalFormat
;
1159 ctx
->Texture
.Proxy1D
->Image
[level
]->Border
= border
;
1160 ctx
->Texture
.Proxy1D
->Image
[level
]->Width
= width
;
1161 ctx
->Texture
.Proxy1D
->Image
[level
]->Height
= 1;
1162 ctx
->Texture
.Proxy1D
->Image
[level
]->Depth
= 1;
1166 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1173 _mesa_TexImage2D( GLenum target
, GLint level
, GLint internalFormat
,
1174 GLsizei width
, GLsizei height
, GLint border
,
1175 GLenum format
, GLenum type
,
1176 const GLvoid
*pixels
)
1178 GET_CURRENT_CONTEXT(ctx
);
1179 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glTexImage2D");
1181 if (target
==GL_TEXTURE_2D
) {
1182 struct gl_texture_unit
*texUnit
;
1183 struct gl_texture_object
*texObj
;
1184 struct gl_texture_image
*texImage
;
1186 if (texture_error_check( ctx
, target
, level
, internalFormat
,
1187 format
, type
, 2, width
, height
, 1, border
)) {
1188 return; /* error in texture image was detected */
1191 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1192 texObj
= texUnit
->CurrentD
[2];
1193 texImage
= texObj
->Image
[level
];
1196 texImage
= _mesa_alloc_texture_image();
1197 texObj
->Image
[level
] = texImage
;
1199 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1203 else if (texImage
->Data
) {
1204 FREE(texImage
->Data
);
1205 texImage
->Data
= NULL
;
1208 /* setup the teximage struct's fields */
1209 init_texture_image(texImage
, width
, height
, 1, border
, internalFormat
);
1211 /* process the texture image */
1213 GLboolean retain
= GL_TRUE
;
1214 GLboolean success
= GL_FALSE
;
1215 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
1216 && ctx
->Driver
.TexImage2D
) {
1217 /* let device driver try to use raw image */
1218 success
= (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, format
,
1219 type
, pixels
, &ctx
->Unpack
,
1220 texObj
, texImage
, &retain
);
1222 if (retain
|| !success
) {
1223 /* make internal copy of the texture image */
1224 make_texture_image(ctx
, texImage
, format
, type
,
1225 pixels
, &ctx
->Unpack
);
1226 if (!success
&& ctx
->Driver
.TexImage2D
) {
1227 /* let device driver try to use unpacked image */
1228 (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, texImage
->Format
,
1229 GL_UNSIGNED_BYTE
, texImage
->Data
,
1230 &_mesa_native_packing
,
1231 texObj
, texImage
, &retain
);
1234 if (!retain
&& texImage
->Data
) {
1235 FREE(texImage
->Data
);
1236 texImage
->Data
= NULL
;
1240 make_null_texture(texImage
);
1241 if (ctx
->Driver
.TexImage2D
) {
1243 (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, texImage
->Format
,
1244 GL_UNSIGNED_BYTE
, texImage
->Data
,
1245 &_mesa_native_packing
,
1246 texObj
, texImage
, &retain
);
1250 #define OLD_DD_TEXTURE
1251 #ifdef OLD_DD_TEXTURE
1252 /* XXX this will be removed in the future */
1253 if (ctx
->Driver
.TexImage
) {
1254 (*ctx
->Driver
.TexImage
)( ctx
, target
, texObj
, level
, internalFormat
,
1260 gl_put_texobj_on_dirty_list( ctx
, texObj
);
1261 ctx
->NewState
|= NEW_TEXTURING
;
1263 else if (target
==GL_PROXY_TEXTURE_2D
) {
1264 /* Proxy texture: check for errors and update proxy state */
1265 if (texture_error_check( ctx
, target
, level
, internalFormat
,
1266 format
, type
, 2, width
, height
, 1, border
)) {
1267 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1268 MEMSET( ctx
->Texture
.Proxy2D
->Image
[level
], 0,
1269 sizeof(struct gl_texture_image
) );
1273 ctx
->Texture
.Proxy2D
->Image
[level
]->Format
= (GLenum
) format
;
1274 set_teximage_component_sizes( ctx
->Texture
.Proxy2D
->Image
[level
] );
1275 ctx
->Texture
.Proxy2D
->Image
[level
]->IntFormat
= (GLenum
) internalFormat
;
1276 ctx
->Texture
.Proxy2D
->Image
[level
]->Border
= border
;
1277 ctx
->Texture
.Proxy2D
->Image
[level
]->Width
= width
;
1278 ctx
->Texture
.Proxy2D
->Image
[level
]->Height
= height
;
1279 ctx
->Texture
.Proxy2D
->Image
[level
]->Depth
= 1;
1283 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1291 * Called by the API or display list executor.
1292 * Note that width and height include the border.
1295 _mesa_TexImage3D( GLenum target
, GLint level
, GLint internalFormat
,
1296 GLsizei width
, GLsizei height
, GLsizei depth
,
1297 GLint border
, GLenum format
, GLenum type
,
1298 const GLvoid
*pixels
)
1300 GET_CURRENT_CONTEXT(ctx
);
1301 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glTexImage3D");
1303 if (target
==GL_TEXTURE_3D_EXT
) {
1304 struct gl_texture_unit
*texUnit
;
1305 struct gl_texture_object
*texObj
;
1306 struct gl_texture_image
*texImage
;
1307 if (texture_error_check( ctx
, target
, level
, internalFormat
,
1308 format
, type
, 3, width
, height
, depth
,
1310 return; /* error in texture image was detected */
1313 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1314 texObj
= texUnit
->CurrentD
[3];
1315 texImage
= texObj
->Image
[level
];
1318 texImage
= _mesa_alloc_texture_image();
1319 texObj
->Image
[level
] = texImage
;
1321 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
1325 else if (texImage
->Data
) {
1326 FREE(texImage
->Data
);
1327 texImage
->Data
= NULL
;
1330 /* setup the teximage struct's fields */
1331 init_texture_image(texImage
, width
, height
, depth
,
1332 border
, internalFormat
);
1334 /* process the texture image */
1336 GLboolean retain
= GL_TRUE
;
1337 GLboolean success
= GL_FALSE
;
1338 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
1339 && ctx
->Driver
.TexImage3D
) {
1340 /* let device driver try to use raw image */
1341 success
= (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, format
,
1342 type
, pixels
, &ctx
->Unpack
,
1343 texObj
, texImage
, &retain
);
1345 if (retain
|| !success
) {
1346 /* make internal copy of the texture image */
1347 make_texture_image(ctx
, texImage
, format
, type
,
1348 pixels
, &ctx
->Unpack
);
1349 if (!success
&& ctx
->Driver
.TexImage3D
) {
1350 /* let device driver try to use unpacked image */
1351 (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, texImage
->Format
,
1352 GL_UNSIGNED_BYTE
, texImage
->Data
,
1353 &_mesa_native_packing
,
1354 texObj
, texImage
, &retain
);
1357 if (!retain
&& texImage
->Data
) {
1358 FREE(texImage
->Data
);
1359 texImage
->Data
= NULL
;
1363 make_null_texture(texImage
);
1364 if (ctx
->Driver
.TexImage3D
) {
1366 (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, texImage
->Format
,
1367 GL_UNSIGNED_BYTE
, texImage
->Data
,
1368 &_mesa_native_packing
,
1369 texObj
, texImage
, &retain
);
1374 gl_put_texobj_on_dirty_list( ctx
, texObj
);
1375 ctx
->NewState
|= NEW_TEXTURING
;
1377 else if (target
==GL_PROXY_TEXTURE_3D_EXT
) {
1378 /* Proxy texture: check for errors and update proxy state */
1379 if (texture_error_check( ctx
, target
, level
, internalFormat
,
1380 format
, type
, 3, width
, height
, depth
,
1382 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1383 MEMSET( ctx
->Texture
.Proxy3D
->Image
[level
], 0,
1384 sizeof(struct gl_texture_image
) );
1388 ctx
->Texture
.Proxy3D
->Image
[level
]->Format
= (GLenum
) format
;
1389 set_teximage_component_sizes( ctx
->Texture
.Proxy3D
->Image
[level
] );
1390 ctx
->Texture
.Proxy3D
->Image
[level
]->IntFormat
= (GLenum
) internalFormat
;
1391 ctx
->Texture
.Proxy3D
->Image
[level
]->Border
= border
;
1392 ctx
->Texture
.Proxy3D
->Image
[level
]->Width
= width
;
1393 ctx
->Texture
.Proxy3D
->Image
[level
]->Height
= height
;
1394 ctx
->Texture
.Proxy3D
->Image
[level
]->Depth
= depth
;
1398 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1405 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
1406 GLsizei width
, GLsizei height
, GLsizei depth
,
1407 GLint border
, GLenum format
, GLenum type
,
1408 const GLvoid
*pixels
)
1410 _mesa_TexImage3D(target
, level
, (GLint
) internalFormat
, width
, height
,
1411 depth
, border
, format
, type
, pixels
);
1416 * Fetch a texture image from the device driver.
1417 * Store the results in the given texture object at the given mipmap level.
1420 _mesa_get_teximage_from_driver( GLcontext
*ctx
, GLenum target
, GLint level
,
1421 const struct gl_texture_object
*texObj
)
1424 GLenum imgFormat
, imgType
;
1425 GLboolean freeImage
;
1426 struct gl_texture_image
*texImage
;
1427 GLint destComponents
, numPixels
, srcBytesPerTexel
;
1429 if (!ctx
->Driver
.GetTexImage
)
1432 image
= (*ctx
->Driver
.GetTexImage
)( ctx
, target
, level
, texObj
,
1433 &imgFormat
, &imgType
, &freeImage
);
1437 texImage
= texObj
->Image
[level
];
1442 destComponents
= components_in_intformat(texImage
->Format
);
1443 assert(destComponents
> 0);
1444 numPixels
= texImage
->Width
* texImage
->Height
* texImage
->Depth
;
1445 assert(numPixels
> 0);
1446 srcBytesPerTexel
= _mesa_bytes_per_pixel(imgFormat
, imgType
);
1447 assert(srcBytesPerTexel
> 0);
1449 if (!texImage
->Data
) {
1450 /* Allocate memory for the texture image data */
1451 texImage
->Data
= (GLubyte
*) MALLOC(numPixels
* destComponents
+ EXTRA_BYTE
);
1454 if (imgFormat
== texImage
->Format
&& imgType
== GL_UNSIGNED_BYTE
) {
1455 /* We got lucky! The driver's format and type match Mesa's format. */
1456 if (texImage
->Data
) {
1457 MEMCPY(texImage
->Data
, image
, numPixels
* destComponents
);
1461 /* Convert the texture image from the driver's format to Mesa's
1464 const GLint width
= texImage
->Width
;
1465 const GLint height
= texImage
->Height
;
1466 const GLint depth
= texImage
->Depth
;
1467 const GLint destBytesPerRow
= width
* destComponents
* sizeof(GLchan
);
1468 const GLint srcBytesPerRow
= width
* srcBytesPerTexel
;
1469 const GLenum dstType
= GL_UNSIGNED_BYTE
;
1470 const GLenum dstFormat
= texImage
->Format
;
1471 const GLubyte
*srcPtr
= (const GLubyte
*) image
;
1472 GLubyte
*destPtr
= texImage
->Data
;
1474 if (texImage
->Format
== GL_COLOR_INDEX
) {
1475 /* color index texture */
1477 assert(imgFormat
== GL_COLOR_INDEX
);
1478 for (img
= 0; img
< depth
; img
++) {
1479 for (row
= 0; row
< height
; row
++) {
1480 _mesa_unpack_index_span(ctx
, width
, dstType
, destPtr
,
1481 imgType
, srcPtr
, &_mesa_native_packing
, GL_FALSE
);
1482 destPtr
+= destBytesPerRow
;
1483 srcPtr
+= srcBytesPerRow
;
1490 for (img
= 0; img
< depth
; img
++) {
1491 for (row
= 0; row
< height
; row
++) {
1492 _mesa_unpack_ubyte_color_span(ctx
, width
, dstFormat
, destPtr
,
1493 imgFormat
, imgType
, srcPtr
, &_mesa_native_packing
, GL_FALSE
);
1494 destPtr
+= destBytesPerRow
;
1495 srcPtr
+= srcBytesPerRow
;
1507 _mesa_GetTexImage( GLenum target
, GLint level
, GLenum format
,
1508 GLenum type
, GLvoid
*pixels
)
1510 GET_CURRENT_CONTEXT(ctx
);
1511 const struct gl_texture_object
*texObj
;
1512 struct gl_texture_image
*texImage
;
1513 GLboolean discardImage
;
1515 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetTexImage");
1517 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1518 gl_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
1522 if (_mesa_sizeof_type(type
) <= 0) {
1523 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
1527 if (_mesa_components_in_format(format
) <= 0) {
1528 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
1537 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[1];
1540 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[2];
1543 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[3];
1546 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)" );
1550 texImage
= texObj
->Image
[level
];
1552 /* invalid mipmap level */
1556 if (!texImage
->Data
) {
1557 /* try to get the texture image from the device driver */
1558 _mesa_get_teximage_from_driver(ctx
, target
, level
, texObj
);
1559 discardImage
= GL_TRUE
;
1562 discardImage
= GL_FALSE
;
1565 if (texImage
->Data
) {
1566 GLint width
= texImage
->Width
;
1567 GLint height
= texImage
->Height
;
1570 for (row
= 0; row
< height
; row
++) {
1571 /* compute destination address in client memory */
1572 GLvoid
*dest
= _mesa_image_address( &ctx
->Unpack
, pixels
,
1574 format
, type
, 0, row
, 0);
1577 if (texImage
->Format
== GL_RGBA
) {
1578 const GLubyte
*src
= texImage
->Data
+ row
* width
* 4 * sizeof(GLubyte
);
1579 _mesa_pack_rgba_span( ctx
, width
, (CONST
GLubyte (*)[4]) src
,
1580 format
, type
, dest
, &ctx
->Pack
, GL_TRUE
);
1583 /* fetch RGBA row from texture image then pack it in client mem */
1584 GLubyte rgba
[MAX_WIDTH
][4];
1587 switch (texImage
->Format
) {
1589 src
= texImage
->Data
+ row
* width
* sizeof(GLubyte
);
1590 for (i
= 0; i
< width
; i
++) {
1591 rgba
[i
][RCOMP
] = 255;
1592 rgba
[i
][GCOMP
] = 255;
1593 rgba
[i
][BCOMP
] = 255;
1594 rgba
[i
][ACOMP
] = src
[i
];
1598 src
= texImage
->Data
+ row
* width
* sizeof(GLubyte
);
1599 for (i
= 0; i
< width
; i
++) {
1600 rgba
[i
][RCOMP
] = src
[i
];
1601 rgba
[i
][GCOMP
] = src
[i
];
1602 rgba
[i
][BCOMP
] = src
[i
];
1603 rgba
[i
][ACOMP
] = 255;
1606 case GL_LUMINANCE_ALPHA
:
1607 src
= texImage
->Data
+ row
* 2 * width
* sizeof(GLubyte
);
1608 for (i
= 0; i
< width
; i
++) {
1609 rgba
[i
][RCOMP
] = src
[i
*2+0];
1610 rgba
[i
][GCOMP
] = src
[i
*2+0];
1611 rgba
[i
][BCOMP
] = src
[i
*2+0];
1612 rgba
[i
][ACOMP
] = src
[i
*2+1];
1616 src
= texImage
->Data
+ row
* width
* sizeof(GLubyte
);
1617 for (i
= 0; i
< width
; i
++) {
1618 rgba
[i
][RCOMP
] = src
[i
];
1619 rgba
[i
][GCOMP
] = src
[i
];
1620 rgba
[i
][BCOMP
] = src
[i
];
1621 rgba
[i
][ACOMP
] = 255;
1625 src
= texImage
->Data
+ row
* 3 * width
* sizeof(GLubyte
);
1626 for (i
= 0; i
< width
; i
++) {
1627 rgba
[i
][RCOMP
] = src
[i
*3+0];
1628 rgba
[i
][GCOMP
] = src
[i
*3+1];
1629 rgba
[i
][BCOMP
] = src
[i
*3+2];
1630 rgba
[i
][ACOMP
] = 255;
1634 /* this special case should have been handled above! */
1635 gl_problem( ctx
, "error 1 in gl_GetTexImage" );
1637 case GL_COLOR_INDEX
:
1638 gl_problem( ctx
, "GL_COLOR_INDEX not implemented in gl_GetTexImage" );
1641 gl_problem( ctx
, "bad format in gl_GetTexImage" );
1643 _mesa_pack_rgba_span( ctx
, width
, (const GLubyte (*)[4])rgba
,
1644 format
, type
, dest
, &ctx
->Pack
, GL_TRUE
);
1648 /* if we got the teximage from the device driver we'll discard it now */
1650 FREE(texImage
->Data
);
1651 texImage
->Data
= NULL
;
1659 _mesa_TexSubImage1D( GLenum target
, GLint level
,
1660 GLint xoffset
, GLsizei width
,
1661 GLenum format
, GLenum type
,
1662 const GLvoid
*pixels
)
1664 GET_CURRENT_CONTEXT(ctx
);
1665 struct gl_texture_unit
*texUnit
;
1666 struct gl_texture_object
*texObj
;
1667 struct gl_texture_image
*texImage
;
1668 GLboolean success
= GL_FALSE
;
1670 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
1671 width
, 1, 1, format
, type
)) {
1672 return; /* error was detected */
1675 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1676 texObj
= texUnit
->CurrentD
[1];
1677 texImage
= texObj
->Image
[level
];
1680 if (width
== 0 || !pixels
)
1681 return; /* no-op, not an error */
1684 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
1685 && ctx
->Driver
.TexSubImage1D
) {
1686 success
= (*ctx
->Driver
.TexSubImage1D
)( ctx
, target
, level
, xoffset
,
1687 width
, format
, type
, pixels
,
1688 &ctx
->Unpack
, texObj
, texImage
);
1691 /* XXX if Driver.TexSubImage1D, unpack image and try again? */
1693 const GLint texComponents
= components_in_intformat(texImage
->Format
);
1694 const GLenum texFormat
= texImage
->Format
;
1695 const GLint xoffsetb
= xoffset
+ texImage
->Border
;
1696 GLboolean retain
= GL_TRUE
;
1697 if (!texImage
->Data
) {
1698 _mesa_get_teximage_from_driver( ctx
, target
, level
, texObj
);
1699 if (!texImage
->Data
) {
1700 make_null_texture(texImage
);
1702 if (!texImage
->Data
)
1703 return; /* we're really out of luck! */
1706 if (texFormat
== GL_COLOR_INDEX
) {
1707 /* color index texture */
1708 GLubyte
*dst
= texImage
->Data
+ xoffsetb
* texComponents
;
1709 const GLvoid
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
, width
,
1710 1, format
, type
, 0, 0, 0);
1711 _mesa_unpack_index_span(ctx
, width
, GL_UNSIGNED_BYTE
, dst
,
1712 type
, src
, &ctx
->Unpack
, GL_TRUE
);
1716 GLubyte
*dst
= texImage
->Data
+ xoffsetb
* texComponents
;
1717 const GLvoid
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
, width
,
1718 1, format
, type
, 0, 0, 0);
1719 _mesa_unpack_ubyte_color_span(ctx
, width
, texFormat
, dst
, format
,
1720 type
, src
, &ctx
->Unpack
, GL_TRUE
);
1723 if (ctx
->Driver
.TexImage1D
) {
1724 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
1725 GL_UNSIGNED_BYTE
, texImage
->Data
,
1726 &_mesa_native_packing
, texObj
, texImage
,
1730 if (!retain
&& texImage
->Data
) {
1731 FREE(texImage
->Data
);
1732 texImage
->Data
= NULL
;
1736 /*gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[1] );*/
1741 _mesa_TexSubImage2D( GLenum target
, GLint level
,
1742 GLint xoffset
, GLint yoffset
,
1743 GLsizei width
, GLsizei height
,
1744 GLenum format
, GLenum type
,
1745 const GLvoid
*pixels
)
1747 GET_CURRENT_CONTEXT(ctx
);
1748 struct gl_texture_unit
*texUnit
;
1749 struct gl_texture_object
*texObj
;
1750 struct gl_texture_image
*texImage
;
1751 GLboolean success
= GL_FALSE
;
1753 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1754 width
, height
, 1, format
, type
)) {
1755 return; /* error was detected */
1758 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1759 texObj
= texUnit
->CurrentD
[2];
1760 texImage
= texObj
->Image
[level
];
1763 if (width
== 0 || height
== 0 || !pixels
)
1764 return; /* no-op, not an error */
1766 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
1767 && ctx
->Driver
.TexSubImage2D
) {
1768 success
= (*ctx
->Driver
.TexSubImage2D
)( ctx
, target
, level
, xoffset
,
1769 yoffset
, width
, height
, format
, type
,
1770 pixels
, &ctx
->Unpack
, texObj
, texImage
);
1773 /* XXX if Driver.TexSubImage2D, unpack image and try again? */
1775 const GLint texComponents
= components_in_intformat(texImage
->Format
);
1776 const GLenum texFormat
= texImage
->Format
;
1777 const GLint xoffsetb
= xoffset
+ texImage
->Border
;
1778 const GLint yoffsetb
= yoffset
+ texImage
->Border
;
1779 const GLint srcStride
= _mesa_image_row_stride(&ctx
->Unpack
, width
,
1781 const GLint dstStride
= texImage
->Width
* texComponents
*sizeof(GLubyte
);
1782 GLboolean retain
= GL_TRUE
;
1784 if (!texImage
->Data
) {
1785 _mesa_get_teximage_from_driver( ctx
, target
, level
, texObj
);
1786 if (!texImage
->Data
) {
1787 make_null_texture(texImage
);
1789 if (!texImage
->Data
)
1790 return; /* we're really out of luck! */
1793 if (texFormat
== GL_COLOR_INDEX
) {
1794 /* color index texture */
1795 GLubyte
*dst
= texImage
->Data
1796 + (yoffsetb
* texImage
->Width
+ xoffsetb
) * texComponents
;
1797 const GLubyte
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
,
1798 width
, height
, format
, type
, 0, 0, 0);
1800 for (row
= 0; row
< height
; row
++) {
1801 _mesa_unpack_index_span(ctx
, width
, GL_UNSIGNED_BYTE
, dst
, type
,
1802 (const GLvoid
*) src
, &ctx
->Unpack
, GL_TRUE
);
1809 GLubyte
*dst
= texImage
->Data
1810 + (yoffsetb
* texImage
->Width
+ xoffsetb
) * texComponents
;
1811 const GLubyte
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
,
1812 width
, height
, format
, type
, 0, 0, 0);
1814 for (row
= 0; row
< height
; row
++) {
1815 _mesa_unpack_ubyte_color_span(ctx
, width
, texFormat
, dst
, format
,
1816 type
, (const GLvoid
*) src
, &ctx
->Unpack
, GL_TRUE
);
1822 if (ctx
->Driver
.TexImage2D
) {
1823 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, texImage
->Format
,
1824 GL_UNSIGNED_BYTE
, texImage
->Data
,
1825 &_mesa_native_packing
, texObj
, texImage
,
1829 if (!retain
&& texImage
->Data
) {
1830 FREE(texImage
->Data
);
1831 texImage
->Data
= NULL
;
1834 #ifdef OLD_DD_TEXTURE
1835 /* XXX this will be removed in the future */
1836 if (ctx
->Driver
.TexSubImage
) {
1837 (*ctx
->Driver
.TexSubImage
)(ctx
, target
, texObj
, level
,
1838 xoffset
, yoffset
, width
, height
,
1839 texImage
->IntFormat
, texImage
);
1841 else if (ctx
->Driver
.TexImage
) {
1842 (*ctx
->Driver
.TexImage
)(ctx
, GL_TEXTURE_2D
, texObj
,
1843 level
, texImage
->IntFormat
, texImage
);
1852 _mesa_TexSubImage3D( GLenum target
, GLint level
,
1853 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1854 GLsizei width
, GLsizei height
, GLsizei depth
,
1855 GLenum format
, GLenum type
,
1856 const GLvoid
*pixels
)
1858 GET_CURRENT_CONTEXT(ctx
);
1859 struct gl_texture_unit
*texUnit
;
1860 struct gl_texture_object
*texObj
;
1861 struct gl_texture_image
*texImage
;
1862 GLboolean success
= GL_FALSE
;
1864 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
1865 width
, height
, depth
, format
, type
)) {
1866 return; /* error was detected */
1869 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1870 texObj
= texUnit
->CurrentD
[3];
1871 texImage
= texObj
->Image
[level
];
1874 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
1875 return; /* no-op, not an error */
1877 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
1878 && ctx
->Driver
.TexSubImage3D
) {
1879 success
= (*ctx
->Driver
.TexSubImage3D
)( ctx
, target
, level
, xoffset
,
1880 yoffset
, zoffset
, width
, height
, depth
, format
,
1881 type
, pixels
, &ctx
->Unpack
, texObj
, texImage
);
1884 /* XXX if Driver.TexSubImage3D, unpack image and try again? */
1886 const GLint texComponents
= components_in_intformat(texImage
->Format
);
1887 const GLenum texFormat
= texImage
->Format
;
1888 const GLint xoffsetb
= xoffset
+ texImage
->Border
;
1889 const GLint yoffsetb
= yoffset
+ texImage
->Border
;
1890 const GLint zoffsetb
= zoffset
+ texImage
->Border
;
1891 const GLint texWidth
= texImage
->Width
;
1892 const GLint dstRectArea
= texWidth
* texImage
->Height
;
1893 const GLint srcStride
= _mesa_image_row_stride(&ctx
->Unpack
,
1894 width
, format
, type
);
1895 const GLint dstStride
= texWidth
* texComponents
* sizeof(GLubyte
);
1896 GLboolean retain
= GL_TRUE
;
1898 if (texFormat
== GL_COLOR_INDEX
) {
1899 /* color index texture */
1901 for (img
= 0; img
< depth
; img
++) {
1902 const GLubyte
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
,
1903 width
, height
, format
, type
, img
, 0, 0);
1904 GLubyte
*dst
= texImage
->Data
+ ((zoffsetb
+ img
) * dstRectArea
1905 + yoffsetb
* texWidth
+ xoffsetb
) * texComponents
;
1906 for (row
= 0; row
< height
; row
++) {
1907 _mesa_unpack_index_span(ctx
, width
, GL_UNSIGNED_BYTE
, dst
,
1908 type
, (const GLvoid
*) src
, &ctx
->Unpack
, GL_TRUE
);
1917 for (img
= 0; img
< depth
; img
++) {
1918 const GLubyte
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
,
1919 width
, height
, format
, type
, img
, 0, 0);
1920 GLubyte
*dst
= texImage
->Data
+ ((zoffsetb
+ img
) * dstRectArea
1921 + yoffsetb
* texWidth
+ xoffsetb
) * texComponents
;
1922 for (row
= 0; row
< height
; row
++) {
1923 _mesa_unpack_ubyte_color_span(ctx
, width
, texFormat
, dst
,
1924 format
, type
, (const GLvoid
*) src
, &ctx
->Unpack
, GL_TRUE
);
1931 if (ctx
->Driver
.TexImage3D
) {
1932 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, texImage
->Format
,
1933 GL_UNSIGNED_BYTE
, texImage
->Data
,
1934 &_mesa_native_packing
, texObj
, texImage
,
1938 if (!retain
&& texImage
->Data
) {
1939 FREE(texImage
->Data
);
1940 texImage
->Data
= NULL
;
1948 * Read an RGBA image from the frame buffer.
1949 * This is used by glCopyTexSubImage[12]D().
1950 * Input: ctx - the context
1951 * x, y - lower left corner
1952 * width, height - size of region to read
1953 * Return: pointer to block of GL_RGBA, GLubyte data.
1956 read_color_image( GLcontext
*ctx
, GLint x
, GLint y
,
1957 GLsizei width
, GLsizei height
)
1960 GLubyte
*image
, *dst
;
1962 image
= (GLubyte
*) MALLOC(width
* height
* 4 * sizeof(GLubyte
));
1966 /* Select buffer to read from */
1967 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->ReadBuffer
,
1968 ctx
->Pixel
.DriverReadBuffer
);
1971 stride
= width
* 4 * sizeof(GLubyte
);
1972 for (i
= 0; i
< height
; i
++) {
1973 gl_read_rgba_span( ctx
, ctx
->ReadBuffer
, width
, x
, y
+ i
,
1974 (GLubyte (*)[4]) dst
);
1978 /* Read from draw buffer (the default) */
1979 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->DrawBuffer
,
1980 ctx
->Color
.DriverDrawBuffer
);
1988 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
1989 GLenum internalFormat
,
1991 GLsizei width
, GLint border
)
1993 GET_CURRENT_CONTEXT(ctx
);
1994 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexImage1D");
1996 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
2000 if (ctx
->Pixel
.MapColorFlag
|| ctx
->Pixel
.ScaleOrBiasRGBA
2001 || !ctx
->Driver
.CopyTexImage1D
2002 || !(*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
,
2003 internalFormat
, x
, y
, width
, border
))
2005 GLubyte
*image
= read_color_image( ctx
, x
, y
, width
, 1 );
2007 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D" );
2010 (*ctx
->Exec
->TexImage1D
)( target
, level
, internalFormat
, width
,
2011 border
, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2019 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
2020 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
2023 GET_CURRENT_CONTEXT(ctx
);
2024 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexImage2D");
2026 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
2027 width
, height
, border
))
2030 if (ctx
->Pixel
.MapColorFlag
|| ctx
->Pixel
.ScaleOrBiasRGBA
2031 || !ctx
->Driver
.CopyTexImage2D
2032 || !(*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
,
2033 internalFormat
, x
, y
, width
, height
, border
))
2035 GLubyte
*image
= read_color_image( ctx
, x
, y
, width
, height
);
2037 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D" );
2040 (ctx
->Exec
->TexImage2D
)( target
, level
, internalFormat
, width
,
2041 height
, border
, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2049 * Do the work of glCopyTexSubImage[123]D.
2052 copy_tex_sub_image( GLcontext
*ctx
, struct gl_texture_image
*dest
,
2053 GLint width
, GLint height
,
2054 GLint srcx
, GLint srcy
,
2055 GLint dstx
, GLint dsty
, GLint dstz
)
2058 GLint format
, components
, rectarea
;
2059 GLint texwidth
, texheight
, zoffset
;
2061 /* dst[xyz] may be negative if we have a texture border! */
2062 dstx
+= dest
->Border
;
2063 dsty
+= dest
->Border
;
2064 dstz
+= dest
->Border
;
2065 texwidth
= dest
->Width
;
2066 texheight
= dest
->Height
;
2067 rectarea
= texwidth
* texheight
;
2068 zoffset
= dstz
* rectarea
;
2069 format
= dest
->Format
;
2070 components
= components_in_intformat( format
);
2072 /* Select buffer to read from */
2073 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->ReadBuffer
,
2074 ctx
->Pixel
.DriverReadBuffer
);
2076 for (i
= 0;i
< height
; i
++) {
2077 GLubyte rgba
[MAX_WIDTH
][4];
2079 gl_read_rgba_span( ctx
, ctx
->ReadBuffer
, width
, srcx
, srcy
+ i
, rgba
);
2080 dst
= dest
->Data
+ ( zoffset
+ (dsty
+i
) * texwidth
+ dstx
) * components
;
2081 _mesa_unpack_ubyte_color_span(ctx
, width
, format
, dst
,
2082 GL_RGBA
, GL_UNSIGNED_BYTE
, rgba
,
2083 &_mesa_native_packing
, GL_TRUE
);
2086 /* Read from draw buffer (the default) */
2087 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->DrawBuffer
,
2088 ctx
->Color
.DriverDrawBuffer
);
2095 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
2096 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
2098 GET_CURRENT_CONTEXT(ctx
);
2099 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexSubImage1D");
2101 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
2102 xoffset
, 0, 0, width
, 1))
2105 if (ctx
->Pixel
.MapColorFlag
|| ctx
->Pixel
.ScaleOrBiasRGBA
2106 || !ctx
->Driver
.CopyTexSubImage1D
2107 || !(*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
,
2108 xoffset
, x
, y
, width
)) {
2109 struct gl_texture_unit
*texUnit
;
2110 struct gl_texture_image
*teximage
;
2111 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2112 teximage
= texUnit
->CurrentD
[1]->Image
[level
];
2114 if (teximage
->Data
) {
2115 copy_tex_sub_image(ctx
, teximage
, width
, 1, x
, y
, xoffset
, 0, 0);
2116 /* tell driver about the change */
2117 /* XXX this is obsolete */
2118 if (ctx
->Driver
.TexImage
) {
2119 (*ctx
->Driver
.TexImage
)( ctx
, GL_TEXTURE_1D
,
2120 texUnit
->CurrentD
[1],
2121 level
, teximage
->IntFormat
, teximage
);
2130 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
2131 GLint xoffset
, GLint yoffset
,
2132 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2134 GET_CURRENT_CONTEXT(ctx
);
2135 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexSubImage2D");
2137 if (copytexsubimage_error_check(ctx
, 2, target
, level
,
2138 xoffset
, yoffset
, 0, width
, height
))
2141 if (ctx
->Pixel
.MapColorFlag
|| ctx
->Pixel
.ScaleOrBiasRGBA
2142 || !ctx
->Driver
.CopyTexSubImage2D
2143 || !(*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
2144 xoffset
, yoffset
, x
, y
, width
, height
)) {
2145 struct gl_texture_unit
*texUnit
;
2146 struct gl_texture_image
*teximage
;
2147 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2148 teximage
= texUnit
->CurrentD
[2]->Image
[level
];
2150 if (teximage
->Data
) {
2151 copy_tex_sub_image(ctx
, teximage
, width
, height
,
2152 x
, y
, xoffset
, yoffset
, 0);
2153 /* tell driver about the change */
2154 /* XXX this is obsolete */
2155 if (ctx
->Driver
.TexImage
) {
2156 (*ctx
->Driver
.TexImage
)( ctx
, GL_TEXTURE_2D
,
2157 texUnit
->CurrentD
[2],
2158 level
, teximage
->IntFormat
, teximage
);
2167 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
2168 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2169 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2171 GET_CURRENT_CONTEXT(ctx
);
2172 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexSubImage3D");
2174 if (copytexsubimage_error_check(ctx
, 3, target
, level
,
2175 xoffset
, yoffset
, zoffset
, width
, height
))
2178 if (ctx
->Pixel
.MapColorFlag
|| ctx
->Pixel
.ScaleOrBiasRGBA
2179 || !ctx
->Driver
.CopyTexSubImage3D
2180 || !(*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
2181 xoffset
, yoffset
, zoffset
, x
, y
, width
, height
)) {
2182 struct gl_texture_unit
*texUnit
;
2183 struct gl_texture_image
*teximage
;
2184 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2185 teximage
= texUnit
->CurrentD
[3]->Image
[level
];
2187 if (teximage
->Data
) {
2188 copy_tex_sub_image(ctx
, teximage
, width
, height
,
2189 x
, y
, xoffset
, yoffset
, zoffset
);
2190 /* tell driver about the change */
2191 /* XXX this is obsolete */
2192 if (ctx
->Driver
.TexImage
) {
2193 (*ctx
->Driver
.TexImage
)( ctx
, GL_TEXTURE_3D
,
2194 texUnit
->CurrentD
[3],
2195 level
, teximage
->IntFormat
, teximage
);