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
->Image
[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
->Image
[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
->Image
[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 !(ctx
->Extensions
.HaveTextureCubeMap
&&
908 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
909 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
910 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
914 else if (dimensions
== 3) {
915 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_3D
);
916 if (target
!= GL_TEXTURE_3D
&& !isProxy
) {
917 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
922 gl_problem( ctx
, "bad dims in texture_error_check" );
927 if (border
!= 0 && border
!= 1) {
930 sprintf(message
, "glTexImage%dD(border)", dimensions
);
931 gl_error(ctx
, GL_INVALID_VALUE
, message
);
937 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
938 || logbase2( width
- 2 * border
) < 0) {
941 sprintf(message
, "glTexImage%dD(width)", dimensions
);
942 gl_error(ctx
, GL_INVALID_VALUE
, message
);
948 if (dimensions
>= 2) {
949 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
950 || logbase2( height
- 2 * border
) < 0) {
953 sprintf(message
, "glTexImage%dD(height)", dimensions
);
954 gl_error(ctx
, GL_INVALID_VALUE
, message
);
960 /* For cube map, width must equal height */
961 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
962 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
963 if (width
!= height
) {
965 gl_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
972 if (dimensions
>= 3) {
973 if (depth
< 2 * border
|| depth
> 2 + ctx
->Const
.MaxTextureSize
974 || logbase2( depth
- 2 * border
) < 0) {
976 gl_error( ctx
, GL_INVALID_VALUE
, "glTexImage3D(depth)" );
983 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
986 sprintf(message
, "glTexImage%dD(level)", dimensions
);
987 gl_error(ctx
, GL_INVALID_VALUE
, message
);
992 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
996 sprintf(message
, "glTexImage%dD(internalFormat)", dimensions
);
997 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1002 if (!is_compressed_format(internalFormat
)) {
1003 if (!_mesa_is_legal_format_and_type( format
, type
)) {
1004 /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
1005 * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
1009 sprintf(message
, "glTexImage%dD(format or type)", dimensions
);
1010 gl_error(ctx
, GL_INVALID_OPERATION
, message
);
1016 /* if we get here, the parameters are OK */
1023 * Test glTexSubImage[123]D() parameters for errors.
1025 * dimensions - must be 1 or 2 or 3
1026 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
1029 subtexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
1030 GLenum target
, GLint level
,
1031 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1032 GLint width
, GLint height
, GLint depth
,
1033 GLenum format
, GLenum type
)
1035 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1036 struct gl_texture_image
*destTex
;
1038 if (dimensions
== 1) {
1039 if (target
!= GL_TEXTURE_1D
) {
1040 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(target)" );
1044 else if (dimensions
== 2) {
1045 if (ctx
->Extensions
.HaveTextureCubeMap
) {
1046 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1047 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1048 target
!= GL_TEXTURE_2D
) {
1049 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
1053 else if (target
!= GL_TEXTURE_2D
) {
1054 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
1058 else if (dimensions
== 3) {
1059 if (target
!= GL_TEXTURE_3D
) {
1060 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3D(target)" );
1065 gl_problem( ctx
, "bad dims in texture_error_check" );
1069 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1070 gl_error(ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(level)");
1076 sprintf(message
, "glTexSubImage%dD(width)", dimensions
);
1077 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1080 if (height
< 0 && dimensions
> 1) {
1082 sprintf(message
, "glTexSubImage%dD(height)", dimensions
);
1083 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1086 if (depth
< 0 && dimensions
> 2) {
1088 sprintf(message
, "glTexSubImage%dD(depth)", dimensions
);
1089 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1093 destTex
= texUnit
->CurrentD
[2]->Image
[level
];
1095 gl_error(ctx
, GL_INVALID_OPERATION
, "glTexSubImage2D");
1099 if (xoffset
< -((GLint
)destTex
->Border
)) {
1100 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset)");
1103 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
1104 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset+width)");
1107 if (dimensions
> 1) {
1108 if (yoffset
< -((GLint
)destTex
->Border
)) {
1109 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset)");
1112 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
1113 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset+height)");
1117 if (dimensions
> 2) {
1118 if (zoffset
< -((GLint
)destTex
->Border
)) {
1119 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset)");
1122 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+destTex
->Border
)) {
1123 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset+depth)");
1128 if (!is_compressed_format(destTex
->IntFormat
)) {
1129 if (!_mesa_is_legal_format_and_type(format
, type
)) {
1131 sprintf(message
, "glTexSubImage%dD(format or type)", dimensions
);
1132 gl_error(ctx
, GL_INVALID_ENUM
, message
);
1142 * Test glCopyTexImage[12]D() parameters for errors.
1143 * Input: dimensions - must be 1 or 2 or 3
1144 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
1147 copytexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
1148 GLenum target
, GLint level
, GLint internalFormat
,
1149 GLint width
, GLint height
, GLint border
)
1153 if (dimensions
== 1) {
1154 if (target
!= GL_TEXTURE_1D
) {
1155 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
1159 else if (dimensions
== 2) {
1160 if (ctx
->Extensions
.HaveTextureCubeMap
) {
1161 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1162 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1163 target
!= GL_TEXTURE_2D
) {
1164 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1168 else if (target
!= GL_TEXTURE_2D
) {
1169 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1175 if (border
!=0 && border
!=1) {
1177 sprintf(message
, "glCopyTexImage%dD(border)", dimensions
);
1178 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1183 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
1184 || logbase2( width
- 2 * border
) < 0) {
1186 sprintf(message
, "glCopyTexImage%dD(width)", dimensions
);
1187 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1192 if (dimensions
>= 2) {
1193 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
1194 || logbase2( height
- 2 * border
) < 0) {
1196 sprintf(message
, "glCopyTexImage%dD(height)", dimensions
);
1197 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1202 /* For cube map, width must equal height */
1203 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1204 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
1205 if (width
!= height
) {
1206 gl_error(ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(width != height)");
1212 if (level
<0 || level
>=ctx
->Const
.MaxTextureLevels
) {
1214 sprintf(message
, "glCopyTexImage%dD(level)", dimensions
);
1215 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1219 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
1222 sprintf(message
, "glCopyTexImage%dD(internalFormat)", dimensions
);
1223 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1227 /* if we get here, the parameters are OK */
1233 copytexsubimage_error_check( GLcontext
*ctx
, GLuint dimensions
,
1234 GLenum target
, GLint level
,
1235 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1236 GLsizei width
, GLsizei height
)
1238 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1239 struct gl_texture_image
*teximage
;
1241 if (dimensions
== 1) {
1242 if (target
!= GL_TEXTURE_1D
) {
1243 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
1247 else if (dimensions
== 2) {
1248 if (ctx
->Extensions
.HaveTextureCubeMap
) {
1249 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1250 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1251 target
!= GL_TEXTURE_2D
) {
1252 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1256 else if (target
!= GL_TEXTURE_2D
) {
1257 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1261 else if (dimensions
== 3) {
1262 if (target
!= GL_TEXTURE_3D
) {
1263 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3D(target)" );
1268 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1270 sprintf(message
, "glCopyTexSubImage%dD(level)", dimensions
);
1271 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1277 sprintf(message
, "glCopyTexSubImage%dD(width)", dimensions
);
1278 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1281 if (dimensions
> 1 && height
< 0) {
1283 sprintf(message
, "glCopyTexSubImage%dD(height)", dimensions
);
1284 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1288 teximage
= texUnit
->CurrentD
[dimensions
]->Image
[level
];
1291 sprintf(message
, "glCopyTexSubImage%dD(undefined texture)", dimensions
);
1292 gl_error(ctx
, GL_INVALID_OPERATION
, message
);
1296 if (xoffset
< -((GLint
)teximage
->Border
)) {
1298 sprintf(message
, "glCopyTexSubImage%dD(xoffset)", dimensions
);
1299 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1302 if (xoffset
+width
> (GLint
) (teximage
->Width
+teximage
->Border
)) {
1304 sprintf(message
, "glCopyTexSubImage%dD(xoffset+width)", dimensions
);
1305 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1308 if (dimensions
> 1) {
1309 if (yoffset
< -((GLint
)teximage
->Border
)) {
1311 sprintf(message
, "glCopyTexSubImage%dD(yoffset)", dimensions
);
1312 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1315 /* NOTE: we're adding the border here, not subtracting! */
1316 if (yoffset
+height
> (GLint
) (teximage
->Height
+teximage
->Border
)) {
1318 sprintf(message
, "glCopyTexSubImage%dD(yoffset+height)", dimensions
);
1319 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1324 if (dimensions
> 2) {
1325 if (zoffset
< -((GLint
)teximage
->Border
)) {
1327 sprintf(message
, "glCopyTexSubImage%dD(zoffset)", dimensions
);
1328 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1331 if (zoffset
> (GLint
) (teximage
->Depth
+teximage
->Border
)) {
1333 sprintf(message
, "glCopyTexSubImage%dD(zoffset+depth)", dimensions
);
1334 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1339 /* if we get here, the parameters are OK */
1347 * Called from the API. Note that width includes the border.
1350 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
1351 GLsizei width
, GLint border
, GLenum format
,
1352 GLenum type
, const GLvoid
*pixels
)
1354 GET_CURRENT_CONTEXT(ctx
);
1355 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glTexImage1D");
1357 if (target
==GL_TEXTURE_1D
) {
1358 struct gl_texture_unit
*texUnit
;
1359 struct gl_texture_object
*texObj
;
1360 struct gl_texture_image
*texImage
;
1362 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1363 format
, type
, 1, width
, 1, 1, border
)) {
1364 return; /* error in texture image was detected */
1367 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1368 texObj
= texUnit
->CurrentD
[1];
1369 texImage
= texObj
->Image
[level
];
1372 texImage
= _mesa_alloc_texture_image();
1373 texObj
->Image
[level
] = texImage
;
1375 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
1379 else if (texImage
->Data
) {
1380 FREE(texImage
->Data
);
1381 texImage
->Data
= NULL
;
1384 /* setup the teximage struct's fields */
1385 init_texture_image(texImage
, width
, 1, 1, border
, internalFormat
);
1387 /* process the texture image */
1389 GLboolean retain
= GL_TRUE
;
1390 GLboolean success
= GL_FALSE
;
1391 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
1392 && ctx
->Driver
.TexImage1D
) {
1393 /* let device driver try to use raw image */
1394 success
= (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, format
,
1395 type
, pixels
, &ctx
->Unpack
,
1396 texObj
, texImage
, &retain
);
1398 if (retain
|| !success
) {
1399 /* make internal copy of the texture image */
1400 make_texture_image(ctx
, texImage
, format
, type
,
1401 pixels
, &ctx
->Unpack
);
1402 if (!success
&& ctx
->Driver
.TexImage1D
) {
1403 /* let device driver try to use unpacked image */
1404 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
1405 GL_UNSIGNED_BYTE
, texImage
->Data
,
1406 &_mesa_native_packing
,
1407 texObj
, texImage
, &retain
);
1410 if (!retain
&& texImage
->Data
) {
1411 FREE(texImage
->Data
);
1412 texImage
->Data
= NULL
;
1416 make_null_texture(texImage
);
1417 if (ctx
->Driver
.TexImage1D
) {
1419 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
1420 GL_UNSIGNED_BYTE
, texImage
->Data
,
1421 &_mesa_native_packing
,
1422 texObj
, texImage
, &retain
);
1427 gl_put_texobj_on_dirty_list( ctx
, texObj
);
1428 ctx
->NewState
|= NEW_TEXTURING
;
1430 else if (target
==GL_PROXY_TEXTURE_1D
) {
1431 /* Proxy texture: check for errors and update proxy state */
1432 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1433 format
, type
, 1, width
, 1, 1, border
)) {
1434 /* if error, clear all proxy texture image parameters */
1435 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1436 MEMSET( ctx
->Texture
.Proxy1D
->Image
[level
], 0,
1437 sizeof(struct gl_texture_image
) );
1441 /* if no error, update proxy texture image parameters */
1442 init_texture_image(ctx
->Texture
.Proxy1D
->Image
[level
],
1443 width
, 1, 1, border
, internalFormat
);
1447 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1454 _mesa_TexImage2D( GLenum target
, GLint level
, GLint internalFormat
,
1455 GLsizei width
, GLsizei height
, GLint border
,
1456 GLenum format
, GLenum type
,
1457 const GLvoid
*pixels
)
1459 GET_CURRENT_CONTEXT(ctx
);
1460 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glTexImage2D");
1462 if (target
==GL_TEXTURE_2D
||
1463 (ctx
->Extensions
.HaveTextureCubeMap
&&
1464 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1465 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
1466 struct gl_texture_unit
*texUnit
;
1467 struct gl_texture_object
*texObj
;
1468 struct gl_texture_image
*texImage
;
1470 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1471 format
, type
, 2, width
, height
, 1, border
)) {
1472 return; /* error in texture image was detected */
1475 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1476 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1477 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1480 texImage
= _mesa_alloc_texture_image();
1481 set_tex_image(texObj
, target
, level
, texImage
);
1482 /*texObj->Image[level] = texImage;*/
1484 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1488 else if (texImage
->Data
) {
1489 FREE(texImage
->Data
);
1490 texImage
->Data
= NULL
;
1493 /* setup the teximage struct's fields */
1494 init_texture_image(texImage
, width
, height
, 1, border
, internalFormat
);
1496 /* process the texture image */
1498 GLboolean retain
= GL_TRUE
;
1499 GLboolean success
= GL_FALSE
;
1500 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
1501 && ctx
->Driver
.TexImage2D
) {
1502 /* let device driver try to use raw image */
1503 success
= (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, format
,
1504 type
, pixels
, &ctx
->Unpack
,
1505 texObj
, texImage
, &retain
);
1507 if (retain
|| !success
) {
1508 /* make internal copy of the texture image */
1509 make_texture_image(ctx
, texImage
, format
, type
,
1510 pixels
, &ctx
->Unpack
);
1511 if (!success
&& ctx
->Driver
.TexImage2D
) {
1512 /* let device driver try to use unpacked image */
1513 (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, texImage
->Format
,
1514 GL_UNSIGNED_BYTE
, texImage
->Data
,
1515 &_mesa_native_packing
,
1516 texObj
, texImage
, &retain
);
1519 if (!retain
&& texImage
->Data
) {
1520 FREE(texImage
->Data
);
1521 texImage
->Data
= NULL
;
1525 make_null_texture(texImage
);
1526 if (ctx
->Driver
.TexImage2D
) {
1528 (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, texImage
->Format
,
1529 GL_UNSIGNED_BYTE
, texImage
->Data
,
1530 &_mesa_native_packing
,
1531 texObj
, texImage
, &retain
);
1535 #define OLD_DD_TEXTURE
1536 #ifdef OLD_DD_TEXTURE
1537 /* XXX this will be removed in the future */
1538 if (ctx
->Driver
.TexImage
) {
1539 (*ctx
->Driver
.TexImage
)( ctx
, target
, texObj
, level
, internalFormat
,
1545 gl_put_texobj_on_dirty_list( ctx
, texObj
);
1546 ctx
->NewState
|= NEW_TEXTURING
;
1548 else if (target
==GL_PROXY_TEXTURE_2D
) {
1549 /* Proxy texture: check for errors and update proxy state */
1550 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1551 format
, type
, 2, width
, height
, 1, border
)) {
1552 /* if error, clear all proxy texture image parameters */
1553 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1554 MEMSET( ctx
->Texture
.Proxy2D
->Image
[level
], 0,
1555 sizeof(struct gl_texture_image
) );
1559 /* if no error, update proxy texture image parameters */
1560 init_texture_image(ctx
->Texture
.Proxy1D
->Image
[level
],
1561 width
, height
, 1, border
, internalFormat
);
1565 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1573 * Called by the API or display list executor.
1574 * Note that width and height include the border.
1577 _mesa_TexImage3D( GLenum target
, GLint level
, GLint internalFormat
,
1578 GLsizei width
, GLsizei height
, GLsizei depth
,
1579 GLint border
, GLenum format
, GLenum type
,
1580 const GLvoid
*pixels
)
1582 GET_CURRENT_CONTEXT(ctx
);
1583 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glTexImage3D");
1585 if (target
==GL_TEXTURE_3D_EXT
) {
1586 struct gl_texture_unit
*texUnit
;
1587 struct gl_texture_object
*texObj
;
1588 struct gl_texture_image
*texImage
;
1589 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1590 format
, type
, 3, width
, height
, depth
, border
)) {
1591 return; /* error in texture image was detected */
1594 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1595 texObj
= texUnit
->CurrentD
[3];
1596 texImage
= texObj
->Image
[level
];
1599 texImage
= _mesa_alloc_texture_image();
1600 texObj
->Image
[level
] = texImage
;
1602 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
1606 else if (texImage
->Data
) {
1607 FREE(texImage
->Data
);
1608 texImage
->Data
= NULL
;
1611 /* setup the teximage struct's fields */
1612 init_texture_image(texImage
, width
, height
, depth
,
1613 border
, internalFormat
);
1615 /* process the texture image */
1617 GLboolean retain
= GL_TRUE
;
1618 GLboolean success
= GL_FALSE
;
1619 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
1620 && ctx
->Driver
.TexImage3D
) {
1621 /* let device driver try to use raw image */
1622 success
= (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, format
,
1623 type
, pixels
, &ctx
->Unpack
,
1624 texObj
, texImage
, &retain
);
1626 if (retain
|| !success
) {
1627 /* make internal copy of the texture image */
1628 make_texture_image(ctx
, texImage
, format
, type
,
1629 pixels
, &ctx
->Unpack
);
1630 if (!success
&& ctx
->Driver
.TexImage3D
) {
1631 /* let device driver try to use unpacked image */
1632 (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, texImage
->Format
,
1633 GL_UNSIGNED_BYTE
, texImage
->Data
,
1634 &_mesa_native_packing
,
1635 texObj
, texImage
, &retain
);
1638 if (!retain
&& texImage
->Data
) {
1639 FREE(texImage
->Data
);
1640 texImage
->Data
= NULL
;
1644 make_null_texture(texImage
);
1645 if (ctx
->Driver
.TexImage3D
) {
1647 (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, texImage
->Format
,
1648 GL_UNSIGNED_BYTE
, texImage
->Data
,
1649 &_mesa_native_packing
,
1650 texObj
, texImage
, &retain
);
1655 gl_put_texobj_on_dirty_list( ctx
, texObj
);
1656 ctx
->NewState
|= NEW_TEXTURING
;
1658 else if (target
==GL_PROXY_TEXTURE_3D
) {
1659 /* Proxy texture: check for errors and update proxy state */
1660 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1661 format
, type
, 3, width
, height
, depth
, border
)) {
1662 /* if error, clear all proxy texture image parameters */
1663 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1664 MEMSET( ctx
->Texture
.Proxy3D
->Image
[level
], 0,
1665 sizeof(struct gl_texture_image
) );
1669 /* if no error, update proxy texture image parameters */
1670 init_texture_image(ctx
->Texture
.Proxy1D
->Image
[level
],
1671 width
, height
, depth
, border
, internalFormat
);
1675 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1682 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
1683 GLsizei width
, GLsizei height
, GLsizei depth
,
1684 GLint border
, GLenum format
, GLenum type
,
1685 const GLvoid
*pixels
)
1687 _mesa_TexImage3D(target
, level
, (GLint
) internalFormat
, width
, height
,
1688 depth
, border
, format
, type
, pixels
);
1693 * Fetch a texture image from the device driver.
1694 * Store the results in the given texture object at the given mipmap level.
1697 _mesa_get_teximage_from_driver( GLcontext
*ctx
, GLenum target
, GLint level
,
1698 const struct gl_texture_object
*texObj
)
1701 GLenum imgFormat
, imgType
;
1702 GLboolean freeImage
;
1703 struct gl_texture_image
*texImage
;
1704 GLint destComponents
, numPixels
, srcBytesPerTexel
;
1706 if (!ctx
->Driver
.GetTexImage
)
1709 image
= (*ctx
->Driver
.GetTexImage
)( ctx
, target
, level
, texObj
,
1710 &imgFormat
, &imgType
, &freeImage
);
1714 texImage
= texObj
->Image
[level
];
1719 destComponents
= components_in_intformat(texImage
->Format
);
1720 assert(destComponents
> 0);
1721 numPixels
= texImage
->Width
* texImage
->Height
* texImage
->Depth
;
1722 assert(numPixels
> 0);
1723 srcBytesPerTexel
= _mesa_bytes_per_pixel(imgFormat
, imgType
);
1724 assert(srcBytesPerTexel
> 0);
1726 if (!texImage
->Data
) {
1727 /* Allocate memory for the texture image data */
1728 texImage
->Data
= (GLubyte
*) MALLOC(numPixels
* destComponents
+ EXTRA_BYTE
);
1731 if (imgFormat
== texImage
->Format
&& imgType
== GL_UNSIGNED_BYTE
) {
1732 /* We got lucky! The driver's format and type match Mesa's format. */
1733 if (texImage
->Data
) {
1734 MEMCPY(texImage
->Data
, image
, numPixels
* destComponents
);
1738 /* Convert the texture image from the driver's format to Mesa's
1741 const GLint width
= texImage
->Width
;
1742 const GLint height
= texImage
->Height
;
1743 const GLint depth
= texImage
->Depth
;
1744 const GLint destBytesPerRow
= width
* destComponents
* sizeof(GLchan
);
1745 const GLint srcBytesPerRow
= width
* srcBytesPerTexel
;
1746 const GLenum dstType
= GL_UNSIGNED_BYTE
;
1747 const GLenum dstFormat
= texImage
->Format
;
1748 const GLubyte
*srcPtr
= (const GLubyte
*) image
;
1749 GLubyte
*destPtr
= texImage
->Data
;
1751 if (texImage
->Format
== GL_COLOR_INDEX
) {
1752 /* color index texture */
1754 assert(imgFormat
== GL_COLOR_INDEX
);
1755 for (img
= 0; img
< depth
; img
++) {
1756 for (row
= 0; row
< height
; row
++) {
1757 _mesa_unpack_index_span(ctx
, width
, dstType
, destPtr
,
1758 imgType
, srcPtr
, &_mesa_native_packing
, GL_FALSE
);
1759 destPtr
+= destBytesPerRow
;
1760 srcPtr
+= srcBytesPerRow
;
1767 for (img
= 0; img
< depth
; img
++) {
1768 for (row
= 0; row
< height
; row
++) {
1769 _mesa_unpack_ubyte_color_span(ctx
, width
, dstFormat
, destPtr
,
1770 imgFormat
, imgType
, srcPtr
, &_mesa_native_packing
, GL_FALSE
);
1771 destPtr
+= destBytesPerRow
;
1772 srcPtr
+= srcBytesPerRow
;
1784 _mesa_GetTexImage( GLenum target
, GLint level
, GLenum format
,
1785 GLenum type
, GLvoid
*pixels
)
1787 GET_CURRENT_CONTEXT(ctx
);
1788 const struct gl_texture_object
*texObj
;
1789 struct gl_texture_image
*texImage
;
1790 GLboolean discardImage
;
1792 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetTexImage");
1794 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1795 gl_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
1799 if (_mesa_sizeof_type(type
) <= 0) {
1800 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
1804 if (_mesa_components_in_format(format
) <= 0) {
1805 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
1814 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[1];
1815 texImage
= texObj
->Image
[level
];
1818 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[2];
1819 texImage
= texObj
->Image
[level
];
1821 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
1822 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
1823 texImage
= texObj
->Image
[level
];
1825 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
1826 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
1827 texImage
= texObj
->NegX
[level
];
1829 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
1830 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
1831 texImage
= texObj
->PosY
[level
];
1833 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
1834 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
1835 texImage
= texObj
->NegY
[level
];
1837 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
1838 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
1839 texImage
= texObj
->PosZ
[level
];
1841 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
1842 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
1843 texImage
= texObj
->NegZ
[level
];
1846 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[3];
1847 texImage
= texObj
->Image
[level
];
1850 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)" );
1855 /* invalid mipmap level */
1859 if (!texImage
->Data
) {
1860 /* try to get the texture image from the device driver */
1861 _mesa_get_teximage_from_driver(ctx
, target
, level
, texObj
);
1862 discardImage
= GL_TRUE
;
1865 discardImage
= GL_FALSE
;
1868 if (texImage
->Data
) {
1869 GLint width
= texImage
->Width
;
1870 GLint height
= texImage
->Height
;
1873 for (row
= 0; row
< height
; row
++) {
1874 /* compute destination address in client memory */
1875 GLvoid
*dest
= _mesa_image_address( &ctx
->Unpack
, pixels
,
1877 format
, type
, 0, row
, 0);
1880 if (texImage
->Format
== GL_RGBA
) {
1881 const GLubyte
*src
= texImage
->Data
+ row
* width
* 4 * sizeof(GLubyte
);
1882 _mesa_pack_rgba_span( ctx
, width
, (CONST
GLubyte (*)[4]) src
,
1883 format
, type
, dest
, &ctx
->Pack
, GL_TRUE
);
1886 /* fetch RGBA row from texture image then pack it in client mem */
1887 GLubyte rgba
[MAX_WIDTH
][4];
1890 switch (texImage
->Format
) {
1892 src
= texImage
->Data
+ row
* width
* sizeof(GLubyte
);
1893 for (i
= 0; i
< width
; i
++) {
1894 rgba
[i
][RCOMP
] = 255;
1895 rgba
[i
][GCOMP
] = 255;
1896 rgba
[i
][BCOMP
] = 255;
1897 rgba
[i
][ACOMP
] = src
[i
];
1901 src
= texImage
->Data
+ row
* width
* sizeof(GLubyte
);
1902 for (i
= 0; i
< width
; i
++) {
1903 rgba
[i
][RCOMP
] = src
[i
];
1904 rgba
[i
][GCOMP
] = src
[i
];
1905 rgba
[i
][BCOMP
] = src
[i
];
1906 rgba
[i
][ACOMP
] = 255;
1909 case GL_LUMINANCE_ALPHA
:
1910 src
= texImage
->Data
+ row
* 2 * width
* sizeof(GLubyte
);
1911 for (i
= 0; i
< width
; i
++) {
1912 rgba
[i
][RCOMP
] = src
[i
*2+0];
1913 rgba
[i
][GCOMP
] = src
[i
*2+0];
1914 rgba
[i
][BCOMP
] = src
[i
*2+0];
1915 rgba
[i
][ACOMP
] = src
[i
*2+1];
1919 src
= texImage
->Data
+ row
* width
* sizeof(GLubyte
);
1920 for (i
= 0; i
< width
; i
++) {
1921 rgba
[i
][RCOMP
] = src
[i
];
1922 rgba
[i
][GCOMP
] = src
[i
];
1923 rgba
[i
][BCOMP
] = src
[i
];
1924 rgba
[i
][ACOMP
] = 255;
1928 src
= texImage
->Data
+ row
* 3 * width
* sizeof(GLubyte
);
1929 for (i
= 0; i
< width
; i
++) {
1930 rgba
[i
][RCOMP
] = src
[i
*3+0];
1931 rgba
[i
][GCOMP
] = src
[i
*3+1];
1932 rgba
[i
][BCOMP
] = src
[i
*3+2];
1933 rgba
[i
][ACOMP
] = 255;
1937 /* this special case should have been handled above! */
1938 gl_problem( ctx
, "error 1 in gl_GetTexImage" );
1940 case GL_COLOR_INDEX
:
1941 gl_problem( ctx
, "GL_COLOR_INDEX not implemented in gl_GetTexImage" );
1944 gl_problem( ctx
, "bad format in gl_GetTexImage" );
1946 _mesa_pack_rgba_span( ctx
, width
, (const GLubyte (*)[4])rgba
,
1947 format
, type
, dest
, &ctx
->Pack
, GL_TRUE
);
1951 /* if we got the teximage from the device driver we'll discard it now */
1953 FREE(texImage
->Data
);
1954 texImage
->Data
= NULL
;
1962 _mesa_TexSubImage1D( GLenum target
, GLint level
,
1963 GLint xoffset
, GLsizei width
,
1964 GLenum format
, GLenum type
,
1965 const GLvoid
*pixels
)
1967 GET_CURRENT_CONTEXT(ctx
);
1968 struct gl_texture_unit
*texUnit
;
1969 struct gl_texture_object
*texObj
;
1970 struct gl_texture_image
*texImage
;
1971 GLboolean success
= GL_FALSE
;
1973 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
1974 width
, 1, 1, format
, type
)) {
1975 return; /* error was detected */
1978 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1979 texObj
= texUnit
->CurrentD
[1];
1980 texImage
= texObj
->Image
[level
];
1983 if (width
== 0 || !pixels
)
1984 return; /* no-op, not an error */
1987 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
1988 && ctx
->Driver
.TexSubImage1D
) {
1989 success
= (*ctx
->Driver
.TexSubImage1D
)( ctx
, target
, level
, xoffset
,
1990 width
, format
, type
, pixels
,
1991 &ctx
->Unpack
, texObj
, texImage
);
1994 /* XXX if Driver.TexSubImage1D, unpack image and try again? */
1996 const GLint texComponents
= components_in_intformat(texImage
->Format
);
1997 const GLenum texFormat
= texImage
->Format
;
1998 const GLint xoffsetb
= xoffset
+ texImage
->Border
;
1999 GLboolean retain
= GL_TRUE
;
2000 if (!texImage
->Data
) {
2001 _mesa_get_teximage_from_driver( ctx
, target
, level
, texObj
);
2002 if (!texImage
->Data
) {
2003 make_null_texture(texImage
);
2005 if (!texImage
->Data
)
2006 return; /* we're really out of luck! */
2009 if (texFormat
== GL_COLOR_INDEX
) {
2010 /* color index texture */
2011 GLubyte
*dst
= texImage
->Data
+ xoffsetb
* texComponents
;
2012 const GLvoid
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
, width
,
2013 1, format
, type
, 0, 0, 0);
2014 _mesa_unpack_index_span(ctx
, width
, GL_UNSIGNED_BYTE
, dst
,
2015 type
, src
, &ctx
->Unpack
, GL_TRUE
);
2019 GLubyte
*dst
= texImage
->Data
+ xoffsetb
* texComponents
;
2020 const GLvoid
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
, width
,
2021 1, format
, type
, 0, 0, 0);
2022 _mesa_unpack_ubyte_color_span(ctx
, width
, texFormat
, dst
, format
,
2023 type
, src
, &ctx
->Unpack
, GL_TRUE
);
2026 if (ctx
->Driver
.TexImage1D
) {
2027 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
2028 GL_UNSIGNED_BYTE
, texImage
->Data
,
2029 &_mesa_native_packing
, texObj
, texImage
,
2033 if (!retain
&& texImage
->Data
) {
2034 FREE(texImage
->Data
);
2035 texImage
->Data
= NULL
;
2039 /*gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[1] );*/
2044 _mesa_TexSubImage2D( GLenum target
, GLint level
,
2045 GLint xoffset
, GLint yoffset
,
2046 GLsizei width
, GLsizei height
,
2047 GLenum format
, GLenum type
,
2048 const GLvoid
*pixels
)
2050 GET_CURRENT_CONTEXT(ctx
);
2051 struct gl_texture_unit
*texUnit
;
2052 struct gl_texture_object
*texObj
;
2053 struct gl_texture_image
*texImage
;
2054 GLboolean success
= GL_FALSE
;
2056 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2057 width
, height
, 1, format
, type
)) {
2058 return; /* error was detected */
2061 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2062 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2063 texImage
= texObj
->Image
[level
];
2066 if (width
== 0 || height
== 0 || !pixels
)
2067 return; /* no-op, not an error */
2069 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
2070 && ctx
->Driver
.TexSubImage2D
) {
2071 success
= (*ctx
->Driver
.TexSubImage2D
)( ctx
, target
, level
, xoffset
,
2072 yoffset
, width
, height
, format
, type
,
2073 pixels
, &ctx
->Unpack
, texObj
, texImage
);
2076 /* XXX if Driver.TexSubImage2D, unpack image and try again? */
2078 const GLint texComponents
= components_in_intformat(texImage
->Format
);
2079 const GLenum texFormat
= texImage
->Format
;
2080 const GLint xoffsetb
= xoffset
+ texImage
->Border
;
2081 const GLint yoffsetb
= yoffset
+ texImage
->Border
;
2082 const GLint srcStride
= _mesa_image_row_stride(&ctx
->Unpack
, width
,
2084 const GLint dstStride
= texImage
->Width
* texComponents
*sizeof(GLubyte
);
2085 GLboolean retain
= GL_TRUE
;
2087 if (!texImage
->Data
) {
2088 _mesa_get_teximage_from_driver( ctx
, target
, level
, texObj
);
2089 if (!texImage
->Data
) {
2090 make_null_texture(texImage
);
2092 if (!texImage
->Data
)
2093 return; /* we're really out of luck! */
2096 if (texFormat
== GL_COLOR_INDEX
) {
2097 /* color index texture */
2098 GLubyte
*dst
= texImage
->Data
2099 + (yoffsetb
* texImage
->Width
+ xoffsetb
) * texComponents
;
2100 const GLubyte
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
,
2101 width
, height
, format
, type
, 0, 0, 0);
2103 for (row
= 0; row
< height
; row
++) {
2104 _mesa_unpack_index_span(ctx
, width
, GL_UNSIGNED_BYTE
, dst
, type
,
2105 (const GLvoid
*) src
, &ctx
->Unpack
, GL_TRUE
);
2112 GLubyte
*dst
= texImage
->Data
2113 + (yoffsetb
* texImage
->Width
+ xoffsetb
) * texComponents
;
2114 const GLubyte
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
,
2115 width
, height
, format
, type
, 0, 0, 0);
2117 for (row
= 0; row
< height
; row
++) {
2118 _mesa_unpack_ubyte_color_span(ctx
, width
, texFormat
, dst
, format
,
2119 type
, (const GLvoid
*) src
, &ctx
->Unpack
, GL_TRUE
);
2125 if (ctx
->Driver
.TexImage2D
) {
2126 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, texImage
->Format
,
2127 GL_UNSIGNED_BYTE
, texImage
->Data
,
2128 &_mesa_native_packing
, texObj
, texImage
,
2132 if (!retain
&& texImage
->Data
) {
2133 FREE(texImage
->Data
);
2134 texImage
->Data
= NULL
;
2137 #ifdef OLD_DD_TEXTURE
2138 /* XXX this will be removed in the future */
2139 if (ctx
->Driver
.TexSubImage
) {
2140 (*ctx
->Driver
.TexSubImage
)(ctx
, target
, texObj
, level
,
2141 xoffset
, yoffset
, width
, height
,
2142 texImage
->IntFormat
, texImage
);
2144 else if (ctx
->Driver
.TexImage
) {
2145 (*ctx
->Driver
.TexImage
)(ctx
, GL_TEXTURE_2D
, texObj
,
2146 level
, texImage
->IntFormat
, texImage
);
2155 _mesa_TexSubImage3D( GLenum target
, GLint level
,
2156 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2157 GLsizei width
, GLsizei height
, GLsizei depth
,
2158 GLenum format
, GLenum type
,
2159 const GLvoid
*pixels
)
2161 GET_CURRENT_CONTEXT(ctx
);
2162 struct gl_texture_unit
*texUnit
;
2163 struct gl_texture_object
*texObj
;
2164 struct gl_texture_image
*texImage
;
2165 GLboolean success
= GL_FALSE
;
2167 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2168 width
, height
, depth
, format
, type
)) {
2169 return; /* error was detected */
2172 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2173 texObj
= texUnit
->CurrentD
[3];
2174 texImage
= texObj
->Image
[level
];
2177 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
2178 return; /* no-op, not an error */
2180 if (!ctx
->Pixel
.MapColorFlag
&& !ctx
->Pixel
.ScaleOrBiasRGBA
2181 && ctx
->Driver
.TexSubImage3D
) {
2182 success
= (*ctx
->Driver
.TexSubImage3D
)( ctx
, target
, level
, xoffset
,
2183 yoffset
, zoffset
, width
, height
, depth
, format
,
2184 type
, pixels
, &ctx
->Unpack
, texObj
, texImage
);
2187 /* XXX if Driver.TexSubImage3D, unpack image and try again? */
2189 const GLint texComponents
= components_in_intformat(texImage
->Format
);
2190 const GLenum texFormat
= texImage
->Format
;
2191 const GLint xoffsetb
= xoffset
+ texImage
->Border
;
2192 const GLint yoffsetb
= yoffset
+ texImage
->Border
;
2193 const GLint zoffsetb
= zoffset
+ texImage
->Border
;
2194 const GLint texWidth
= texImage
->Width
;
2195 const GLint dstRectArea
= texWidth
* texImage
->Height
;
2196 const GLint srcStride
= _mesa_image_row_stride(&ctx
->Unpack
,
2197 width
, format
, type
);
2198 const GLint dstStride
= texWidth
* texComponents
* sizeof(GLubyte
);
2199 GLboolean retain
= GL_TRUE
;
2201 if (texFormat
== GL_COLOR_INDEX
) {
2202 /* color index texture */
2204 for (img
= 0; img
< depth
; img
++) {
2205 const GLubyte
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
,
2206 width
, height
, format
, type
, img
, 0, 0);
2207 GLubyte
*dst
= texImage
->Data
+ ((zoffsetb
+ img
) * dstRectArea
2208 + yoffsetb
* texWidth
+ xoffsetb
) * texComponents
;
2209 for (row
= 0; row
< height
; row
++) {
2210 _mesa_unpack_index_span(ctx
, width
, GL_UNSIGNED_BYTE
, dst
,
2211 type
, (const GLvoid
*) src
, &ctx
->Unpack
, GL_TRUE
);
2220 for (img
= 0; img
< depth
; img
++) {
2221 const GLubyte
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
,
2222 width
, height
, format
, type
, img
, 0, 0);
2223 GLubyte
*dst
= texImage
->Data
+ ((zoffsetb
+ img
) * dstRectArea
2224 + yoffsetb
* texWidth
+ xoffsetb
) * texComponents
;
2225 for (row
= 0; row
< height
; row
++) {
2226 _mesa_unpack_ubyte_color_span(ctx
, width
, texFormat
, dst
,
2227 format
, type
, (const GLvoid
*) src
, &ctx
->Unpack
, GL_TRUE
);
2234 if (ctx
->Driver
.TexImage3D
) {
2235 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, texImage
->Format
,
2236 GL_UNSIGNED_BYTE
, texImage
->Data
,
2237 &_mesa_native_packing
, texObj
, texImage
,
2241 if (!retain
&& texImage
->Data
) {
2242 FREE(texImage
->Data
);
2243 texImage
->Data
= NULL
;
2251 * Read an RGBA image from the frame buffer.
2252 * This is used by glCopyTexSubImage[12]D().
2253 * Input: ctx - the context
2254 * x, y - lower left corner
2255 * width, height - size of region to read
2256 * Return: pointer to block of GL_RGBA, GLubyte data.
2259 read_color_image( GLcontext
*ctx
, GLint x
, GLint y
,
2260 GLsizei width
, GLsizei height
)
2263 GLubyte
*image
, *dst
;
2265 image
= (GLubyte
*) MALLOC(width
* height
* 4 * sizeof(GLubyte
));
2269 /* Select buffer to read from */
2270 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->ReadBuffer
,
2271 ctx
->Pixel
.DriverReadBuffer
);
2273 /* XXX TODO we have to apply pixel transfer ops here! */
2276 stride
= width
* 4 * sizeof(GLubyte
);
2277 for (i
= 0; i
< height
; i
++) {
2278 gl_read_rgba_span( ctx
, ctx
->ReadBuffer
, width
, x
, y
+ i
,
2279 (GLubyte (*)[4]) dst
);
2283 /* Read from draw buffer (the default) */
2284 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->DrawBuffer
,
2285 ctx
->Color
.DriverDrawBuffer
);
2293 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
2294 GLenum internalFormat
,
2296 GLsizei width
, GLint border
)
2298 GET_CURRENT_CONTEXT(ctx
);
2299 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexImage1D");
2301 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
2305 if (ctx
->Pixel
.MapColorFlag
|| ctx
->Pixel
.ScaleOrBiasRGBA
2306 || !ctx
->Driver
.CopyTexImage1D
2307 || !(*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
,
2308 internalFormat
, x
, y
, width
, border
))
2310 struct gl_pixelstore_attrib unpackSave
;
2312 /* get image from framebuffer */
2313 GLubyte
*image
= read_color_image( ctx
, x
, y
, width
, 1 );
2315 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D" );
2319 /* call glTexImage1D to redefine the texture */
2320 unpackSave
= ctx
->Unpack
;
2321 ctx
->Unpack
= _mesa_native_packing
;
2322 (*ctx
->Exec
->TexImage1D
)( target
, level
, internalFormat
, width
,
2323 border
, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2324 ctx
->Unpack
= unpackSave
;
2333 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
2334 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
2337 GET_CURRENT_CONTEXT(ctx
);
2338 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexImage2D");
2340 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
2341 width
, height
, border
))
2344 if (ctx
->Pixel
.MapColorFlag
|| ctx
->Pixel
.ScaleOrBiasRGBA
2345 || !ctx
->Driver
.CopyTexImage2D
2346 || !(*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
,
2347 internalFormat
, x
, y
, width
, height
, border
))
2349 struct gl_pixelstore_attrib unpackSave
;
2351 /* get image from framebuffer */
2352 GLubyte
*image
= read_color_image( ctx
, x
, y
, width
, height
);
2354 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D" );
2358 /* call glTexImage2D to redefine the texture */
2359 unpackSave
= ctx
->Unpack
;
2360 ctx
->Unpack
= _mesa_native_packing
;
2361 (ctx
->Exec
->TexImage2D
)( target
, level
, internalFormat
, width
,
2362 height
, border
, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2363 ctx
->Unpack
= unpackSave
;
2372 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
2373 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
2375 GET_CURRENT_CONTEXT(ctx
);
2376 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexSubImage1D");
2378 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
2379 xoffset
, 0, 0, width
, 1))
2382 if (ctx
->Pixel
.MapColorFlag
|| ctx
->Pixel
.ScaleOrBiasRGBA
2383 || !ctx
->Driver
.CopyTexSubImage1D
2384 || !(*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
,
2385 xoffset
, x
, y
, width
)) {
2386 struct gl_texture_unit
*texUnit
;
2387 struct gl_texture_image
*teximage
;
2388 struct gl_pixelstore_attrib unpackSave
;
2391 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2392 teximage
= texUnit
->CurrentD
[1]->Image
[level
];
2395 /* get image from frame buffer */
2396 image
= read_color_image(ctx
, x
, y
, width
, 1);
2398 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage2D" );
2402 /* now call glTexSubImage1D to do the real work */
2403 unpackSave
= ctx
->Unpack
;
2404 ctx
->Unpack
= _mesa_native_packing
;
2405 _mesa_TexSubImage1D(target
, level
, xoffset
, width
,
2406 GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2407 ctx
->Unpack
= unpackSave
;
2416 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
2417 GLint xoffset
, GLint yoffset
,
2418 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2420 GET_CURRENT_CONTEXT(ctx
);
2421 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexSubImage2D");
2423 if (copytexsubimage_error_check(ctx
, 2, target
, level
,
2424 xoffset
, yoffset
, 0, width
, height
))
2427 if (ctx
->Pixel
.MapColorFlag
|| ctx
->Pixel
.ScaleOrBiasRGBA
2428 || !ctx
->Driver
.CopyTexSubImage2D
2429 || !(*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
2430 xoffset
, yoffset
, x
, y
, width
, height
)) {
2431 struct gl_texture_unit
*texUnit
;
2432 struct gl_texture_image
*teximage
;
2433 struct gl_pixelstore_attrib unpackSave
;
2436 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2437 teximage
= texUnit
->CurrentD
[2]->Image
[level
];
2440 /* get image from frame buffer */
2441 image
= read_color_image(ctx
, x
, y
, width
, height
);
2443 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage2D" );
2447 /* now call glTexSubImage2D to do the real work */
2448 unpackSave
= ctx
->Unpack
;
2449 ctx
->Unpack
= _mesa_native_packing
;
2450 _mesa_TexSubImage2D(target
, level
, xoffset
, yoffset
, width
, height
,
2451 GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2452 ctx
->Unpack
= unpackSave
;
2461 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
2462 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2463 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2465 GET_CURRENT_CONTEXT(ctx
);
2466 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexSubImage3D");
2468 if (copytexsubimage_error_check(ctx
, 3, target
, level
,
2469 xoffset
, yoffset
, zoffset
, width
, height
))
2472 if (ctx
->Pixel
.MapColorFlag
|| ctx
->Pixel
.ScaleOrBiasRGBA
2473 || !ctx
->Driver
.CopyTexSubImage3D
2474 || !(*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
2475 xoffset
, yoffset
, zoffset
, x
, y
, width
, height
)) {
2476 struct gl_texture_unit
*texUnit
;
2477 struct gl_texture_image
*teximage
;
2478 struct gl_pixelstore_attrib unpackSave
;
2481 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2482 teximage
= texUnit
->CurrentD
[3]->Image
[level
];
2485 /* get image from frame buffer */
2486 image
= read_color_image(ctx
, x
, y
, width
, height
);
2488 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage2D" );
2492 /* now call glTexSubImage2D to do the real work */
2493 unpackSave
= ctx
->Unpack
;
2494 ctx
->Unpack
= _mesa_native_packing
;
2495 _mesa_TexSubImage3D(target
, level
, xoffset
, yoffset
, zoffset
,
2496 width
, height
, 1, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2497 ctx
->Unpack
= unpackSave
;
2506 _mesa_CompressedTexImage1DARB(GLenum target
, GLint level
,
2507 GLenum internalFormat
, GLsizei width
,
2508 GLint border
, GLsizei imageSize
,
2511 GET_CURRENT_CONTEXT(ctx
);
2512 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCompressedTexImage1DARB");
2514 if (target
== GL_TEXTURE_1D
) {
2515 struct gl_texture_unit
*texUnit
;
2516 struct gl_texture_object
*texObj
;
2517 struct gl_texture_image
*texImage
;
2519 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2520 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
2521 return; /* error in texture image was detected */
2524 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2525 texObj
= texUnit
->CurrentD
[1];
2526 texImage
= texObj
->Image
[level
];
2529 texImage
= _mesa_alloc_texture_image();
2530 texObj
->Image
[level
] = texImage
;
2532 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage1DARB");
2536 else if (texImage
->Data
) {
2537 FREE(texImage
->Data
);
2538 texImage
->Data
= NULL
;
2541 /* setup the teximage struct's fields */
2542 init_texture_image(texImage
, width
, 1, 1, border
, internalFormat
);
2544 /* process the texture image */
2546 GLboolean retain
= GL_TRUE
;
2547 GLboolean success
= GL_FALSE
;
2548 if (ctx
->Driver
.CompressedTexImage1D
) {
2549 success
= (*ctx
->Driver
.CompressedTexImage1D
)( ctx
, target
, level
,
2550 data
, texObj
, texImage
, &retain
);
2552 if (retain
|| !success
) {
2553 /* make internal copy of the texture image */
2554 GLuint imageSize
= _mesa_compressed_image_size(internalFormat
,
2556 texImage
->Data
= MALLOC(imageSize
);
2557 if (texImage
->Data
) {
2558 MEMCPY(texImage
->Data
, data
, imageSize
);
2561 if (!retain
&& texImage
->Data
) {
2562 FREE(texImage
->Data
);
2563 texImage
->Data
= NULL
;
2567 make_null_texture(texImage
);
2568 if (ctx
->Driver
.CompressedTexImage1D
) {
2570 (*ctx
->Driver
.CompressedTexImage1D
)( ctx
, target
, level
,
2571 texImage
->Data
, texObj
, texImage
, &retain
);
2576 gl_put_texobj_on_dirty_list( ctx
, texObj
);
2577 ctx
->NewState
|= NEW_TEXTURING
;
2579 else if (target
== GL_PROXY_TEXTURE_1D
) {
2580 /* Proxy texture: check for errors and update proxy state */
2581 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2582 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
2583 /* if error, clear all proxy texture image parameters */
2584 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
2585 MEMSET( ctx
->Texture
.Proxy1D
->Image
[level
], 0,
2586 sizeof(struct gl_texture_image
) );
2590 /* if no error, update proxy texture image parameters */
2591 init_texture_image(ctx
->Texture
.Proxy1D
->Image
[level
],
2592 width
, 1, 1, border
, internalFormat
);
2596 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB(target)" );
2603 _mesa_CompressedTexImage2DARB(GLenum target
, GLint level
,
2604 GLenum internalFormat
, GLsizei width
,
2605 GLsizei height
, GLint border
, GLsizei imageSize
,
2608 GET_CURRENT_CONTEXT(ctx
);
2609 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCompressedTexImage2DARB");
2611 if (target
==GL_TEXTURE_2D
||
2612 (ctx
->Extensions
.HaveTextureCubeMap
&&
2613 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2614 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
2615 struct gl_texture_unit
*texUnit
;
2616 struct gl_texture_object
*texObj
;
2617 struct gl_texture_image
*texImage
;
2619 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2620 GL_NONE
, GL_NONE
, 1, width
, height
, 1, border
)) {
2621 return; /* error in texture image was detected */
2624 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2625 texObj
= texUnit
->CurrentD
[2];
2626 texImage
= texObj
->Image
[level
];
2629 texImage
= _mesa_alloc_texture_image();
2630 texObj
->Image
[level
] = texImage
;
2632 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
2636 else if (texImage
->Data
) {
2637 FREE(texImage
->Data
);
2638 texImage
->Data
= NULL
;
2641 /* setup the teximage struct's fields */
2642 init_texture_image(texImage
, width
, height
, 1, border
, internalFormat
);
2644 /* process the texture image */
2646 GLboolean retain
= GL_TRUE
;
2647 GLboolean success
= GL_FALSE
;
2648 if (ctx
->Driver
.CompressedTexImage2D
) {
2649 success
= (*ctx
->Driver
.CompressedTexImage2D
)( ctx
, target
, level
,
2650 data
, texObj
, texImage
, &retain
);
2652 if (retain
|| !success
) {
2653 /* make internal copy of the texture image */
2654 GLuint imageSize
= _mesa_compressed_image_size(internalFormat
,
2656 texImage
->Data
= MALLOC(imageSize
);
2657 if (texImage
->Data
) {
2658 MEMCPY(texImage
->Data
, data
, imageSize
);
2661 if (!retain
&& texImage
->Data
) {
2662 FREE(texImage
->Data
);
2663 texImage
->Data
= NULL
;
2667 make_null_texture(texImage
);
2668 if (ctx
->Driver
.CompressedTexImage2D
) {
2670 (*ctx
->Driver
.CompressedTexImage2D
)( ctx
, target
, level
,
2671 texImage
->Data
, texObj
, texImage
, &retain
);
2676 gl_put_texobj_on_dirty_list( ctx
, texObj
);
2677 ctx
->NewState
|= NEW_TEXTURING
;
2679 else if (target
== GL_PROXY_TEXTURE_2D
) {
2680 /* Proxy texture: check for errors and update proxy state */
2681 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2682 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
2683 /* if error, clear all proxy texture image parameters */
2684 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
2685 MEMSET( ctx
->Texture
.Proxy2D
->Image
[level
], 0,
2686 sizeof(struct gl_texture_image
) );
2690 /* if no error, update proxy texture image parameters */
2691 init_texture_image(ctx
->Texture
.Proxy2D
->Image
[level
],
2692 width
, 1, 1, border
, internalFormat
);
2696 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB(target)" );
2703 _mesa_CompressedTexImage3DARB(GLenum target
, GLint level
,
2704 GLenum internalFormat
, GLsizei width
,
2705 GLsizei height
, GLsizei depth
, GLint border
,
2706 GLsizei imageSize
, const GLvoid
*data
)
2708 GET_CURRENT_CONTEXT(ctx
);
2709 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCompressedTexImage3DARB");
2711 if (target
== GL_TEXTURE_3D
) {
2712 struct gl_texture_unit
*texUnit
;
2713 struct gl_texture_object
*texObj
;
2714 struct gl_texture_image
*texImage
;
2716 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2717 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
)) {
2718 return; /* error in texture image was detected */
2721 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2722 texObj
= texUnit
->CurrentD
[3];
2723 texImage
= texObj
->Image
[level
];
2726 texImage
= _mesa_alloc_texture_image();
2727 texObj
->Image
[level
] = texImage
;
2729 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage3DARB");
2733 else if (texImage
->Data
) {
2734 FREE(texImage
->Data
);
2735 texImage
->Data
= NULL
;
2738 /* setup the teximage struct's fields */
2739 init_texture_image(texImage
, width
, height
, depth
, border
, internalFormat
);
2741 /* process the texture image */
2743 GLboolean retain
= GL_TRUE
;
2744 GLboolean success
= GL_FALSE
;
2745 if (ctx
->Driver
.CompressedTexImage3D
) {
2746 success
= (*ctx
->Driver
.CompressedTexImage3D
)( ctx
, target
, level
,
2747 data
, texObj
, texImage
, &retain
);
2749 if (retain
|| !success
) {
2750 /* make internal copy of the texture image */
2751 GLuint imageSize
= _mesa_compressed_image_size(internalFormat
,
2752 width
, height
, depth
);
2753 texImage
->Data
= MALLOC(imageSize
);
2754 if (texImage
->Data
) {
2755 MEMCPY(texImage
->Data
, data
, imageSize
);
2758 if (!retain
&& texImage
->Data
) {
2759 FREE(texImage
->Data
);
2760 texImage
->Data
= NULL
;
2764 make_null_texture(texImage
);
2765 if (ctx
->Driver
.CompressedTexImage3D
) {
2767 (*ctx
->Driver
.CompressedTexImage3D
)( ctx
, target
, level
,
2768 texImage
->Data
, texObj
, texImage
, &retain
);
2773 gl_put_texobj_on_dirty_list( ctx
, texObj
);
2774 ctx
->NewState
|= NEW_TEXTURING
;
2776 else if (target
== GL_PROXY_TEXTURE_3D
) {
2777 /* Proxy texture: check for errors and update proxy state */
2778 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2779 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
)) {
2780 /* if error, clear all proxy texture image parameters */
2781 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
2782 MEMSET( ctx
->Texture
.Proxy3D
->Image
[level
], 0,
2783 sizeof(struct gl_texture_image
) );
2787 /* if no error, update proxy texture image parameters */
2788 init_texture_image(ctx
->Texture
.Proxy3D
->Image
[level
],
2789 width
, 1, 1, border
, internalFormat
);
2793 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB(target)" );
2800 _mesa_CompressedTexSubImage1DARB(GLenum target
, GLint level
, GLint xoffset
,
2801 GLsizei width
, GLenum format
,
2802 GLsizei imageSize
, const GLvoid
*data
)
2804 GET_CURRENT_CONTEXT(ctx
);
2805 struct gl_texture_unit
*texUnit
;
2806 struct gl_texture_object
*texObj
;
2807 struct gl_texture_image
*texImage
;
2808 GLboolean success
= GL_FALSE
;
2810 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
2811 width
, 1, 1, format
, GL_NONE
)) {
2812 return; /* error was detected */
2815 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2816 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2817 texImage
= texObj
->Image
[level
];
2820 if (width
== 0 || !data
)
2821 return; /* no-op, not an error */
2823 if (ctx
->Driver
.CompressedTexSubImage1D
) {
2824 success
= (*ctx
->Driver
.CompressedTexSubImage1D
)(ctx
, target
, level
,
2825 xoffset
, width
, format
, imageSize
, data
, texObj
, texImage
);
2828 /* XXX what else can we do? */
2829 gl_problem(ctx
, "glCompressedTexSubImage1DARB failed!");
2837 _mesa_CompressedTexSubImage2DARB(GLenum target
, GLint level
, GLint xoffset
,
2838 GLint yoffset
, GLsizei width
, GLsizei height
,
2839 GLenum format
, GLsizei imageSize
,
2842 GET_CURRENT_CONTEXT(ctx
);
2843 struct gl_texture_unit
*texUnit
;
2844 struct gl_texture_object
*texObj
;
2845 struct gl_texture_image
*texImage
;
2846 GLboolean success
= GL_FALSE
;
2848 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2849 width
, height
, 1, format
, GL_NONE
)) {
2850 return; /* error was detected */
2853 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2854 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2855 texImage
= texObj
->Image
[level
];
2858 if (width
== 0 || height
== 0 || !data
)
2859 return; /* no-op, not an error */
2861 if (ctx
->Driver
.CompressedTexSubImage2D
) {
2862 success
= (*ctx
->Driver
.CompressedTexSubImage2D
)(ctx
, target
, level
,
2863 xoffset
, yoffset
, width
, height
, format
,
2864 imageSize
, data
, texObj
, texImage
);
2867 /* XXX what else can we do? */
2868 gl_problem(ctx
, "glCompressedTexSubImage2DARB failed!");
2875 _mesa_CompressedTexSubImage3DARB(GLenum target
, GLint level
, GLint xoffset
,
2876 GLint yoffset
, GLint zoffset
, GLsizei width
,
2877 GLsizei height
, GLsizei depth
, GLenum format
,
2878 GLsizei imageSize
, const GLvoid
*data
)
2880 GET_CURRENT_CONTEXT(ctx
);
2881 struct gl_texture_unit
*texUnit
;
2882 struct gl_texture_object
*texObj
;
2883 struct gl_texture_image
*texImage
;
2884 GLboolean success
= GL_FALSE
;
2886 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2887 width
, height
, depth
, format
, GL_NONE
)) {
2888 return; /* error was detected */
2891 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2892 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2893 texImage
= texObj
->Image
[level
];
2896 if (width
== 0 || height
== 0 || depth
== 0 || !data
)
2897 return; /* no-op, not an error */
2899 if (ctx
->Driver
.CompressedTexSubImage3D
) {
2900 success
= (*ctx
->Driver
.CompressedTexSubImage3D
)(ctx
, target
, level
,
2901 xoffset
, yoffset
, zoffset
, width
, height
, depth
,
2902 format
, imageSize
, data
, texObj
, texImage
);
2905 /* XXX what else can we do? */
2906 gl_problem(ctx
, "glCompressedTexSubImage3DARB failed!");
2913 _mesa_GetCompressedTexImageARB(GLenum target
, GLint level
, GLvoid
*img
)
2915 GET_CURRENT_CONTEXT(ctx
);
2916 const struct gl_texture_object
*texObj
;
2917 struct gl_texture_image
*texImage
;
2919 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetCompressedTexImageARB");
2921 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
2922 gl_error( ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)" );
2928 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[1];
2929 texImage
= texObj
->Image
[level
];
2932 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[2];
2933 texImage
= texObj
->Image
[level
];
2935 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
2936 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
2937 texImage
= texObj
->Image
[level
];
2939 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
2940 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
2941 texImage
= texObj
->NegX
[level
];
2943 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
2944 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
2945 texImage
= texObj
->PosY
[level
];
2947 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
2948 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
2949 texImage
= texObj
->NegY
[level
];
2951 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
2952 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
2953 texImage
= texObj
->PosZ
[level
];
2955 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
2956 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
2957 texImage
= texObj
->NegZ
[level
];
2960 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[3];
2961 texImage
= texObj
->Image
[level
];
2964 gl_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB(target)");
2969 /* invalid mipmap level */
2970 gl_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
2974 if (!texImage
->IsCompressed
) {
2975 gl_error(ctx
, GL_INVALID_OPERATION
, "glGetCompressedTexImageARB");
2982 if (ctx
->Driver
.GetCompressedTexImage
) {
2983 (*ctx
->Driver
.GetCompressedTexImage
)(ctx
, target
, level
, img
, texObj
,
2987 gl_problem(ctx
, "Driver doesn't implement GetCompressedTexImage");