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( GLcontext
*ctx
, GLint format
)
143 case GL_COMPRESSED_ALPHA_ARB
:
144 if (ctx
&& !ctx
->Extensions
.HaveTextureCompression
)
153 case GL_COMPRESSED_LUMINANCE_ARB
:
154 if (ctx
&& !ctx
->Extensions
.HaveTextureCompression
)
164 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
165 if (ctx
&& !ctx
->Extensions
.HaveTextureCompression
)
169 case GL_LUMINANCE_ALPHA
:
170 case GL_LUMINANCE4_ALPHA4
:
171 case GL_LUMINANCE6_ALPHA2
:
172 case GL_LUMINANCE8_ALPHA8
:
173 case GL_LUMINANCE12_ALPHA4
:
174 case GL_LUMINANCE12_ALPHA12
:
175 case GL_LUMINANCE16_ALPHA16
:
176 return GL_LUMINANCE_ALPHA
;
177 case GL_COMPRESSED_INTENSITY_ARB
:
178 if (ctx
&& !ctx
->Extensions
.HaveTextureCompression
)
187 case GL_COMPRESSED_RGB_ARB
:
188 if (ctx
&& ctx
->Extensions
.HaveTextureCompression
)
192 case GL_COMPRESSED_RGB_FXT1_3DFX
:
193 if (ctx
&& ctx
->Extensions
.HaveTextureCompressionFXT1
)
197 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
198 if (ctx
&& ctx
->Extensions
.HaveTextureCompressionS3TC
)
212 case GL_COMPRESSED_RGBA_ARB
:
213 if (ctx
&& ctx
->Extensions
.HaveTextureCompression
)
217 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
218 if (ctx
&& ctx
->Extensions
.HaveTextureCompressionFXT1
)
222 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
223 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
224 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
225 if (ctx
&& ctx
->Extensions
.HaveTextureCompressionS3TC
)
240 case GL_COLOR_INDEX1_EXT
:
241 case GL_COLOR_INDEX2_EXT
:
242 case GL_COLOR_INDEX4_EXT
:
243 case GL_COLOR_INDEX8_EXT
:
244 case GL_COLOR_INDEX12_EXT
:
245 case GL_COLOR_INDEX16_EXT
:
246 return GL_COLOR_INDEX
;
248 return -1; /* error */
255 * Given an internal texture format enum or 1, 2, 3, 4 return the
256 * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE,
257 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA. Return the
258 * number of components for the format. Return -1 if invalid enum.
261 components_in_intformat( GLint format
)
278 case GL_LUMINANCE_ALPHA
:
279 case GL_LUMINANCE4_ALPHA4
:
280 case GL_LUMINANCE6_ALPHA2
:
281 case GL_LUMINANCE8_ALPHA8
:
282 case GL_LUMINANCE12_ALPHA4
:
283 case GL_LUMINANCE12_ALPHA12
:
284 case GL_LUMINANCE16_ALPHA16
:
313 case GL_COLOR_INDEX1_EXT
:
314 case GL_COLOR_INDEX2_EXT
:
315 case GL_COLOR_INDEX4_EXT
:
316 case GL_COLOR_INDEX8_EXT
:
317 case GL_COLOR_INDEX12_EXT
:
318 case GL_COLOR_INDEX16_EXT
:
321 return -1; /* error */
327 * Return GL_TRUE if internalFormat is a compressed format, return GL_FALSE
331 is_compressed_format(GLenum internalFormat
)
333 switch (internalFormat
) {
334 case GL_COMPRESSED_ALPHA_ARB
:
335 case GL_COMPRESSED_LUMINANCE_ARB
:
336 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
337 case GL_COMPRESSED_INTENSITY_ARB
:
338 case GL_COMPRESSED_RGB_ARB
:
339 case GL_COMPRESSED_RGBA_ARB
:
340 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
341 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
342 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
343 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
344 case GL_COMPRESSED_RGB_FXT1_3DFX
:
345 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
355 * Examine the texImage->Format field and set the Red, Green, Blue, etc
356 * texel component sizes to default values.
357 * These fields are set only here by core Mesa but device drivers may
358 * overwritting these fields to indicate true texel resolution.
361 set_teximage_component_sizes( struct gl_texture_image
*texImage
)
363 switch (texImage
->Format
) {
365 texImage
->RedBits
= 0;
366 texImage
->GreenBits
= 0;
367 texImage
->BlueBits
= 0;
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
= 8;
380 texImage
->IndexBits
= 0;
382 case GL_LUMINANCE_ALPHA
:
383 texImage
->RedBits
= 0;
384 texImage
->GreenBits
= 0;
385 texImage
->BlueBits
= 0;
386 texImage
->AlphaBits
= 8;
387 texImage
->IntensityBits
= 0;
388 texImage
->LuminanceBits
= 8;
389 texImage
->IndexBits
= 0;
392 texImage
->RedBits
= 0;
393 texImage
->GreenBits
= 0;
394 texImage
->BlueBits
= 0;
395 texImage
->AlphaBits
= 0;
396 texImage
->IntensityBits
= 8;
397 texImage
->LuminanceBits
= 0;
398 texImage
->IndexBits
= 0;
401 texImage
->RedBits
= 8;
402 texImage
->GreenBits
= 0;
403 texImage
->BlueBits
= 0;
404 texImage
->AlphaBits
= 0;
405 texImage
->IntensityBits
= 0;
406 texImage
->LuminanceBits
= 0;
407 texImage
->IndexBits
= 0;
410 texImage
->RedBits
= 0;
411 texImage
->GreenBits
= 8;
412 texImage
->BlueBits
= 0;
413 texImage
->AlphaBits
= 0;
414 texImage
->IntensityBits
= 0;
415 texImage
->LuminanceBits
= 0;
416 texImage
->IndexBits
= 0;
419 texImage
->RedBits
= 0;
420 texImage
->GreenBits
= 0;
421 texImage
->BlueBits
= 8;
422 texImage
->AlphaBits
= 0;
423 texImage
->IntensityBits
= 0;
424 texImage
->LuminanceBits
= 0;
425 texImage
->IndexBits
= 0;
429 texImage
->RedBits
= 8;
430 texImage
->GreenBits
= 8;
431 texImage
->BlueBits
= 8;
432 texImage
->AlphaBits
= 0;
433 texImage
->IntensityBits
= 0;
434 texImage
->LuminanceBits
= 0;
435 texImage
->IndexBits
= 0;
440 texImage
->RedBits
= 8;
441 texImage
->GreenBits
= 8;
442 texImage
->BlueBits
= 8;
443 texImage
->AlphaBits
= 8;
444 texImage
->IntensityBits
= 0;
445 texImage
->LuminanceBits
= 0;
446 texImage
->IndexBits
= 0;
449 texImage
->RedBits
= 0;
450 texImage
->GreenBits
= 0;
451 texImage
->BlueBits
= 0;
452 texImage
->AlphaBits
= 0;
453 texImage
->IntensityBits
= 0;
454 texImage
->LuminanceBits
= 0;
455 texImage
->IndexBits
= 8;
458 gl_problem(NULL
, "unexpected format in set_teximage_component_sizes");
464 set_tex_image(struct gl_texture_object
*tObj
,
465 GLenum target
, GLint level
,
466 struct gl_texture_image
*texImage
)
472 tObj
->Image
[level
] = texImage
;
474 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
475 tObj
->PosX
[level
] = texImage
;
477 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
478 tObj
->NegX
[level
] = texImage
;
480 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
481 tObj
->PosY
[level
] = texImage
;
483 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
484 tObj
->NegY
[level
] = texImage
;
486 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
487 tObj
->PosZ
[level
] = texImage
;
489 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
490 tObj
->NegZ
[level
] = texImage
;
493 gl_problem(NULL
, "bad target in set_tex_image()");
500 * Return new gl_texture_image struct with all fields initialized to zero.
502 struct gl_texture_image
*
503 _mesa_alloc_texture_image( void )
505 return CALLOC_STRUCT(gl_texture_image
);
511 * Initialize most fields of a gl_texture_image struct.
514 init_texture_image( struct gl_texture_image
*img
,
515 GLsizei width
, GLsizei height
, GLsizei depth
,
516 GLint border
, GLenum internalFormat
)
520 img
->Format
= (GLenum
) _mesa_base_tex_format(NULL
, internalFormat
);
521 set_teximage_component_sizes( img
);
522 img
->IntFormat
= (GLenum
) internalFormat
;
523 img
->Border
= border
;
525 img
->Height
= height
;
527 img
->WidthLog2
= logbase2(width
- 2 * border
);
528 if (height
== 1) /* 1-D texture */
531 img
->HeightLog2
= logbase2(height
- 2 * border
);
532 if (depth
== 1) /* 2-D texture */
535 img
->DepthLog2
= logbase2(depth
- 2 * border
);
536 img
->Width2
= 1 << img
->WidthLog2
;
537 img
->Height2
= 1 << img
->HeightLog2
;
538 img
->Depth2
= 1 << img
->DepthLog2
;
539 img
->MaxLog2
= MAX2(img
->WidthLog2
, img
->HeightLog2
);
540 img
->IsCompressed
= is_compressed_format(internalFormat
);
546 _mesa_free_texture_image( struct gl_texture_image
*teximage
)
548 if (teximage
->Data
) {
549 FREE( teximage
->Data
);
550 teximage
->Data
= NULL
;
558 * Return number of bytes of storage needed to store a compressed texture
562 _mesa_compressed_image_size(GLenum internalFormat
,
563 GLint width
, GLint height
, GLint depth
)
571 * Given a texture unit and a texture target, return the corresponding
574 struct gl_texture_object
*
575 _mesa_select_tex_object(GLcontext
*ctx
, struct gl_texture_unit
*texUnit
,
580 return texUnit
->CurrentD
[1];
581 case GL_PROXY_TEXTURE_1D
:
582 return ctx
->Texture
.Proxy1D
;
584 return texUnit
->CurrentD
[2];
585 case GL_PROXY_TEXTURE_2D
:
586 return ctx
->Texture
.Proxy2D
;
588 return texUnit
->CurrentD
[3];
589 case GL_PROXY_TEXTURE_3D
:
590 return ctx
->Texture
.Proxy3D
;
591 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
592 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
593 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
594 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
595 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
596 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
597 return ctx
->Extensions
.HaveTextureCubeMap
598 ? texUnit
->CurrentCubeMap
: NULL
;
599 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
600 return ctx
->Extensions
.HaveTextureCubeMap
601 ? ctx
->Texture
.ProxyCubeMap
: NULL
;
603 gl_problem(NULL
, "bad target in _mesa_select_tex_object()");
610 * Return the texture image struct which corresponds to target and level
611 * for the given texture unit.
613 struct gl_texture_image
*
614 _mesa_select_tex_image(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
615 GLenum target
, GLint level
)
620 return texUnit
->CurrentD
[1]->Image
[level
];
621 case GL_PROXY_TEXTURE_1D
:
622 return ctx
->Texture
.Proxy1D
->Image
[level
];
624 return texUnit
->CurrentD
[2]->Image
[level
];
625 case GL_PROXY_TEXTURE_2D
:
626 return ctx
->Texture
.Proxy2D
->Image
[level
];
628 return texUnit
->CurrentD
[3]->Image
[level
];
629 case GL_PROXY_TEXTURE_3D
:
630 return ctx
->Texture
.Proxy3D
->Image
[level
];
631 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
632 if (ctx
->Extensions
.HaveTextureCubeMap
)
633 return texUnit
->CurrentCubeMap
->PosX
[level
];
636 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
637 if (ctx
->Extensions
.HaveTextureCubeMap
)
638 return texUnit
->CurrentCubeMap
->NegX
[level
];
641 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
642 if (ctx
->Extensions
.HaveTextureCubeMap
)
643 return texUnit
->CurrentCubeMap
->PosY
[level
];
646 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
647 if (ctx
->Extensions
.HaveTextureCubeMap
)
648 return texUnit
->CurrentCubeMap
->NegY
[level
];
651 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
652 if (ctx
->Extensions
.HaveTextureCubeMap
)
653 return texUnit
->CurrentCubeMap
->PosZ
[level
];
656 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
657 if (ctx
->Extensions
.HaveTextureCubeMap
)
658 return texUnit
->CurrentCubeMap
->NegZ
[level
];
661 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
662 if (ctx
->Extensions
.HaveTextureCubeMap
)
663 return ctx
->Texture
.ProxyCubeMap
->PosX
[level
];
667 gl_problem(ctx
, "bad target in _mesa_select_tex_image()");
674 /* Need this to prevent an out-of-bounds memory access when using
675 * X86 optimized code.
678 # define EXTRA_BYTE 1
680 # define EXTRA_BYTE 0
686 * Called by glTexImage[123]D. Fill in a texture image with data given
687 * by the client. All pixel transfer and unpack modes are handled here.
688 * NOTE: All texture image parameters should have already been error checked.
691 make_texture_image( GLcontext
*ctx
,
692 struct gl_texture_image
*texImage
,
693 GLenum srcFormat
, GLenum srcType
, const GLvoid
*pixels
,
694 const struct gl_pixelstore_attrib
*unpacking
)
696 GLint components
, numPixels
;
697 GLint internalFormat
, width
, height
, depth
, border
;
701 ASSERT(!texImage
->Data
);
705 internalFormat
= texImage
->IntFormat
;
706 width
= texImage
->Width
;
707 height
= texImage
->Height
;
708 depth
= texImage
->Depth
;
709 border
= texImage
->Border
;
710 components
= components_in_intformat(internalFormat
);
715 ASSERT(border
== 0 || border
== 1);
720 numPixels
= width
* height
* depth
;
722 texImage
->Data
= (GLubyte
*) MALLOC(numPixels
* components
+ EXTRA_BYTE
);
724 return; /* out of memory */
727 * OK, the texture image struct has been initialized and the texture
728 * image memory has been allocated.
729 * Now fill in the texture image from the source data.
730 * This includes applying the pixel transfer operations.
733 /* try common 2D texture cases first */
734 if (!ctx
->Pixel
.ScaleOrBiasRGBA
&& !ctx
->Pixel
.MapColorFlag
735 && !ctx
->Pixel
.IndexOffset
&& !ctx
->Pixel
.IndexShift
736 && srcType
== GL_UNSIGNED_BYTE
&& depth
== 1) {
738 if (srcFormat
== internalFormat
||
739 (srcFormat
== GL_LUMINANCE
&& internalFormat
== 1) ||
740 (srcFormat
== GL_LUMINANCE_ALPHA
&& internalFormat
== 2) ||
741 (srcFormat
== GL_RGB
&& internalFormat
== 3) ||
742 (srcFormat
== GL_RGBA
&& internalFormat
== 4)) {
743 /* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA,
744 * GL_LUMINANCE_ALPHA, etc. texture formats.
746 const GLubyte
*src
= (const GLubyte
*) _mesa_image_address(
747 unpacking
, pixels
, width
, height
, srcFormat
, srcType
, 0, 0, 0);
748 const GLint srcStride
= _mesa_image_row_stride(unpacking
, width
,
750 GLubyte
*dst
= texImage
->Data
;
751 GLint dstBytesPerRow
= width
* components
* sizeof(GLubyte
);
752 if (srcStride
== dstBytesPerRow
) {
753 MEMCPY(dst
, src
, height
* dstBytesPerRow
);
757 for (i
= 0; i
< height
; i
++) {
758 MEMCPY(dst
, src
, dstBytesPerRow
);
760 dst
+= dstBytesPerRow
;
763 return; /* all done */
765 else if (srcFormat
== GL_RGBA
&& internalFormat
== GL_RGB
) {
766 /* commonly used by Quake */
767 const GLubyte
*src
= (const GLubyte
*) _mesa_image_address(
768 unpacking
, pixels
, width
, height
, srcFormat
, srcType
, 0, 0, 0);
769 const GLint srcStride
= _mesa_image_row_stride(unpacking
, width
,
771 GLubyte
*dst
= texImage
->Data
;
773 for (i
= 0; i
< height
; i
++) {
774 const GLubyte
*s
= src
;
775 for (j
= 0; j
< width
; j
++) {
776 *dst
++ = *s
++; /*red*/
777 *dst
++ = *s
++; /*green*/
778 *dst
++ = *s
++; /*blue*/
783 return; /* all done */
789 * General case solutions
791 if (texImage
->Format
== GL_COLOR_INDEX
) {
792 /* color index texture */
793 const GLint destBytesPerRow
= width
* components
* sizeof(GLubyte
);
794 const GLenum dstType
= GL_UNSIGNED_BYTE
;
795 GLubyte
*dest
= texImage
->Data
;
797 for (img
= 0; img
< depth
; img
++) {
798 for (row
= 0; row
< height
; row
++) {
799 const GLvoid
*source
= _mesa_image_address(unpacking
,
800 pixels
, width
, height
, srcFormat
, srcType
, img
, row
, 0);
801 _mesa_unpack_index_span(ctx
, width
, dstType
, dest
,
802 srcType
, source
, unpacking
, GL_TRUE
);
803 dest
+= destBytesPerRow
;
808 /* regular, color texture */
809 const GLint destBytesPerRow
= width
* components
* sizeof(GLubyte
);
810 const GLenum dstFormat
= texImage
->Format
;
811 GLubyte
*dest
= texImage
->Data
;
813 for (img
= 0; img
< depth
; img
++) {
814 for (row
= 0; row
< height
; row
++) {
815 const GLvoid
*source
= _mesa_image_address(unpacking
,
816 pixels
, width
, height
, srcFormat
, srcType
, img
, row
, 0);
817 _mesa_unpack_ubyte_color_span(ctx
, width
, dstFormat
, dest
,
818 srcFormat
, srcType
, source
, unpacking
, GL_TRUE
);
819 dest
+= destBytesPerRow
;
828 * glTexImage[123]D can accept a NULL image pointer. In this case we
829 * create a texture image with unspecified image contents per the OpenGL
830 * spec. This function creates an empty image for the given texture image.
833 make_null_texture( struct gl_texture_image
*texImage
)
839 ASSERT(!texImage
->Data
);
841 components
= components_in_intformat(texImage
->IntFormat
);
842 numPixels
= texImage
->Width
* texImage
->Height
* texImage
->Depth
;
844 texImage
->Data
= (GLubyte
*) MALLOC( numPixels
* components
+ EXTRA_BYTE
);
847 * Let's see if anyone finds this. If glTexImage2D() is called with
848 * a NULL image pointer then load the texture image with something
849 * interesting instead of leaving it indeterminate.
851 if (texImage
->Data
) {
852 static const char message
[8][32] = {
856 " X X XXXX XXX XXXXX ",
859 " X X XXXXX XXX X X ",
863 GLubyte
*imgPtr
= texImage
->Data
;
865 for (i
= 0; i
< texImage
->Height
; i
++) {
866 GLint srcRow
= 7 - i
% 8;
867 for (j
= 0; j
< texImage
->Width
; j
++) {
868 GLint srcCol
= j
% 32;
869 GLint texel
= (message
[srcRow
][srcCol
]=='X') ? 255 : 70;
870 for (k
=0;k
<components
;k
++) {
871 *imgPtr
++ = (GLubyte
) texel
;
881 * Test glTexImage[123]D() parameters for errors.
883 * dimensions - must be 1 or 2 or 3
884 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
887 texture_error_check( GLcontext
*ctx
, GLenum target
,
888 GLint level
, GLint internalFormat
,
889 GLenum format
, GLenum type
,
891 GLint width
, GLint height
,
892 GLint depth
, GLint border
)
897 if (dimensions
== 1) {
898 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_1D
);
899 if (target
!= GL_TEXTURE_1D
&& !isProxy
) {
900 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
904 else if (dimensions
== 2) {
905 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_2D
);
906 if (target
!= GL_TEXTURE_2D
&& !isProxy
) {
907 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
911 else if (dimensions
== 3) {
912 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_3D
);
913 if (target
!= GL_TEXTURE_3D
&& !isProxy
) {
914 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
919 gl_problem( ctx
, "bad dims in texture_error_check" );
924 if (border
!= 0 && border
!= 1) {
927 sprintf(message
, "glTexImage%dD(border)", dimensions
);
928 gl_error(ctx
, GL_INVALID_VALUE
, message
);
934 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
935 || logbase2( width
- 2 * border
) < 0) {
938 sprintf(message
, "glTexImage%dD(width)", dimensions
);
939 gl_error(ctx
, GL_INVALID_VALUE
, message
);
945 if (dimensions
>= 2) {
946 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
947 || logbase2( height
- 2 * border
) < 0) {
950 sprintf(message
, "glTexImage%dD(height)", dimensions
);
951 gl_error(ctx
, GL_INVALID_VALUE
, message
);
958 if (dimensions
>= 3) {
959 if (depth
< 2 * border
|| depth
> 2 + ctx
->Const
.MaxTextureSize
960 || logbase2( depth
- 2 * border
) < 0) {
962 gl_error( ctx
, GL_INVALID_VALUE
, "glTexImage3D(depth)" );
969 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
972 sprintf(message
, "glTexImage%dD(level)", dimensions
);
973 gl_error(ctx
, GL_INVALID_VALUE
, message
);
978 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
982 sprintf(message
, "glTexImage%dD(internalFormat)", dimensions
);
983 gl_error(ctx
, GL_INVALID_VALUE
, message
);
988 if (!is_compressed_format(internalFormat
)) {
989 if (!_mesa_is_legal_format_and_type( format
, type
)) {
990 /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
991 * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
995 sprintf(message
, "glTexImage%dD(format or type)", dimensions
);
996 gl_error(ctx
, GL_INVALID_OPERATION
, message
);
1002 /* if we get here, the parameters are OK */
1009 * Test glTexSubImage[123]D() parameters for errors.
1011 * dimensions - must be 1 or 2 or 3
1012 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
1015 subtexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
1016 GLenum target
, GLint level
,
1017 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1018 GLint width
, GLint height
, GLint depth
,
1019 GLenum format
, GLenum type
)
1021 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1022 struct gl_texture_image
*destTex
;
1024 if (dimensions
== 1) {
1025 if (target
!= GL_TEXTURE_1D
) {
1026 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(target)" );
1030 else if (dimensions
== 2) {
1031 if (ctx
->Extensions
.HaveTextureCubeMap
) {
1032 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1033 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1034 target
!= GL_TEXTURE_2D
) {
1035 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
1039 else if (target
!= GL_TEXTURE_2D
) {
1040 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
1044 else if (dimensions
== 3) {
1045 if (target
!= GL_TEXTURE_3D
) {
1046 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3D(target)" );
1051 gl_problem( ctx
, "bad dims in texture_error_check" );
1055 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1056 gl_error(ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(level)");
1062 sprintf(message
, "glTexSubImage%dD(width)", dimensions
);
1063 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1066 if (height
< 0 && dimensions
> 1) {
1068 sprintf(message
, "glTexSubImage%dD(height)", dimensions
);
1069 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1072 if (depth
< 0 && dimensions
> 2) {
1074 sprintf(message
, "glTexSubImage%dD(depth)", dimensions
);
1075 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1079 destTex
= texUnit
->CurrentD
[2]->Image
[level
];
1081 gl_error(ctx
, GL_INVALID_OPERATION
, "glTexSubImage2D");
1085 if (xoffset
< -((GLint
)destTex
->Border
)) {
1086 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset)");
1089 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
1090 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset+width)");
1093 if (dimensions
> 1) {
1094 if (yoffset
< -((GLint
)destTex
->Border
)) {
1095 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset)");
1098 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
1099 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset+height)");
1103 if (dimensions
> 2) {
1104 if (zoffset
< -((GLint
)destTex
->Border
)) {
1105 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset)");
1108 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+destTex
->Border
)) {
1109 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset+depth)");
1114 if (!_mesa_is_legal_format_and_type(format
, type
)) {
1116 sprintf(message
, "glTexSubImage%dD(format or type)", dimensions
);
1117 gl_error(ctx
, GL_INVALID_ENUM
, message
);
1126 * Test glCopyTexImage[12]D() parameters for errors.
1127 * Input: dimensions - must be 1 or 2 or 3
1128 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
1131 copytexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
1132 GLenum target
, GLint level
, GLint internalFormat
,
1133 GLint width
, GLint height
, GLint border
)
1137 if (dimensions
== 1) {
1138 if (target
!= GL_TEXTURE_1D
) {
1139 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
1143 else if (dimensions
== 2) {
1144 if (ctx
->Extensions
.HaveTextureCubeMap
) {
1145 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1146 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1147 target
!= GL_TEXTURE_2D
) {
1148 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1152 else if (target
!= GL_TEXTURE_2D
) {
1153 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1159 if (border
!=0 && border
!=1) {
1161 sprintf(message
, "glCopyTexImage%dD(border)", dimensions
);
1162 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1167 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
1168 || logbase2( width
- 2 * border
) < 0) {
1170 sprintf(message
, "glCopyTexImage%dD(width)", dimensions
);
1171 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1176 if (dimensions
>= 2) {
1177 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
1178 || logbase2( height
- 2 * border
) < 0) {
1180 sprintf(message
, "glCopyTexImage%dD(height)", dimensions
);
1181 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1187 if (level
<0 || level
>=ctx
->Const
.MaxTextureLevels
) {
1189 sprintf(message
, "glCopyTexImage%dD(level)", dimensions
);
1190 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1194 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
1197 sprintf(message
, "glCopyTexImage%dD(internalFormat)", dimensions
);
1198 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1202 /* if we get here, the parameters are OK */
1208 copytexsubimage_error_check( GLcontext
*ctx
, GLuint dimensions
,
1209 GLenum target
, GLint level
,
1210 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1211 GLsizei width
, GLsizei height
)
1213 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1214 struct gl_texture_image
*teximage
;
1216 if (dimensions
== 1) {
1217 if (target
!= GL_TEXTURE_1D
) {
1218 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
1222 else if (dimensions
== 2) {
1223 if (ctx
->Extensions
.HaveTextureCubeMap
) {
1224 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1225 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1226 target
!= GL_TEXTURE_2D
) {
1227 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1231 else if (target
!= GL_TEXTURE_2D
) {
1232 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1236 else if (dimensions
== 3) {
1237 if (target
!= GL_TEXTURE_3D
) {
1238 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3D(target)" );
1243 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1245 sprintf(message
, "glCopyTexSubImage%dD(level)", dimensions
);
1246 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1252 sprintf(message
, "glCopyTexSubImage%dD(width)", dimensions
);
1253 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1256 if (dimensions
> 1 && height
< 0) {
1258 sprintf(message
, "glCopyTexSubImage%dD(height)", dimensions
);
1259 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1263 teximage
= texUnit
->CurrentD
[dimensions
]->Image
[level
];
1266 sprintf(message
, "glCopyTexSubImage%dD(undefined texture)", dimensions
);
1267 gl_error(ctx
, GL_INVALID_OPERATION
, message
);
1271 if (xoffset
< -((GLint
)teximage
->Border
)) {
1273 sprintf(message
, "glCopyTexSubImage%dD(xoffset)", dimensions
);
1274 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1277 if (xoffset
+width
> (GLint
) (teximage
->Width
+teximage
->Border
)) {
1279 sprintf(message
, "glCopyTexSubImage%dD(xoffset+width)", dimensions
);
1280 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1283 if (dimensions
> 1) {
1284 if (yoffset
< -((GLint
)teximage
->Border
)) {
1286 sprintf(message
, "glCopyTexSubImage%dD(yoffset)", dimensions
);
1287 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1290 /* NOTE: we're adding the border here, not subtracting! */
1291 if (yoffset
+height
> (GLint
) (teximage
->Height
+teximage
->Border
)) {
1293 sprintf(message
, "glCopyTexSubImage%dD(yoffset+height)", dimensions
);
1294 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1299 if (dimensions
> 2) {
1300 if (zoffset
< -((GLint
)teximage
->Border
)) {
1302 sprintf(message
, "glCopyTexSubImage%dD(zoffset)", dimensions
);
1303 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1306 if (zoffset
> (GLint
) (teximage
->Depth
+teximage
->Border
)) {
1308 sprintf(message
, "glCopyTexSubImage%dD(zoffset+depth)", dimensions
);
1309 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1314 /* if we get here, the parameters are OK */
1322 * Called from the API. Note that width includes the border.
1325 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
1326 GLsizei width
, GLint border
, GLenum format
,
1327 GLenum type
, const GLvoid
*pixels
)
1329 GET_CURRENT_CONTEXT(ctx
);
1330 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glTexImage1D");
1332 if (target
==GL_TEXTURE_1D
) {
1333 struct gl_texture_unit
*texUnit
;
1334 struct gl_texture_object
*texObj
;
1335 struct gl_texture_image
*texImage
;
1337 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1338 format
, type
, 1, width
, 1, 1, border
)) {
1339 return; /* error in texture image was detected */
1342 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1343 texObj
= texUnit
->CurrentD
[1];
1344 texImage
= texObj
->Image
[level
];
1347 texImage
= _mesa_alloc_texture_image();
1348 texObj
->Image
[level
] = texImage
;
1350 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
1354 else if (texImage
->Data
) {
1355 FREE(texImage
->Data
);
1356 texImage
->Data
= NULL
;
1359 /* setup the teximage struct's fields */
1360 init_texture_image(texImage
, width
, 1, 1, border
, internalFormat
);
1362 /* process the texture image */
1364 GLboolean retain
= GL_TRUE
;
1365 GLboolean success
= GL_FALSE
;
1366 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
1367 && ctx
->Driver
.TexImage1D
) {
1368 /* let device driver try to use raw image */
1369 success
= (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, format
,
1370 type
, pixels
, &ctx
->Unpack
,
1371 texObj
, texImage
, &retain
);
1373 if (retain
|| !success
) {
1374 /* make internal copy of the texture image */
1375 make_texture_image(ctx
, texImage
, format
, type
,
1376 pixels
, &ctx
->Unpack
);
1377 if (!success
&& ctx
->Driver
.TexImage1D
) {
1378 /* let device driver try to use unpacked image */
1379 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
1380 GL_UNSIGNED_BYTE
, texImage
->Data
,
1381 &_mesa_native_packing
,
1382 texObj
, texImage
, &retain
);
1385 if (!retain
&& texImage
->Data
) {
1386 FREE(texImage
->Data
);
1387 texImage
->Data
= NULL
;
1391 make_null_texture(texImage
);
1392 if (ctx
->Driver
.TexImage1D
) {
1394 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
1395 GL_UNSIGNED_BYTE
, texImage
->Data
,
1396 &_mesa_native_packing
,
1397 texObj
, texImage
, &retain
);
1402 gl_put_texobj_on_dirty_list( ctx
, texObj
);
1403 ctx
->NewState
|= NEW_TEXTURING
;
1405 else if (target
==GL_PROXY_TEXTURE_1D
) {
1406 /* Proxy texture: check for errors and update proxy state */
1407 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1408 format
, type
, 1, width
, 1, 1, border
)) {
1409 /* if error, clear all proxy texture image parameters */
1410 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1411 MEMSET( ctx
->Texture
.Proxy1D
->Image
[level
], 0,
1412 sizeof(struct gl_texture_image
) );
1416 /* if no error, update proxy texture image parameters */
1417 init_texture_image(ctx
->Texture
.Proxy1D
->Image
[level
],
1418 width
, 1, 1, border
, internalFormat
);
1422 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1429 _mesa_TexImage2D( GLenum target
, GLint level
, GLint internalFormat
,
1430 GLsizei width
, GLsizei height
, GLint border
,
1431 GLenum format
, GLenum type
,
1432 const GLvoid
*pixels
)
1434 GET_CURRENT_CONTEXT(ctx
);
1435 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glTexImage2D");
1437 if (target
==GL_TEXTURE_2D
||
1438 (ctx
->Extensions
.HaveTextureCubeMap
&&
1439 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1440 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
1441 struct gl_texture_unit
*texUnit
;
1442 struct gl_texture_object
*texObj
;
1443 struct gl_texture_image
*texImage
;
1445 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1446 format
, type
, 2, width
, height
, 1, border
)) {
1447 return; /* error in texture image was detected */
1450 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1451 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1452 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1455 texImage
= _mesa_alloc_texture_image();
1456 set_tex_image(texObj
, target
, level
, texImage
);
1457 /*texObj->Image[level] = texImage;*/
1459 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1463 else if (texImage
->Data
) {
1464 FREE(texImage
->Data
);
1465 texImage
->Data
= NULL
;
1468 /* setup the teximage struct's fields */
1469 init_texture_image(texImage
, width
, height
, 1, border
, internalFormat
);
1471 /* process the texture image */
1473 GLboolean retain
= GL_TRUE
;
1474 GLboolean success
= GL_FALSE
;
1475 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
1476 && ctx
->Driver
.TexImage2D
) {
1477 /* let device driver try to use raw image */
1478 success
= (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, format
,
1479 type
, pixels
, &ctx
->Unpack
,
1480 texObj
, texImage
, &retain
);
1482 if (retain
|| !success
) {
1483 /* make internal copy of the texture image */
1484 make_texture_image(ctx
, texImage
, format
, type
,
1485 pixels
, &ctx
->Unpack
);
1486 if (!success
&& ctx
->Driver
.TexImage2D
) {
1487 /* let device driver try to use unpacked image */
1488 (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, texImage
->Format
,
1489 GL_UNSIGNED_BYTE
, texImage
->Data
,
1490 &_mesa_native_packing
,
1491 texObj
, texImage
, &retain
);
1494 if (!retain
&& texImage
->Data
) {
1495 FREE(texImage
->Data
);
1496 texImage
->Data
= NULL
;
1500 make_null_texture(texImage
);
1501 if (ctx
->Driver
.TexImage2D
) {
1503 (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, texImage
->Format
,
1504 GL_UNSIGNED_BYTE
, texImage
->Data
,
1505 &_mesa_native_packing
,
1506 texObj
, texImage
, &retain
);
1510 #define OLD_DD_TEXTURE
1511 #ifdef OLD_DD_TEXTURE
1512 /* XXX this will be removed in the future */
1513 if (ctx
->Driver
.TexImage
) {
1514 (*ctx
->Driver
.TexImage
)( ctx
, target
, texObj
, level
, internalFormat
,
1520 gl_put_texobj_on_dirty_list( ctx
, texObj
);
1521 ctx
->NewState
|= NEW_TEXTURING
;
1523 else if (target
==GL_PROXY_TEXTURE_2D
) {
1524 /* Proxy texture: check for errors and update proxy state */
1525 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1526 format
, type
, 2, width
, height
, 1, border
)) {
1527 /* if error, clear all proxy texture image parameters */
1528 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1529 MEMSET( ctx
->Texture
.Proxy2D
->Image
[level
], 0,
1530 sizeof(struct gl_texture_image
) );
1534 /* if no error, update proxy texture image parameters */
1535 init_texture_image(ctx
->Texture
.Proxy1D
->Image
[level
],
1536 width
, height
, 1, border
, internalFormat
);
1540 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1548 * Called by the API or display list executor.
1549 * Note that width and height include the border.
1552 _mesa_TexImage3D( GLenum target
, GLint level
, GLint internalFormat
,
1553 GLsizei width
, GLsizei height
, GLsizei depth
,
1554 GLint border
, GLenum format
, GLenum type
,
1555 const GLvoid
*pixels
)
1557 GET_CURRENT_CONTEXT(ctx
);
1558 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glTexImage3D");
1560 if (target
==GL_TEXTURE_3D_EXT
) {
1561 struct gl_texture_unit
*texUnit
;
1562 struct gl_texture_object
*texObj
;
1563 struct gl_texture_image
*texImage
;
1564 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1565 format
, type
, 3, width
, height
, depth
, border
)) {
1566 return; /* error in texture image was detected */
1569 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1570 texObj
= texUnit
->CurrentD
[3];
1571 texImage
= texObj
->Image
[level
];
1574 texImage
= _mesa_alloc_texture_image();
1575 texObj
->Image
[level
] = texImage
;
1577 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
1581 else if (texImage
->Data
) {
1582 FREE(texImage
->Data
);
1583 texImage
->Data
= NULL
;
1586 /* setup the teximage struct's fields */
1587 init_texture_image(texImage
, width
, height
, depth
,
1588 border
, internalFormat
);
1590 /* process the texture image */
1592 GLboolean retain
= GL_TRUE
;
1593 GLboolean success
= GL_FALSE
;
1594 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
1595 && ctx
->Driver
.TexImage3D
) {
1596 /* let device driver try to use raw image */
1597 success
= (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, format
,
1598 type
, pixels
, &ctx
->Unpack
,
1599 texObj
, texImage
, &retain
);
1601 if (retain
|| !success
) {
1602 /* make internal copy of the texture image */
1603 make_texture_image(ctx
, texImage
, format
, type
,
1604 pixels
, &ctx
->Unpack
);
1605 if (!success
&& ctx
->Driver
.TexImage3D
) {
1606 /* let device driver try to use unpacked image */
1607 (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, texImage
->Format
,
1608 GL_UNSIGNED_BYTE
, texImage
->Data
,
1609 &_mesa_native_packing
,
1610 texObj
, texImage
, &retain
);
1613 if (!retain
&& texImage
->Data
) {
1614 FREE(texImage
->Data
);
1615 texImage
->Data
= NULL
;
1619 make_null_texture(texImage
);
1620 if (ctx
->Driver
.TexImage3D
) {
1622 (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, texImage
->Format
,
1623 GL_UNSIGNED_BYTE
, texImage
->Data
,
1624 &_mesa_native_packing
,
1625 texObj
, texImage
, &retain
);
1630 gl_put_texobj_on_dirty_list( ctx
, texObj
);
1631 ctx
->NewState
|= NEW_TEXTURING
;
1633 else if (target
==GL_PROXY_TEXTURE_3D
) {
1634 /* Proxy texture: check for errors and update proxy state */
1635 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1636 format
, type
, 3, width
, height
, depth
, border
)) {
1637 /* if error, clear all proxy texture image parameters */
1638 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1639 MEMSET( ctx
->Texture
.Proxy3D
->Image
[level
], 0,
1640 sizeof(struct gl_texture_image
) );
1644 /* if no error, update proxy texture image parameters */
1645 init_texture_image(ctx
->Texture
.Proxy1D
->Image
[level
],
1646 width
, height
, depth
, border
, internalFormat
);
1650 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1657 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
1658 GLsizei width
, GLsizei height
, GLsizei depth
,
1659 GLint border
, GLenum format
, GLenum type
,
1660 const GLvoid
*pixels
)
1662 _mesa_TexImage3D(target
, level
, (GLint
) internalFormat
, width
, height
,
1663 depth
, border
, format
, type
, pixels
);
1668 * Fetch a texture image from the device driver.
1669 * Store the results in the given texture object at the given mipmap level.
1672 _mesa_get_teximage_from_driver( GLcontext
*ctx
, GLenum target
, GLint level
,
1673 const struct gl_texture_object
*texObj
)
1676 GLenum imgFormat
, imgType
;
1677 GLboolean freeImage
;
1678 struct gl_texture_image
*texImage
;
1679 GLint destComponents
, numPixels
, srcBytesPerTexel
;
1681 if (!ctx
->Driver
.GetTexImage
)
1684 image
= (*ctx
->Driver
.GetTexImage
)( ctx
, target
, level
, texObj
,
1685 &imgFormat
, &imgType
, &freeImage
);
1689 texImage
= texObj
->Image
[level
];
1694 destComponents
= components_in_intformat(texImage
->Format
);
1695 assert(destComponents
> 0);
1696 numPixels
= texImage
->Width
* texImage
->Height
* texImage
->Depth
;
1697 assert(numPixels
> 0);
1698 srcBytesPerTexel
= _mesa_bytes_per_pixel(imgFormat
, imgType
);
1699 assert(srcBytesPerTexel
> 0);
1701 if (!texImage
->Data
) {
1702 /* Allocate memory for the texture image data */
1703 texImage
->Data
= (GLubyte
*) MALLOC(numPixels
* destComponents
+ EXTRA_BYTE
);
1706 if (imgFormat
== texImage
->Format
&& imgType
== GL_UNSIGNED_BYTE
) {
1707 /* We got lucky! The driver's format and type match Mesa's format. */
1708 if (texImage
->Data
) {
1709 MEMCPY(texImage
->Data
, image
, numPixels
* destComponents
);
1713 /* Convert the texture image from the driver's format to Mesa's
1716 const GLint width
= texImage
->Width
;
1717 const GLint height
= texImage
->Height
;
1718 const GLint depth
= texImage
->Depth
;
1719 const GLint destBytesPerRow
= width
* destComponents
* sizeof(GLchan
);
1720 const GLint srcBytesPerRow
= width
* srcBytesPerTexel
;
1721 const GLenum dstType
= GL_UNSIGNED_BYTE
;
1722 const GLenum dstFormat
= texImage
->Format
;
1723 const GLubyte
*srcPtr
= (const GLubyte
*) image
;
1724 GLubyte
*destPtr
= texImage
->Data
;
1726 if (texImage
->Format
== GL_COLOR_INDEX
) {
1727 /* color index texture */
1729 assert(imgFormat
== GL_COLOR_INDEX
);
1730 for (img
= 0; img
< depth
; img
++) {
1731 for (row
= 0; row
< height
; row
++) {
1732 _mesa_unpack_index_span(ctx
, width
, dstType
, destPtr
,
1733 imgType
, srcPtr
, &_mesa_native_packing
, GL_FALSE
);
1734 destPtr
+= destBytesPerRow
;
1735 srcPtr
+= srcBytesPerRow
;
1742 for (img
= 0; img
< depth
; img
++) {
1743 for (row
= 0; row
< height
; row
++) {
1744 _mesa_unpack_ubyte_color_span(ctx
, width
, dstFormat
, destPtr
,
1745 imgFormat
, imgType
, srcPtr
, &_mesa_native_packing
, GL_FALSE
);
1746 destPtr
+= destBytesPerRow
;
1747 srcPtr
+= srcBytesPerRow
;
1759 _mesa_GetTexImage( GLenum target
, GLint level
, GLenum format
,
1760 GLenum type
, GLvoid
*pixels
)
1762 GET_CURRENT_CONTEXT(ctx
);
1763 const struct gl_texture_object
*texObj
;
1764 struct gl_texture_image
*texImage
;
1765 GLboolean discardImage
;
1767 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetTexImage");
1769 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1770 gl_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
1774 if (_mesa_sizeof_type(type
) <= 0) {
1775 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
1779 if (_mesa_components_in_format(format
) <= 0) {
1780 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
1789 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[1];
1792 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[2];
1795 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[3];
1798 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)" );
1802 texImage
= texObj
->Image
[level
];
1804 /* invalid mipmap level */
1808 if (!texImage
->Data
) {
1809 /* try to get the texture image from the device driver */
1810 _mesa_get_teximage_from_driver(ctx
, target
, level
, texObj
);
1811 discardImage
= GL_TRUE
;
1814 discardImage
= GL_FALSE
;
1817 if (texImage
->Data
) {
1818 GLint width
= texImage
->Width
;
1819 GLint height
= texImage
->Height
;
1822 for (row
= 0; row
< height
; row
++) {
1823 /* compute destination address in client memory */
1824 GLvoid
*dest
= _mesa_image_address( &ctx
->Unpack
, pixels
,
1826 format
, type
, 0, row
, 0);
1829 if (texImage
->Format
== GL_RGBA
) {
1830 const GLubyte
*src
= texImage
->Data
+ row
* width
* 4 * sizeof(GLubyte
);
1831 _mesa_pack_rgba_span( ctx
, width
, (CONST
GLubyte (*)[4]) src
,
1832 format
, type
, dest
, &ctx
->Pack
, GL_TRUE
);
1835 /* fetch RGBA row from texture image then pack it in client mem */
1836 GLubyte rgba
[MAX_WIDTH
][4];
1839 switch (texImage
->Format
) {
1841 src
= texImage
->Data
+ row
* width
* sizeof(GLubyte
);
1842 for (i
= 0; i
< width
; i
++) {
1843 rgba
[i
][RCOMP
] = 255;
1844 rgba
[i
][GCOMP
] = 255;
1845 rgba
[i
][BCOMP
] = 255;
1846 rgba
[i
][ACOMP
] = src
[i
];
1850 src
= texImage
->Data
+ row
* width
* sizeof(GLubyte
);
1851 for (i
= 0; i
< width
; i
++) {
1852 rgba
[i
][RCOMP
] = src
[i
];
1853 rgba
[i
][GCOMP
] = src
[i
];
1854 rgba
[i
][BCOMP
] = src
[i
];
1855 rgba
[i
][ACOMP
] = 255;
1858 case GL_LUMINANCE_ALPHA
:
1859 src
= texImage
->Data
+ row
* 2 * width
* sizeof(GLubyte
);
1860 for (i
= 0; i
< width
; i
++) {
1861 rgba
[i
][RCOMP
] = src
[i
*2+0];
1862 rgba
[i
][GCOMP
] = src
[i
*2+0];
1863 rgba
[i
][BCOMP
] = src
[i
*2+0];
1864 rgba
[i
][ACOMP
] = src
[i
*2+1];
1868 src
= texImage
->Data
+ row
* width
* sizeof(GLubyte
);
1869 for (i
= 0; i
< width
; i
++) {
1870 rgba
[i
][RCOMP
] = src
[i
];
1871 rgba
[i
][GCOMP
] = src
[i
];
1872 rgba
[i
][BCOMP
] = src
[i
];
1873 rgba
[i
][ACOMP
] = 255;
1877 src
= texImage
->Data
+ row
* 3 * width
* sizeof(GLubyte
);
1878 for (i
= 0; i
< width
; i
++) {
1879 rgba
[i
][RCOMP
] = src
[i
*3+0];
1880 rgba
[i
][GCOMP
] = src
[i
*3+1];
1881 rgba
[i
][BCOMP
] = src
[i
*3+2];
1882 rgba
[i
][ACOMP
] = 255;
1886 /* this special case should have been handled above! */
1887 gl_problem( ctx
, "error 1 in gl_GetTexImage" );
1889 case GL_COLOR_INDEX
:
1890 gl_problem( ctx
, "GL_COLOR_INDEX not implemented in gl_GetTexImage" );
1893 gl_problem( ctx
, "bad format in gl_GetTexImage" );
1895 _mesa_pack_rgba_span( ctx
, width
, (const GLubyte (*)[4])rgba
,
1896 format
, type
, dest
, &ctx
->Pack
, GL_TRUE
);
1900 /* if we got the teximage from the device driver we'll discard it now */
1902 FREE(texImage
->Data
);
1903 texImage
->Data
= NULL
;
1911 _mesa_TexSubImage1D( GLenum target
, GLint level
,
1912 GLint xoffset
, GLsizei width
,
1913 GLenum format
, GLenum type
,
1914 const GLvoid
*pixels
)
1916 GET_CURRENT_CONTEXT(ctx
);
1917 struct gl_texture_unit
*texUnit
;
1918 struct gl_texture_object
*texObj
;
1919 struct gl_texture_image
*texImage
;
1920 GLboolean success
= GL_FALSE
;
1922 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
1923 width
, 1, 1, format
, type
)) {
1924 return; /* error was detected */
1927 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1928 texObj
= texUnit
->CurrentD
[1];
1929 texImage
= texObj
->Image
[level
];
1932 if (width
== 0 || !pixels
)
1933 return; /* no-op, not an error */
1936 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
1937 && ctx
->Driver
.TexSubImage1D
) {
1938 success
= (*ctx
->Driver
.TexSubImage1D
)( ctx
, target
, level
, xoffset
,
1939 width
, format
, type
, pixels
,
1940 &ctx
->Unpack
, texObj
, texImage
);
1943 /* XXX if Driver.TexSubImage1D, unpack image and try again? */
1945 const GLint texComponents
= components_in_intformat(texImage
->Format
);
1946 const GLenum texFormat
= texImage
->Format
;
1947 const GLint xoffsetb
= xoffset
+ texImage
->Border
;
1948 GLboolean retain
= GL_TRUE
;
1949 if (!texImage
->Data
) {
1950 _mesa_get_teximage_from_driver( ctx
, target
, level
, texObj
);
1951 if (!texImage
->Data
) {
1952 make_null_texture(texImage
);
1954 if (!texImage
->Data
)
1955 return; /* we're really out of luck! */
1958 if (texFormat
== GL_COLOR_INDEX
) {
1959 /* color index texture */
1960 GLubyte
*dst
= texImage
->Data
+ xoffsetb
* texComponents
;
1961 const GLvoid
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
, width
,
1962 1, format
, type
, 0, 0, 0);
1963 _mesa_unpack_index_span(ctx
, width
, GL_UNSIGNED_BYTE
, dst
,
1964 type
, src
, &ctx
->Unpack
, GL_TRUE
);
1968 GLubyte
*dst
= texImage
->Data
+ xoffsetb
* texComponents
;
1969 const GLvoid
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
, width
,
1970 1, format
, type
, 0, 0, 0);
1971 _mesa_unpack_ubyte_color_span(ctx
, width
, texFormat
, dst
, format
,
1972 type
, src
, &ctx
->Unpack
, GL_TRUE
);
1975 if (ctx
->Driver
.TexImage1D
) {
1976 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
1977 GL_UNSIGNED_BYTE
, texImage
->Data
,
1978 &_mesa_native_packing
, texObj
, texImage
,
1982 if (!retain
&& texImage
->Data
) {
1983 FREE(texImage
->Data
);
1984 texImage
->Data
= NULL
;
1988 /*gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[1] );*/
1993 _mesa_TexSubImage2D( GLenum target
, GLint level
,
1994 GLint xoffset
, GLint yoffset
,
1995 GLsizei width
, GLsizei height
,
1996 GLenum format
, GLenum type
,
1997 const GLvoid
*pixels
)
1999 GET_CURRENT_CONTEXT(ctx
);
2000 struct gl_texture_unit
*texUnit
;
2001 struct gl_texture_object
*texObj
;
2002 struct gl_texture_image
*texImage
;
2003 GLboolean success
= GL_FALSE
;
2005 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2006 width
, height
, 1, format
, type
)) {
2007 return; /* error was detected */
2010 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2011 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2012 texImage
= texObj
->Image
[level
];
2015 if (width
== 0 || height
== 0 || !pixels
)
2016 return; /* no-op, not an error */
2018 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
2019 && ctx
->Driver
.TexSubImage2D
) {
2020 success
= (*ctx
->Driver
.TexSubImage2D
)( ctx
, target
, level
, xoffset
,
2021 yoffset
, width
, height
, format
, type
,
2022 pixels
, &ctx
->Unpack
, texObj
, texImage
);
2025 /* XXX if Driver.TexSubImage2D, unpack image and try again? */
2027 const GLint texComponents
= components_in_intformat(texImage
->Format
);
2028 const GLenum texFormat
= texImage
->Format
;
2029 const GLint xoffsetb
= xoffset
+ texImage
->Border
;
2030 const GLint yoffsetb
= yoffset
+ texImage
->Border
;
2031 const GLint srcStride
= _mesa_image_row_stride(&ctx
->Unpack
, width
,
2033 const GLint dstStride
= texImage
->Width
* texComponents
*sizeof(GLubyte
);
2034 GLboolean retain
= GL_TRUE
;
2036 if (!texImage
->Data
) {
2037 _mesa_get_teximage_from_driver( ctx
, target
, level
, texObj
);
2038 if (!texImage
->Data
) {
2039 make_null_texture(texImage
);
2041 if (!texImage
->Data
)
2042 return; /* we're really out of luck! */
2045 if (texFormat
== GL_COLOR_INDEX
) {
2046 /* color index texture */
2047 GLubyte
*dst
= texImage
->Data
2048 + (yoffsetb
* texImage
->Width
+ xoffsetb
) * texComponents
;
2049 const GLubyte
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
,
2050 width
, height
, format
, type
, 0, 0, 0);
2052 for (row
= 0; row
< height
; row
++) {
2053 _mesa_unpack_index_span(ctx
, width
, GL_UNSIGNED_BYTE
, dst
, type
,
2054 (const GLvoid
*) src
, &ctx
->Unpack
, GL_TRUE
);
2061 GLubyte
*dst
= texImage
->Data
2062 + (yoffsetb
* texImage
->Width
+ xoffsetb
) * texComponents
;
2063 const GLubyte
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
,
2064 width
, height
, format
, type
, 0, 0, 0);
2066 for (row
= 0; row
< height
; row
++) {
2067 _mesa_unpack_ubyte_color_span(ctx
, width
, texFormat
, dst
, format
,
2068 type
, (const GLvoid
*) src
, &ctx
->Unpack
, GL_TRUE
);
2074 if (ctx
->Driver
.TexImage2D
) {
2075 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, texImage
->Format
,
2076 GL_UNSIGNED_BYTE
, texImage
->Data
,
2077 &_mesa_native_packing
, texObj
, texImage
,
2081 if (!retain
&& texImage
->Data
) {
2082 FREE(texImage
->Data
);
2083 texImage
->Data
= NULL
;
2086 #ifdef OLD_DD_TEXTURE
2087 /* XXX this will be removed in the future */
2088 if (ctx
->Driver
.TexSubImage
) {
2089 (*ctx
->Driver
.TexSubImage
)(ctx
, target
, texObj
, level
,
2090 xoffset
, yoffset
, width
, height
,
2091 texImage
->IntFormat
, texImage
);
2093 else if (ctx
->Driver
.TexImage
) {
2094 (*ctx
->Driver
.TexImage
)(ctx
, GL_TEXTURE_2D
, texObj
,
2095 level
, texImage
->IntFormat
, texImage
);
2104 _mesa_TexSubImage3D( GLenum target
, GLint level
,
2105 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2106 GLsizei width
, GLsizei height
, GLsizei depth
,
2107 GLenum format
, GLenum type
,
2108 const GLvoid
*pixels
)
2110 GET_CURRENT_CONTEXT(ctx
);
2111 struct gl_texture_unit
*texUnit
;
2112 struct gl_texture_object
*texObj
;
2113 struct gl_texture_image
*texImage
;
2114 GLboolean success
= GL_FALSE
;
2116 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2117 width
, height
, depth
, format
, type
)) {
2118 return; /* error was detected */
2121 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2122 texObj
= texUnit
->CurrentD
[3];
2123 texImage
= texObj
->Image
[level
];
2126 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
2127 return; /* no-op, not an error */
2129 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
2130 && ctx
->Driver
.TexSubImage3D
) {
2131 success
= (*ctx
->Driver
.TexSubImage3D
)( ctx
, target
, level
, xoffset
,
2132 yoffset
, zoffset
, width
, height
, depth
, format
,
2133 type
, pixels
, &ctx
->Unpack
, texObj
, texImage
);
2136 /* XXX if Driver.TexSubImage3D, unpack image and try again? */
2138 const GLint texComponents
= components_in_intformat(texImage
->Format
);
2139 const GLenum texFormat
= texImage
->Format
;
2140 const GLint xoffsetb
= xoffset
+ texImage
->Border
;
2141 const GLint yoffsetb
= yoffset
+ texImage
->Border
;
2142 const GLint zoffsetb
= zoffset
+ texImage
->Border
;
2143 const GLint texWidth
= texImage
->Width
;
2144 const GLint dstRectArea
= texWidth
* texImage
->Height
;
2145 const GLint srcStride
= _mesa_image_row_stride(&ctx
->Unpack
,
2146 width
, format
, type
);
2147 const GLint dstStride
= texWidth
* texComponents
* sizeof(GLubyte
);
2148 GLboolean retain
= GL_TRUE
;
2150 if (texFormat
== GL_COLOR_INDEX
) {
2151 /* color index texture */
2153 for (img
= 0; img
< depth
; img
++) {
2154 const GLubyte
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
,
2155 width
, height
, format
, type
, img
, 0, 0);
2156 GLubyte
*dst
= texImage
->Data
+ ((zoffsetb
+ img
) * dstRectArea
2157 + yoffsetb
* texWidth
+ xoffsetb
) * texComponents
;
2158 for (row
= 0; row
< height
; row
++) {
2159 _mesa_unpack_index_span(ctx
, width
, GL_UNSIGNED_BYTE
, dst
,
2160 type
, (const GLvoid
*) src
, &ctx
->Unpack
, GL_TRUE
);
2169 for (img
= 0; img
< depth
; img
++) {
2170 const GLubyte
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
,
2171 width
, height
, format
, type
, img
, 0, 0);
2172 GLubyte
*dst
= texImage
->Data
+ ((zoffsetb
+ img
) * dstRectArea
2173 + yoffsetb
* texWidth
+ xoffsetb
) * texComponents
;
2174 for (row
= 0; row
< height
; row
++) {
2175 _mesa_unpack_ubyte_color_span(ctx
, width
, texFormat
, dst
,
2176 format
, type
, (const GLvoid
*) src
, &ctx
->Unpack
, GL_TRUE
);
2183 if (ctx
->Driver
.TexImage3D
) {
2184 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, texImage
->Format
,
2185 GL_UNSIGNED_BYTE
, texImage
->Data
,
2186 &_mesa_native_packing
, texObj
, texImage
,
2190 if (!retain
&& texImage
->Data
) {
2191 FREE(texImage
->Data
);
2192 texImage
->Data
= NULL
;
2200 * Read an RGBA image from the frame buffer.
2201 * This is used by glCopyTexSubImage[12]D().
2202 * Input: ctx - the context
2203 * x, y - lower left corner
2204 * width, height - size of region to read
2205 * Return: pointer to block of GL_RGBA, GLubyte data.
2208 read_color_image( GLcontext
*ctx
, GLint x
, GLint y
,
2209 GLsizei width
, GLsizei height
)
2212 GLubyte
*image
, *dst
;
2214 image
= (GLubyte
*) MALLOC(width
* height
* 4 * sizeof(GLubyte
));
2218 /* Select buffer to read from */
2219 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->ReadBuffer
,
2220 ctx
->Pixel
.DriverReadBuffer
);
2223 stride
= width
* 4 * sizeof(GLubyte
);
2224 for (i
= 0; i
< height
; i
++) {
2225 gl_read_rgba_span( ctx
, ctx
->ReadBuffer
, width
, x
, y
+ i
,
2226 (GLubyte (*)[4]) dst
);
2230 /* Read from draw buffer (the default) */
2231 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->DrawBuffer
,
2232 ctx
->Color
.DriverDrawBuffer
);
2240 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
2241 GLenum internalFormat
,
2243 GLsizei width
, GLint border
)
2245 GET_CURRENT_CONTEXT(ctx
);
2246 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexImage1D");
2248 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
2252 if (ctx
->Pixel
.MapColorFlag
|| ctx
->Pixel
.ScaleOrBiasRGBA
2253 || !ctx
->Driver
.CopyTexImage1D
2254 || !(*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
,
2255 internalFormat
, x
, y
, width
, border
))
2257 GLubyte
*image
= read_color_image( ctx
, x
, y
, width
, 1 );
2259 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D" );
2262 (*ctx
->Exec
->TexImage1D
)( target
, level
, internalFormat
, width
,
2263 border
, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2271 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
2272 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
2275 GET_CURRENT_CONTEXT(ctx
);
2276 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexImage2D");
2278 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
2279 width
, height
, border
))
2282 if (ctx
->Pixel
.MapColorFlag
|| ctx
->Pixel
.ScaleOrBiasRGBA
2283 || !ctx
->Driver
.CopyTexImage2D
2284 || !(*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
,
2285 internalFormat
, x
, y
, width
, height
, border
))
2287 GLubyte
*image
= read_color_image( ctx
, x
, y
, width
, height
);
2289 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D" );
2292 (ctx
->Exec
->TexImage2D
)( target
, level
, internalFormat
, width
,
2293 height
, border
, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2301 * Do the work of glCopyTexSubImage[123]D.
2304 copy_tex_sub_image( GLcontext
*ctx
, struct gl_texture_image
*dest
,
2305 GLint width
, GLint height
,
2306 GLint srcx
, GLint srcy
,
2307 GLint dstx
, GLint dsty
, GLint dstz
)
2310 GLint format
, components
, rectarea
;
2311 GLint texwidth
, texheight
, zoffset
;
2313 /* dst[xyz] may be negative if we have a texture border! */
2314 dstx
+= dest
->Border
;
2315 dsty
+= dest
->Border
;
2316 dstz
+= dest
->Border
;
2317 texwidth
= dest
->Width
;
2318 texheight
= dest
->Height
;
2319 rectarea
= texwidth
* texheight
;
2320 zoffset
= dstz
* rectarea
;
2321 format
= dest
->Format
;
2322 components
= components_in_intformat( format
);
2324 /* Select buffer to read from */
2325 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->ReadBuffer
,
2326 ctx
->Pixel
.DriverReadBuffer
);
2328 for (i
= 0;i
< height
; i
++) {
2329 GLubyte rgba
[MAX_WIDTH
][4];
2331 gl_read_rgba_span( ctx
, ctx
->ReadBuffer
, width
, srcx
, srcy
+ i
, rgba
);
2332 dst
= dest
->Data
+ ( zoffset
+ (dsty
+i
) * texwidth
+ dstx
) * components
;
2333 _mesa_unpack_ubyte_color_span(ctx
, width
, format
, dst
,
2334 GL_RGBA
, GL_UNSIGNED_BYTE
, rgba
,
2335 &_mesa_native_packing
, GL_TRUE
);
2338 /* Read from draw buffer (the default) */
2339 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->DrawBuffer
,
2340 ctx
->Color
.DriverDrawBuffer
);
2347 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
2348 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
2350 GET_CURRENT_CONTEXT(ctx
);
2351 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexSubImage1D");
2353 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
2354 xoffset
, 0, 0, width
, 1))
2357 if (ctx
->Pixel
.MapColorFlag
|| ctx
->Pixel
.ScaleOrBiasRGBA
2358 || !ctx
->Driver
.CopyTexSubImage1D
2359 || !(*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
,
2360 xoffset
, x
, y
, width
)) {
2361 struct gl_texture_unit
*texUnit
;
2362 struct gl_texture_image
*teximage
;
2363 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2364 teximage
= texUnit
->CurrentD
[1]->Image
[level
];
2366 if (teximage
->Data
) {
2367 copy_tex_sub_image(ctx
, teximage
, width
, 1, x
, y
, xoffset
, 0, 0);
2368 /* tell driver about the change */
2369 /* XXX this is obsolete */
2370 if (ctx
->Driver
.TexImage
) {
2371 (*ctx
->Driver
.TexImage
)( ctx
, GL_TEXTURE_1D
,
2372 texUnit
->CurrentD
[1],
2373 level
, teximage
->IntFormat
, teximage
);
2382 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
2383 GLint xoffset
, GLint yoffset
,
2384 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2386 GET_CURRENT_CONTEXT(ctx
);
2387 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexSubImage2D");
2389 if (copytexsubimage_error_check(ctx
, 2, target
, level
,
2390 xoffset
, yoffset
, 0, width
, height
))
2393 if (ctx
->Pixel
.MapColorFlag
|| ctx
->Pixel
.ScaleOrBiasRGBA
2394 || !ctx
->Driver
.CopyTexSubImage2D
2395 || !(*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
2396 xoffset
, yoffset
, x
, y
, width
, height
)) {
2397 struct gl_texture_unit
*texUnit
;
2398 struct gl_texture_image
*teximage
;
2399 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2400 teximage
= texUnit
->CurrentD
[2]->Image
[level
];
2402 if (teximage
->Data
) {
2403 copy_tex_sub_image(ctx
, teximage
, width
, height
,
2404 x
, y
, xoffset
, yoffset
, 0);
2405 /* tell driver about the change */
2406 /* XXX this is obsolete */
2407 if (ctx
->Driver
.TexImage
) {
2408 (*ctx
->Driver
.TexImage
)( ctx
, GL_TEXTURE_2D
,
2409 texUnit
->CurrentD
[2],
2410 level
, teximage
->IntFormat
, teximage
);
2419 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
2420 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2421 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2423 GET_CURRENT_CONTEXT(ctx
);
2424 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexSubImage3D");
2426 if (copytexsubimage_error_check(ctx
, 3, target
, level
,
2427 xoffset
, yoffset
, zoffset
, width
, height
))
2430 if (ctx
->Pixel
.MapColorFlag
|| ctx
->Pixel
.ScaleOrBiasRGBA
2431 || !ctx
->Driver
.CopyTexSubImage3D
2432 || !(*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
2433 xoffset
, yoffset
, zoffset
, x
, y
, width
, height
)) {
2434 struct gl_texture_unit
*texUnit
;
2435 struct gl_texture_image
*teximage
;
2436 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2437 teximage
= texUnit
->CurrentD
[3]->Image
[level
];
2439 if (teximage
->Data
) {
2440 copy_tex_sub_image(ctx
, teximage
, width
, height
,
2441 x
, y
, xoffset
, yoffset
, zoffset
);
2442 /* tell driver about the change */
2443 /* XXX this is obsolete */
2444 if (ctx
->Driver
.TexImage
) {
2445 (*ctx
->Driver
.TexImage
)( ctx
, GL_TEXTURE_3D
,
2446 texUnit
->CurrentD
[3],
2447 level
, teximage
->IntFormat
, teximage
);
2456 _mesa_CompressedTexImage1DARB(GLenum target
, GLint level
,
2457 GLenum internalFormat
, GLsizei width
,
2458 GLint border
, GLsizei imageSize
,
2461 GET_CURRENT_CONTEXT(ctx
);
2462 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCompressedTexImage1DARB");
2464 if (target
== GL_TEXTURE_1D
) {
2465 struct gl_texture_unit
*texUnit
;
2466 struct gl_texture_object
*texObj
;
2467 struct gl_texture_image
*texImage
;
2469 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2470 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
2471 return; /* error in texture image was detected */
2474 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2475 texObj
= texUnit
->CurrentD
[1];
2476 texImage
= texObj
->Image
[level
];
2479 texImage
= _mesa_alloc_texture_image();
2480 texObj
->Image
[level
] = texImage
;
2482 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage1DARB");
2486 else if (texImage
->Data
) {
2487 FREE(texImage
->Data
);
2488 texImage
->Data
= NULL
;
2491 /* setup the teximage struct's fields */
2492 init_texture_image(texImage
, width
, 1, 1, border
, internalFormat
);
2494 /* process the texture image */
2496 GLboolean retain
= GL_TRUE
;
2497 GLboolean success
= GL_FALSE
;
2498 if (ctx
->Driver
.CompressedTexImage1D
) {
2499 success
= (*ctx
->Driver
.CompressedTexImage1D
)( ctx
, target
, level
,
2500 data
, texObj
, texImage
, &retain
);
2502 if (retain
|| !success
) {
2503 /* make internal copy of the texture image */
2504 GLuint imageSize
= _mesa_compressed_image_size(internalFormat
,
2506 texImage
->Data
= MALLOC(imageSize
);
2507 if (texImage
->Data
) {
2508 MEMCPY(texImage
->Data
, data
, imageSize
);
2511 if (!retain
&& texImage
->Data
) {
2512 FREE(texImage
->Data
);
2513 texImage
->Data
= NULL
;
2517 make_null_texture(texImage
);
2518 if (ctx
->Driver
.CompressedTexImage1D
) {
2520 (*ctx
->Driver
.CompressedTexImage1D
)( ctx
, target
, level
,
2521 texImage
->Data
, texObj
, texImage
, &retain
);
2526 gl_put_texobj_on_dirty_list( ctx
, texObj
);
2527 ctx
->NewState
|= NEW_TEXTURING
;
2529 else if (target
== GL_PROXY_TEXTURE_1D
) {
2530 /* Proxy texture: check for errors and update proxy state */
2531 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2532 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
2533 /* if error, clear all proxy texture image parameters */
2534 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
2535 MEMSET( ctx
->Texture
.Proxy1D
->Image
[level
], 0,
2536 sizeof(struct gl_texture_image
) );
2540 /* if no error, update proxy texture image parameters */
2541 init_texture_image(ctx
->Texture
.Proxy1D
->Image
[level
],
2542 width
, 1, 1, border
, internalFormat
);
2546 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB(target)" );
2553 _mesa_CompressedTexImage2DARB(GLenum target
, GLint level
,
2554 GLenum internalFormat
, GLsizei width
,
2555 GLsizei height
, GLint border
, GLsizei imageSize
,
2558 GET_CURRENT_CONTEXT(ctx
);
2559 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCompressedTexImage2DARB");
2561 if (target
== GL_TEXTURE_2D
) {
2562 struct gl_texture_unit
*texUnit
;
2563 struct gl_texture_object
*texObj
;
2564 struct gl_texture_image
*texImage
;
2566 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2567 GL_NONE
, GL_NONE
, 1, width
, height
, 1, border
)) {
2568 return; /* error in texture image was detected */
2571 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2572 texObj
= texUnit
->CurrentD
[2];
2573 texImage
= texObj
->Image
[level
];
2576 texImage
= _mesa_alloc_texture_image();
2577 texObj
->Image
[level
] = texImage
;
2579 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
2583 else if (texImage
->Data
) {
2584 FREE(texImage
->Data
);
2585 texImage
->Data
= NULL
;
2588 /* setup the teximage struct's fields */
2589 init_texture_image(texImage
, width
, height
, 1, border
, internalFormat
);
2591 /* process the texture image */
2593 GLboolean retain
= GL_TRUE
;
2594 GLboolean success
= GL_FALSE
;
2595 if (ctx
->Driver
.CompressedTexImage2D
) {
2596 success
= (*ctx
->Driver
.CompressedTexImage2D
)( ctx
, target
, level
,
2597 data
, texObj
, texImage
, &retain
);
2599 if (retain
|| !success
) {
2600 /* make internal copy of the texture image */
2601 GLuint imageSize
= _mesa_compressed_image_size(internalFormat
,
2603 texImage
->Data
= MALLOC(imageSize
);
2604 if (texImage
->Data
) {
2605 MEMCPY(texImage
->Data
, data
, imageSize
);
2608 if (!retain
&& texImage
->Data
) {
2609 FREE(texImage
->Data
);
2610 texImage
->Data
= NULL
;
2614 make_null_texture(texImage
);
2615 if (ctx
->Driver
.CompressedTexImage2D
) {
2617 (*ctx
->Driver
.CompressedTexImage2D
)( ctx
, target
, level
,
2618 texImage
->Data
, texObj
, texImage
, &retain
);
2623 gl_put_texobj_on_dirty_list( ctx
, texObj
);
2624 ctx
->NewState
|= NEW_TEXTURING
;
2626 else if (target
== GL_PROXY_TEXTURE_2D
) {
2627 /* Proxy texture: check for errors and update proxy state */
2628 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2629 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
2630 /* if error, clear all proxy texture image parameters */
2631 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
2632 MEMSET( ctx
->Texture
.Proxy2D
->Image
[level
], 0,
2633 sizeof(struct gl_texture_image
) );
2637 /* if no error, update proxy texture image parameters */
2638 init_texture_image(ctx
->Texture
.Proxy2D
->Image
[level
],
2639 width
, 1, 1, border
, internalFormat
);
2643 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB(target)" );
2650 _mesa_CompressedTexImage3DARB(GLenum target
, GLint level
,
2651 GLenum internalFormat
, GLsizei width
,
2652 GLsizei height
, GLsizei depth
, GLint border
,
2653 GLsizei imageSize
, const GLvoid
*data
)
2655 GET_CURRENT_CONTEXT(ctx
);
2656 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCompressedTexImage3DARB");
2658 if (target
== GL_TEXTURE_1D
) {
2659 struct gl_texture_unit
*texUnit
;
2660 struct gl_texture_object
*texObj
;
2661 struct gl_texture_image
*texImage
;
2663 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2664 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
)) {
2665 return; /* error in texture image was detected */
2668 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2669 texObj
= texUnit
->CurrentD
[3];
2670 texImage
= texObj
->Image
[level
];
2673 texImage
= _mesa_alloc_texture_image();
2674 texObj
->Image
[level
] = texImage
;
2676 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage3DARB");
2680 else if (texImage
->Data
) {
2681 FREE(texImage
->Data
);
2682 texImage
->Data
= NULL
;
2685 /* setup the teximage struct's fields */
2686 init_texture_image(texImage
, width
, height
, depth
, border
, internalFormat
);
2688 /* process the texture image */
2690 GLboolean retain
= GL_TRUE
;
2691 GLboolean success
= GL_FALSE
;
2692 if (ctx
->Driver
.CompressedTexImage3D
) {
2693 success
= (*ctx
->Driver
.CompressedTexImage3D
)( ctx
, target
, level
,
2694 data
, texObj
, texImage
, &retain
);
2696 if (retain
|| !success
) {
2697 /* make internal copy of the texture image */
2698 GLuint imageSize
= _mesa_compressed_image_size(internalFormat
,
2699 width
, height
, depth
);
2700 texImage
->Data
= MALLOC(imageSize
);
2701 if (texImage
->Data
) {
2702 MEMCPY(texImage
->Data
, data
, imageSize
);
2705 if (!retain
&& texImage
->Data
) {
2706 FREE(texImage
->Data
);
2707 texImage
->Data
= NULL
;
2711 make_null_texture(texImage
);
2712 if (ctx
->Driver
.CompressedTexImage3D
) {
2714 (*ctx
->Driver
.CompressedTexImage3D
)( ctx
, target
, level
,
2715 texImage
->Data
, texObj
, texImage
, &retain
);
2720 gl_put_texobj_on_dirty_list( ctx
, texObj
);
2721 ctx
->NewState
|= NEW_TEXTURING
;
2723 else if (target
== GL_PROXY_TEXTURE_3D
) {
2724 /* Proxy texture: check for errors and update proxy state */
2725 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2726 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
)) {
2727 /* if error, clear all proxy texture image parameters */
2728 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
2729 MEMSET( ctx
->Texture
.Proxy3D
->Image
[level
], 0,
2730 sizeof(struct gl_texture_image
) );
2734 /* if no error, update proxy texture image parameters */
2735 init_texture_image(ctx
->Texture
.Proxy3D
->Image
[level
],
2736 width
, 1, 1, border
, internalFormat
);
2740 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB(target)" );
2747 _mesa_CompressedTexSubImage1DARB(GLenum target
, GLint level
, GLint xoffset
,
2748 GLsizei width
, GLenum format
,
2749 GLsizei imageSize
, const GLvoid
*data
)
2755 _mesa_CompressedTexSubImage2DARB(GLenum target
, GLint level
, GLint xoffset
,
2756 GLint yoffset
, GLsizei width
, GLsizei height
,
2757 GLenum format
, GLsizei imageSize
,
2764 _mesa_CompressedTexSubImage3DARB(GLenum target
, GLint level
, GLint xoffset
,
2765 GLint yoffset
, GLint zoffset
, GLsizei width
,
2766 GLsizei height
, GLsizei depth
, GLenum format
,
2767 GLsizei imageSize
, const GLvoid
*data
)
2773 _mesa_GetCompressedTexImageARB(GLenum target
, GLint lod
, GLvoid
*img
)