1 /* $Id: teximage.c,v 1.70 2001/01/23 23:35:23 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 #include "swrast/s_span.h" /* XXX SWRAST hack */
49 * Mesa's native texture datatype is GLchan. Native formats are
50 * GL_ALPHA, GL_LUMINANCE, GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, GL_RGBA,
52 * Device drivers are free to implement any internal format they want.
57 static void PrintTexture(const struct gl_texture_image
*img
)
60 GLchan
*data
= img
->Data
;
63 printf("No texture data\n");
67 switch (img
->Format
) {
74 case GL_LUMINANCE_ALPHA
:
84 gl_problem(NULL
, "error in PrintTexture\n");
89 for (i
= 0; i
< img
->Height
; i
++) {
90 for (j
= 0; j
< img
->Width
; j
++) {
92 printf("%02x ", data
[0]);
94 printf("%02x%02x ", data
[0], data
[1]);
96 printf("%02x%02x%02x ", data
[0], data
[1], data
[2]);
98 printf("%02x%02x%02x%02x ", data
[0], data
[1], data
[2], data
[3]);
109 * Compute log base 2 of n.
110 * If n isn't an exact power of two return -1.
138 * Given an internal texture format enum or 1, 2, 3, 4 return the
139 * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE,
140 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.
141 * Return -1 if invalid enum.
144 _mesa_base_tex_format( GLcontext
*ctx
, GLint format
)
147 * Ask the driver for the base format, if it doesn't
148 * know, it will return -1;
150 if (ctx
->Driver
.BaseCompressedTexFormat
) {
151 GLint ifmt
= (*ctx
->Driver
.BaseCompressedTexFormat
)(ctx
, format
);
171 case GL_LUMINANCE_ALPHA
:
172 case GL_LUMINANCE4_ALPHA4
:
173 case GL_LUMINANCE6_ALPHA2
:
174 case GL_LUMINANCE8_ALPHA8
:
175 case GL_LUMINANCE12_ALPHA4
:
176 case GL_LUMINANCE12_ALPHA12
:
177 case GL_LUMINANCE16_ALPHA16
:
178 return GL_LUMINANCE_ALPHA
;
206 case GL_COLOR_INDEX1_EXT
:
207 case GL_COLOR_INDEX2_EXT
:
208 case GL_COLOR_INDEX4_EXT
:
209 case GL_COLOR_INDEX8_EXT
:
210 case GL_COLOR_INDEX12_EXT
:
211 case GL_COLOR_INDEX16_EXT
:
212 return GL_COLOR_INDEX
;
214 return -1; /* error */
221 * Given an internal texture format enum or 1, 2, 3, 4 return the
222 * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE,
223 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA. Return the
224 * number of components for the format. Return -1 if invalid enum.
227 components_in_intformat( GLint format
)
244 case GL_LUMINANCE_ALPHA
:
245 case GL_LUMINANCE4_ALPHA4
:
246 case GL_LUMINANCE6_ALPHA2
:
247 case GL_LUMINANCE8_ALPHA8
:
248 case GL_LUMINANCE12_ALPHA4
:
249 case GL_LUMINANCE12_ALPHA12
:
250 case GL_LUMINANCE16_ALPHA16
:
279 case GL_COLOR_INDEX1_EXT
:
280 case GL_COLOR_INDEX2_EXT
:
281 case GL_COLOR_INDEX4_EXT
:
282 case GL_COLOR_INDEX8_EXT
:
283 case GL_COLOR_INDEX12_EXT
:
284 case GL_COLOR_INDEX16_EXT
:
287 return -1; /* error */
293 * Return GL_TRUE if internalFormat is a compressed format, return GL_FALSE
297 is_compressed_format(GLcontext
*ctx
, GLenum internalFormat
)
299 if (ctx
->Driver
.IsCompressedFormat
) {
300 return (*ctx
->Driver
.IsCompressedFormat
)(ctx
, internalFormat
);
308 * Examine the texImage->Format field and set the Red, Green, Blue, etc
309 * texel component sizes to default values.
310 * These fields are set only here by core Mesa but device drivers may
311 * overwritting these fields to indicate true texel resolution.
314 set_teximage_component_sizes( struct gl_texture_image
*texImage
)
316 switch (texImage
->Format
) {
318 texImage
->RedBits
= 0;
319 texImage
->GreenBits
= 0;
320 texImage
->BlueBits
= 0;
321 texImage
->AlphaBits
= 8;
322 texImage
->IntensityBits
= 0;
323 texImage
->LuminanceBits
= 0;
324 texImage
->IndexBits
= 0;
327 texImage
->RedBits
= 0;
328 texImage
->GreenBits
= 0;
329 texImage
->BlueBits
= 0;
330 texImage
->AlphaBits
= 0;
331 texImage
->IntensityBits
= 0;
332 texImage
->LuminanceBits
= 8;
333 texImage
->IndexBits
= 0;
335 case GL_LUMINANCE_ALPHA
:
336 texImage
->RedBits
= 0;
337 texImage
->GreenBits
= 0;
338 texImage
->BlueBits
= 0;
339 texImage
->AlphaBits
= 8;
340 texImage
->IntensityBits
= 0;
341 texImage
->LuminanceBits
= 8;
342 texImage
->IndexBits
= 0;
345 texImage
->RedBits
= 0;
346 texImage
->GreenBits
= 0;
347 texImage
->BlueBits
= 0;
348 texImage
->AlphaBits
= 0;
349 texImage
->IntensityBits
= 8;
350 texImage
->LuminanceBits
= 0;
351 texImage
->IndexBits
= 0;
354 texImage
->RedBits
= 8;
355 texImage
->GreenBits
= 0;
356 texImage
->BlueBits
= 0;
357 texImage
->AlphaBits
= 0;
358 texImage
->IntensityBits
= 0;
359 texImage
->LuminanceBits
= 0;
360 texImage
->IndexBits
= 0;
363 texImage
->RedBits
= 0;
364 texImage
->GreenBits
= 8;
365 texImage
->BlueBits
= 0;
366 texImage
->AlphaBits
= 0;
367 texImage
->IntensityBits
= 0;
368 texImage
->LuminanceBits
= 0;
369 texImage
->IndexBits
= 0;
372 texImage
->RedBits
= 0;
373 texImage
->GreenBits
= 0;
374 texImage
->BlueBits
= 8;
375 texImage
->AlphaBits
= 0;
376 texImage
->IntensityBits
= 0;
377 texImage
->LuminanceBits
= 0;
378 texImage
->IndexBits
= 0;
382 texImage
->RedBits
= 8;
383 texImage
->GreenBits
= 8;
384 texImage
->BlueBits
= 8;
385 texImage
->AlphaBits
= 0;
386 texImage
->IntensityBits
= 0;
387 texImage
->LuminanceBits
= 0;
388 texImage
->IndexBits
= 0;
393 texImage
->RedBits
= 8;
394 texImage
->GreenBits
= 8;
395 texImage
->BlueBits
= 8;
396 texImage
->AlphaBits
= 8;
397 texImage
->IntensityBits
= 0;
398 texImage
->LuminanceBits
= 0;
399 texImage
->IndexBits
= 0;
402 texImage
->RedBits
= 0;
403 texImage
->GreenBits
= 0;
404 texImage
->BlueBits
= 0;
405 texImage
->AlphaBits
= 0;
406 texImage
->IntensityBits
= 0;
407 texImage
->LuminanceBits
= 0;
408 texImage
->IndexBits
= 8;
411 gl_problem(NULL
, "unexpected format in set_teximage_component_sizes");
417 set_tex_image(struct gl_texture_object
*tObj
,
418 GLenum target
, GLint level
,
419 struct gl_texture_image
*texImage
)
425 tObj
->Image
[level
] = texImage
;
427 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
428 tObj
->Image
[level
] = texImage
;
430 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
431 tObj
->NegX
[level
] = texImage
;
433 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
434 tObj
->PosY
[level
] = texImage
;
436 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
437 tObj
->NegY
[level
] = texImage
;
439 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
440 tObj
->PosZ
[level
] = texImage
;
442 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
443 tObj
->NegZ
[level
] = texImage
;
446 gl_problem(NULL
, "bad target in set_tex_image()");
453 * Return new gl_texture_image struct with all fields initialized to zero.
455 struct gl_texture_image
*
456 _mesa_alloc_texture_image( void )
458 return CALLOC_STRUCT(gl_texture_image
);
464 * Initialize most fields of a gl_texture_image struct.
467 init_texture_image( GLcontext
*ctx
,
468 struct gl_texture_image
*img
,
469 GLsizei width
, GLsizei height
, GLsizei depth
,
470 GLint border
, GLenum internalFormat
)
474 img
->Format
= (GLenum
) _mesa_base_tex_format(ctx
, internalFormat
);
475 set_teximage_component_sizes( img
);
476 img
->IntFormat
= (GLenum
) internalFormat
;
477 img
->Border
= border
;
479 img
->Height
= height
;
481 img
->WidthLog2
= logbase2(width
- 2 * border
);
482 if (height
== 1) /* 1-D texture */
485 img
->HeightLog2
= logbase2(height
- 2 * border
);
486 if (depth
== 1) /* 2-D texture */
489 img
->DepthLog2
= logbase2(depth
- 2 * border
);
490 img
->Width2
= 1 << img
->WidthLog2
;
491 img
->Height2
= 1 << img
->HeightLog2
;
492 img
->Depth2
= 1 << img
->DepthLog2
;
493 img
->MaxLog2
= MAX2(img
->WidthLog2
, img
->HeightLog2
);
494 img
->IsCompressed
= is_compressed_format(ctx
, internalFormat
);
500 _mesa_free_texture_image( struct gl_texture_image
*teximage
)
502 if (teximage
->Data
) {
503 FREE( teximage
->Data
);
504 teximage
->Data
= NULL
;
512 * Return number of bytes of storage needed to store a compressed texture
513 * image. Only the driver knows for sure. If the driver can't help us,
517 _mesa_compressed_image_size(GLcontext
*ctx
,
518 GLenum internalFormat
,
524 if (ctx
->Driver
.CompressedImageSize
) {
525 return (*ctx
->Driver
.CompressedImageSize
)(ctx
, internalFormat
,
527 width
, height
, depth
);
530 /* Shouldn't this be an internal error of some sort? */
538 * Given a texture unit and a texture target, return the corresponding
541 struct gl_texture_object
*
542 _mesa_select_tex_object(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
547 return texUnit
->Current1D
;
548 case GL_PROXY_TEXTURE_1D
:
549 return ctx
->Texture
.Proxy1D
;
551 return texUnit
->Current2D
;
552 case GL_PROXY_TEXTURE_2D
:
553 return ctx
->Texture
.Proxy2D
;
555 return texUnit
->Current3D
;
556 case GL_PROXY_TEXTURE_3D
:
557 return ctx
->Texture
.Proxy3D
;
558 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
559 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
560 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
561 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
562 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
563 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
564 return ctx
->Extensions
.ARB_texture_cube_map
565 ? texUnit
->CurrentCubeMap
: NULL
;
566 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
567 return ctx
->Extensions
.ARB_texture_cube_map
568 ? ctx
->Texture
.ProxyCubeMap
: NULL
;
570 gl_problem(NULL
, "bad target in _mesa_select_tex_object()");
577 * Return the texture image struct which corresponds to target and level
578 * for the given texture unit.
580 struct gl_texture_image
*
581 _mesa_select_tex_image(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
582 GLenum target
, GLint level
)
587 return texUnit
->Current1D
->Image
[level
];
588 case GL_PROXY_TEXTURE_1D
:
589 return ctx
->Texture
.Proxy1D
->Image
[level
];
591 return texUnit
->Current2D
->Image
[level
];
592 case GL_PROXY_TEXTURE_2D
:
593 return ctx
->Texture
.Proxy2D
->Image
[level
];
595 return texUnit
->Current3D
->Image
[level
];
596 case GL_PROXY_TEXTURE_3D
:
597 return ctx
->Texture
.Proxy3D
->Image
[level
];
598 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
599 if (ctx
->Extensions
.ARB_texture_cube_map
)
600 return texUnit
->CurrentCubeMap
->Image
[level
];
603 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
604 if (ctx
->Extensions
.ARB_texture_cube_map
)
605 return texUnit
->CurrentCubeMap
->NegX
[level
];
608 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
609 if (ctx
->Extensions
.ARB_texture_cube_map
)
610 return texUnit
->CurrentCubeMap
->PosY
[level
];
613 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
614 if (ctx
->Extensions
.ARB_texture_cube_map
)
615 return texUnit
->CurrentCubeMap
->NegY
[level
];
618 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
619 if (ctx
->Extensions
.ARB_texture_cube_map
)
620 return texUnit
->CurrentCubeMap
->PosZ
[level
];
623 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
624 if (ctx
->Extensions
.ARB_texture_cube_map
)
625 return texUnit
->CurrentCubeMap
->NegZ
[level
];
628 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
629 if (ctx
->Extensions
.ARB_texture_cube_map
)
630 return ctx
->Texture
.ProxyCubeMap
->Image
[level
];
634 gl_problem(ctx
, "bad target in _mesa_select_tex_image()");
642 * Calling glTexImage and related functions when convolution is enabled
643 * with GL_REDUCE border mode causes some complications.
644 * The incoming image must be extra large so that the post-convolution
645 * image size is reduced to a power of two size (plus 2 * border).
646 * This function adjusts a texture width and height accordingly if
647 * convolution with GL_REDUCE is enabled.
650 adjust_texture_size_for_convolution(const GLcontext
*ctx
, GLuint dimensions
,
651 GLsizei
*width
, GLsizei
*height
)
653 if (ctx
->Pixel
.Convolution1DEnabled
655 && ctx
->Pixel
.ConvolutionBorderMode
[0] == GL_REDUCE
) {
656 *width
= *width
- (MAX2(ctx
->Convolution1D
.Width
, 1) - 1);
658 else if (ctx
->Pixel
.Convolution2DEnabled
660 && ctx
->Pixel
.ConvolutionBorderMode
[1] == GL_REDUCE
) {
661 *width
= *width
- (MAX2(ctx
->Convolution2D
.Width
, 1) - 1);
662 *height
= *height
- (MAX2(ctx
->Convolution2D
.Height
, 1) - 1);
664 else if (ctx
->Pixel
.Separable2DEnabled
666 && ctx
->Pixel
.ConvolutionBorderMode
[2] == GL_REDUCE
) {
667 *width
= *width
- (MAX2(ctx
->Separable2D
.Width
, 1) - 1);
668 *height
= *height
- (MAX2(ctx
->Separable2D
.Height
, 1) - 1);
675 * This function is used to move user image data into a texture image.
676 * We handle full texture images and subtexture images. We also take
677 * care of all image transfer operations here, including convolution.
679 * dstXoffset, dstYoffset, dstZoffset - offsets in pixels
680 * dstRowStride, dstImageStride - strides in GLchan's
683 fill_texture_image( GLcontext
*ctx
, GLuint dimensions
,
684 GLenum texFormat
, GLchan
*texAddr
,
685 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
686 GLint dstXoffset
, GLint dstYoffset
, GLint dstZoffset
,
687 GLint dstRowStride
, GLint dstImageStride
,
688 GLenum srcFormat
, GLenum srcType
, const GLvoid
*srcAddr
,
689 const struct gl_pixelstore_attrib
*srcPacking
)
694 ASSERT(dimensions
>= 1 && dimensions
<= 3);
696 ASSERT(srcWidth
>= 1);
697 ASSERT(srcHeight
>= 1);
698 ASSERT(srcDepth
>= 1);
699 ASSERT(dstXoffset
>= 0);
700 ASSERT(dstYoffset
>= 0);
701 ASSERT(dstZoffset
>= 0);
702 ASSERT(dstRowStride
>= 0);
703 ASSERT(dstImageStride
>= 0);
707 texComponents
= components_in_intformat(texFormat
);
709 /* try common 2D texture cases first */
710 if (!ctx
->_ImageTransferState
&& dimensions
== 2
711 && srcType
== GL_UNSIGNED_BYTE
) {
713 if (srcFormat
== texFormat
) {
714 /* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA,
715 * GL_LUMINANCE_ALPHA, etc. texture formats. Use memcpy().
717 const GLchan
*src
= (const GLchan
*) _mesa_image_address(
718 srcPacking
, srcAddr
, srcWidth
, srcHeight
,
719 srcFormat
, srcType
, 0, 0, 0);
720 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
,
721 srcWidth
, srcFormat
, srcType
);
722 const GLint widthInBytes
= srcWidth
* texComponents
* sizeof(GLchan
);
723 GLchan
*dst
= texAddr
+ dstYoffset
* dstRowStride
724 + dstXoffset
* texComponents
;
725 if (srcRowStride
== widthInBytes
&& dstRowStride
== widthInBytes
) {
726 MEMCPY(dst
, src
, srcHeight
* widthInBytes
);
730 for (i
= 0; i
< srcHeight
; i
++) {
731 MEMCPY(dst
, src
, widthInBytes
);
736 return; /* all done */
738 else if (srcFormat
== GL_RGBA
&& texFormat
== GL_RGB
) {
739 /* commonly used by Quake */
740 const GLchan
*src
= (const GLchan
*) _mesa_image_address(
741 srcPacking
, srcAddr
, srcWidth
, srcHeight
,
742 srcFormat
, srcType
, 0, 0, 0);
743 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
,
744 srcWidth
, srcFormat
, srcType
);
745 GLchan
*dst
= texAddr
+ dstYoffset
* dstRowStride
746 + dstXoffset
* texComponents
;
748 for (i
= 0; i
< srcHeight
; i
++) {
749 const GLchan
*s
= src
;
751 for (j
= 0; j
< srcWidth
; j
++) {
753 *d
++ = *s
++; /*green*/
754 *d
++ = *s
++; /*blue*/
760 return; /* all done */
765 * General case solutions
767 if (texFormat
== GL_COLOR_INDEX
) {
768 /* color index texture */
769 const GLenum texType
= GL_UNSIGNED_BYTE
;
771 GLchan
*dest
= texAddr
+ dstZoffset
* dstImageStride
772 + dstYoffset
* dstRowStride
773 + dstXoffset
* texComponents
;
774 for (img
= 0; img
< srcDepth
; img
++) {
775 GLchan
*destRow
= dest
;
776 for (row
= 0; row
< srcHeight
; row
++) {
777 const GLvoid
*src
= _mesa_image_address(srcPacking
,
778 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
779 _mesa_unpack_index_span(ctx
, srcWidth
, texType
, destRow
,
780 srcType
, src
, srcPacking
,
781 ctx
->_ImageTransferState
);
782 destRow
+= dstRowStride
;
784 dest
+= dstImageStride
;
788 /* regular, color texture */
789 if ((dimensions
== 1 && ctx
->Pixel
.Convolution1DEnabled
) ||
790 (dimensions
>= 2 && ctx
->Pixel
.Convolution2DEnabled
) ||
791 (dimensions
>= 2 && ctx
->Pixel
.Separable2DEnabled
)) {
793 * Fill texture image with convolution
796 GLint convWidth
= srcWidth
, convHeight
= srcHeight
;
797 GLfloat
*tmpImage
, *convImage
;
798 tmpImage
= (GLfloat
*) MALLOC(srcWidth
* srcHeight
* 4 * sizeof(GLfloat
));
800 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage");
803 convImage
= (GLfloat
*) MALLOC(srcWidth
* srcHeight
* 4 * sizeof(GLfloat
));
805 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage");
810 for (img
= 0; img
< srcDepth
; img
++) {
812 GLfloat
*dstf
= tmpImage
;
815 /* unpack and do transfer ops up to convolution */
816 for (row
= 0; row
< srcHeight
; row
++) {
817 const GLvoid
*src
= _mesa_image_address(srcPacking
,
818 srcAddr
, srcWidth
, srcHeight
,
819 srcFormat
, srcType
, img
, row
, 0);
820 _mesa_unpack_float_color_span(ctx
, srcWidth
, GL_RGBA
, dstf
,
821 srcFormat
, srcType
, src
, srcPacking
,
822 ctx
->_ImageTransferState
& IMAGE_PRE_CONVOLUTION_BITS
,
824 dstf
+= srcWidth
* 4;
828 if (dimensions
== 1) {
829 ASSERT(ctx
->Pixel
.Convolution1DEnabled
);
830 _mesa_convolve_1d_image(ctx
, &convWidth
, tmpImage
, convImage
);
833 if (ctx
->Pixel
.Convolution2DEnabled
) {
834 _mesa_convolve_2d_image(ctx
, &convWidth
, &convHeight
,
835 tmpImage
, convImage
);
838 ASSERT(ctx
->Pixel
.Separable2DEnabled
);
839 _mesa_convolve_sep_image(ctx
, &convWidth
, &convHeight
,
840 tmpImage
, convImage
);
844 /* packing and transfer ops after convolution */
846 dest
= texAddr
+ (dstZoffset
+ img
) * dstImageStride
847 + dstYoffset
* dstRowStride
;
848 for (row
= 0; row
< convHeight
; row
++) {
849 _mesa_pack_float_rgba_span(ctx
, convWidth
,
850 (const GLfloat (*)[4]) srcf
,
851 texFormat
, GL_UNSIGNED_BYTE
,
852 dest
, &_mesa_native_packing
,
853 ctx
->_ImageTransferState
854 & IMAGE_POST_CONVOLUTION_BITS
);
855 srcf
+= convWidth
* 4;
856 dest
+= dstRowStride
;
868 GLchan
*dest
= texAddr
+ dstZoffset
* dstImageStride
869 + dstYoffset
* dstRowStride
870 + dstXoffset
* texComponents
;
871 for (img
= 0; img
< srcDepth
; img
++) {
872 GLchan
*destRow
= dest
;
873 for (row
= 0; row
< srcHeight
; row
++) {
874 const GLvoid
*srcRow
= _mesa_image_address(srcPacking
,
875 srcAddr
, srcWidth
, srcHeight
,
876 srcFormat
, srcType
, img
, row
, 0);
877 _mesa_unpack_chan_color_span(ctx
, srcWidth
, texFormat
, destRow
,
878 srcFormat
, srcType
, srcRow
, srcPacking
,
879 ctx
->_ImageTransferState
);
880 destRow
+= dstRowStride
;
882 dest
+= dstImageStride
;
890 /* Need this to prevent an out-of-bounds memory access when using
891 * X86 optimized code.
894 # define EXTRA_BYTE sizeof(GLchan)
896 # define EXTRA_BYTE 0
902 * Called by glTexImage[123]D. Fill in a texture image with data given
903 * by the client. All pixel transfer and unpack modes are handled here.
904 * Input: dimensions (1, 2, or 3)
905 * texImage - destination texture image (we'll malloc the memory)
906 * width, height, depth - size of source image
907 * srcFormat, srcType - source image format and type
908 * pixels - source image data
909 * srcPacking - source image packing parameters
911 * NOTE: All texture image parameters should have already been error checked.
913 * NOTE: the texImage dimensions and source image dimensions must be correct
914 * with respect to convolution with border mode = reduce.
917 make_texture_image( GLcontext
*ctx
, GLuint dimensions
,
918 struct gl_texture_image
*texImage
,
919 GLint width
, GLint height
, GLint depth
,
920 GLenum srcFormat
, GLenum srcType
, const GLvoid
*pixels
,
921 const struct gl_pixelstore_attrib
*srcPacking
)
923 const GLint internalFormat
= texImage
->IntFormat
;
924 const GLint components
= components_in_intformat(internalFormat
);
925 GLint convWidth
= width
, convHeight
= height
;
927 if (ctx
->NewState
& _NEW_PIXEL
)
928 gl_update_state(ctx
);
930 if (ctx
->_ImageTransferState
& IMAGE_CONVOLUTION_BIT
) {
931 adjust_texture_size_for_convolution(ctx
, dimensions
,
932 &convWidth
, &convHeight
);
935 texImage
->Data
= (GLchan
*) MALLOC(convWidth
* convHeight
* depth
936 * components
* sizeof(GLchan
) + EXTRA_BYTE
);
938 return; /* out of memory */
940 fill_texture_image(ctx
, dimensions
, texImage
->Format
, texImage
->Data
,
941 width
, height
, depth
, 0, 0, 0,
942 convWidth
* components
* sizeof(GLchan
),
943 convWidth
* convHeight
* components
* sizeof(GLchan
),
944 srcFormat
, srcType
, pixels
, srcPacking
);
950 * glTexImage[123]D can accept a NULL image pointer. In this case we
951 * create a texture image with unspecified image contents per the OpenGL
952 * spec. This function creates an empty image for the given texture image.
955 make_null_texture( struct gl_texture_image
*texImage
)
961 ASSERT(!texImage
->Data
);
963 components
= components_in_intformat(texImage
->IntFormat
);
964 numPixels
= texImage
->Width
* texImage
->Height
* texImage
->Depth
;
966 texImage
->Data
= (GLchan
*) MALLOC( numPixels
* components
* sizeof(GLchan
)
970 * Let's see if anyone finds this. If glTexImage2D() is called with
971 * a NULL image pointer then load the texture image with something
972 * interesting instead of leaving it indeterminate.
974 if (texImage
->Data
) {
975 static const char message
[8][32] = {
979 " X X XXXX XXX XXXXX ",
982 " X X XXXXX XXX X X ",
986 GLchan
*imgPtr
= texImage
->Data
;
988 for (i
= 0; i
< texImage
->Height
; i
++) {
989 GLint srcRow
= 7 - i
% 8;
990 for (j
= 0; j
< texImage
->Width
; j
++) {
991 GLint srcCol
= j
% 32;
992 GLint texel
= (message
[srcRow
][srcCol
]=='X') ? CHAN_MAX
: 70;
993 for (k
=0;k
<components
;k
++) {
994 *imgPtr
++ = (GLchan
) texel
;
1004 * This is called when a proxy texture test fails, we set all the
1005 * image members (except DriverData) to zero.
1008 clear_proxy_teximage(struct gl_texture_image
*img
)
1017 img
->IntensityBits
= 0;
1018 img
->LuminanceBits
= 0;
1028 img
->HeightLog2
= 0;
1031 img
->IsCompressed
= 0;
1032 img
->CompressedSize
= 0;
1038 * Test glTexImage[123]D() parameters for errors.
1040 * dimensions - must be 1 or 2 or 3
1041 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
1044 texture_error_check( GLcontext
*ctx
, GLenum target
,
1045 GLint level
, GLint internalFormat
,
1046 GLenum format
, GLenum type
,
1048 GLint width
, GLint height
,
1049 GLint depth
, GLint border
)
1054 if (dimensions
== 1) {
1055 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_1D
);
1056 if (target
!= GL_TEXTURE_1D
&& !isProxy
) {
1057 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1061 else if (dimensions
== 2) {
1062 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_2D
);
1063 if (target
!= GL_TEXTURE_2D
&& !isProxy
&&
1064 !(ctx
->Extensions
.ARB_texture_cube_map
&&
1065 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1066 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
1067 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1071 else if (dimensions
== 3) {
1072 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_3D
);
1073 if (target
!= GL_TEXTURE_3D
&& !isProxy
) {
1074 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1079 gl_problem( ctx
, "bad dims in texture_error_check" );
1084 if (border
!= 0 && border
!= 1) {
1087 sprintf(message
, "glTexImage%dD(border=%d)", dimensions
, border
);
1088 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1094 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
1095 || logbase2( width
- 2 * border
) < 0) {
1098 sprintf(message
, "glTexImage%dD(width=%d)", dimensions
, width
);
1099 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1105 if (dimensions
>= 2) {
1106 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
1107 || logbase2( height
- 2 * border
) < 0) {
1110 sprintf(message
, "glTexImage%dD(height=%d)", dimensions
, height
);
1111 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1117 /* For cube map, width must equal height */
1118 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1119 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
1120 if (width
!= height
) {
1122 gl_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
1129 if (dimensions
>= 3) {
1130 if (depth
< 2 * border
|| depth
> 2 + ctx
->Const
.MaxTextureSize
1131 || logbase2( depth
- 2 * border
) < 0) {
1134 sprintf(message
, "glTexImage3D(depth=%d)", depth
);
1135 gl_error( ctx
, GL_INVALID_VALUE
, message
);
1142 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1145 sprintf(message
, "glTexImage%dD(level=%d)", dimensions
, level
);
1146 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1151 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
1155 sprintf(message
, "glTexImage%dD(internalFormat=0x%x)", dimensions
,
1157 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1162 if (!is_compressed_format(ctx
, internalFormat
)) {
1163 if (!_mesa_is_legal_format_and_type( format
, type
)) {
1164 /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
1165 * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
1169 sprintf(message
, "glTexImage%dD(format or type)", dimensions
);
1170 gl_error(ctx
, GL_INVALID_OPERATION
, message
);
1176 /* if we get here, the parameters are OK */
1183 * Test glTexSubImage[123]D() parameters for errors.
1185 * dimensions - must be 1 or 2 or 3
1186 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
1189 subtexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
1190 GLenum target
, GLint level
,
1191 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1192 GLint width
, GLint height
, GLint depth
,
1193 GLenum format
, GLenum type
)
1195 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1196 struct gl_texture_image
*destTex
;
1198 if (dimensions
== 1) {
1199 if (target
!= GL_TEXTURE_1D
) {
1200 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(target)" );
1204 else if (dimensions
== 2) {
1205 if (ctx
->Extensions
.ARB_texture_cube_map
) {
1206 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1207 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1208 target
!= GL_TEXTURE_2D
) {
1209 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
1213 else if (target
!= GL_TEXTURE_2D
) {
1214 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
1218 else if (dimensions
== 3) {
1219 if (target
!= GL_TEXTURE_3D
) {
1220 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3D(target)" );
1225 gl_problem( ctx
, "bad dims in texture_error_check" );
1229 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1231 sprintf(message
, "glTexSubImage2D(level=%d)", level
);
1232 gl_error(ctx
, GL_INVALID_ENUM
, message
);
1238 sprintf(message
, "glTexSubImage%dD(width=%d)", dimensions
, width
);
1239 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1242 if (height
< 0 && dimensions
> 1) {
1244 sprintf(message
, "glTexSubImage%dD(height=%d)", dimensions
, height
);
1245 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1248 if (depth
< 0 && dimensions
> 2) {
1250 sprintf(message
, "glTexSubImage%dD(depth=%d)", dimensions
, depth
);
1251 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1255 destTex
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1258 gl_error(ctx
, GL_INVALID_OPERATION
, "glTexSubImage2D");
1262 if (xoffset
< -((GLint
)destTex
->Border
)) {
1263 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset)");
1266 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
1267 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset+width)");
1270 if (dimensions
> 1) {
1271 if (yoffset
< -((GLint
)destTex
->Border
)) {
1272 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset)");
1275 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
1276 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset+height)");
1280 if (dimensions
> 2) {
1281 if (zoffset
< -((GLint
)destTex
->Border
)) {
1282 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset)");
1285 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+destTex
->Border
)) {
1286 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset+depth)");
1291 if (!is_compressed_format(ctx
, destTex
->IntFormat
)) {
1292 if (!_mesa_is_legal_format_and_type(format
, type
)) {
1294 sprintf(message
, "glTexSubImage%dD(format or type)", dimensions
);
1295 gl_error(ctx
, GL_INVALID_ENUM
, message
);
1305 * Test glCopyTexImage[12]D() parameters for errors.
1306 * Input: dimensions - must be 1 or 2 or 3
1307 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
1310 copytexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
1311 GLenum target
, GLint level
, GLint internalFormat
,
1312 GLint width
, GLint height
, GLint border
)
1316 if (dimensions
== 1) {
1317 if (target
!= GL_TEXTURE_1D
) {
1318 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
1322 else if (dimensions
== 2) {
1323 if (ctx
->Extensions
.ARB_texture_cube_map
) {
1324 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1325 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1326 target
!= GL_TEXTURE_2D
) {
1327 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1331 else if (target
!= GL_TEXTURE_2D
) {
1332 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1338 if (border
!=0 && border
!=1) {
1340 sprintf(message
, "glCopyTexImage%dD(border)", dimensions
);
1341 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1346 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
1347 || logbase2( width
- 2 * border
) < 0) {
1349 sprintf(message
, "glCopyTexImage%dD(width=%d)", dimensions
, width
);
1350 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1355 if (dimensions
>= 2) {
1356 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
1357 || logbase2( height
- 2 * border
) < 0) {
1359 sprintf(message
, "glCopyTexImage%dD(height=%d)", dimensions
, height
);
1360 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1365 /* For cube map, width must equal height */
1366 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1367 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
1368 if (width
!= height
) {
1369 gl_error(ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(width != height)");
1375 if (level
<0 || level
>=ctx
->Const
.MaxTextureLevels
) {
1377 sprintf(message
, "glCopyTexImage%dD(level=%d)", dimensions
, level
);
1378 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1382 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
1385 sprintf(message
, "glCopyTexImage%dD(internalFormat)", dimensions
);
1386 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1390 /* if we get here, the parameters are OK */
1396 copytexsubimage_error_check( GLcontext
*ctx
, GLuint dimensions
,
1397 GLenum target
, GLint level
,
1398 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1399 GLsizei width
, GLsizei height
)
1401 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1402 struct gl_texture_image
*teximage
;
1404 if (dimensions
== 1) {
1405 if (target
!= GL_TEXTURE_1D
) {
1406 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
1410 else if (dimensions
== 2) {
1411 if (ctx
->Extensions
.ARB_texture_cube_map
) {
1412 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1413 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1414 target
!= GL_TEXTURE_2D
) {
1415 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1419 else if (target
!= GL_TEXTURE_2D
) {
1420 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1424 else if (dimensions
== 3) {
1425 if (target
!= GL_TEXTURE_3D
) {
1426 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3D(target)" );
1431 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1433 sprintf(message
, "glCopyTexSubImage%dD(level=%d)", dimensions
, level
);
1434 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1440 sprintf(message
, "glCopyTexSubImage%dD(width=%d)", dimensions
, width
);
1441 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1444 if (dimensions
> 1 && height
< 0) {
1446 sprintf(message
, "glCopyTexSubImage%dD(height=%d)", dimensions
, height
);
1447 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1451 teximage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1454 sprintf(message
, "glCopyTexSubImage%dD(undefined texture)", dimensions
);
1455 gl_error(ctx
, GL_INVALID_OPERATION
, message
);
1459 if (xoffset
< -((GLint
)teximage
->Border
)) {
1461 sprintf(message
, "glCopyTexSubImage%dD(xoffset=%d)", dimensions
, xoffset
);
1462 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1465 if (xoffset
+width
> (GLint
) (teximage
->Width
+teximage
->Border
)) {
1467 sprintf(message
, "glCopyTexSubImage%dD(xoffset+width)", dimensions
);
1468 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1471 if (dimensions
> 1) {
1472 if (yoffset
< -((GLint
)teximage
->Border
)) {
1474 sprintf(message
, "glCopyTexSubImage%dD(yoffset=%d)", dimensions
, yoffset
);
1475 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1478 /* NOTE: we're adding the border here, not subtracting! */
1479 if (yoffset
+height
> (GLint
) (teximage
->Height
+teximage
->Border
)) {
1481 sprintf(message
, "glCopyTexSubImage%dD(yoffset+height)", dimensions
);
1482 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1487 if (dimensions
> 2) {
1488 if (zoffset
< -((GLint
)teximage
->Border
)) {
1490 sprintf(message
, "glCopyTexSubImage%dD(zoffset)", dimensions
);
1491 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1494 if (zoffset
> (GLint
) (teximage
->Depth
+teximage
->Border
)) {
1496 sprintf(message
, "glCopyTexSubImage%dD(zoffset+depth)", dimensions
);
1497 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1502 /* if we get here, the parameters are OK */
1510 * Turn generic compressed formats into specific compressed format.
1511 * Some of the compressed formats we don't support, so we
1512 * fall back to the uncompressed format. (See issue 15 of
1513 * the GL_ARB_texture_compression specification.)
1516 get_specific_compressed_tex_format(GLcontext
*ctx
,
1517 GLint ifmt
, GLint numDimensions
,
1527 GLint internalFormat
= ifmt
;
1529 if (ctx
->Extensions
.ARB_texture_compression
1530 && ctx
->Driver
.SpecificCompressedTexFormat
) {
1532 * First, ask the driver for the specific format.
1533 * We do this for all formats, since we may want to
1534 * fake one compressed format for another.
1536 internalFormat
= (*ctx
->Driver
.SpecificCompressedTexFormat
)
1537 (ctx
, internalFormat
, numDimensions
,
1539 widthp
, heightp
, depthp
,
1540 borderp
, formatp
, typep
);
1544 * Now, convert any generic format left to an uncompressed
1545 * specific format. If the driver does not support compression
1546 * of the format, we must drop back to the uncompressed format.
1547 * See issue 15 of the GL_ARB_texture_compression specification.
1549 switch (internalFormat
) {
1550 case GL_COMPRESSED_ALPHA_ARB
:
1551 if (ctx
&& !ctx
->Extensions
.ARB_texture_compression
) {
1552 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1553 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1556 internalFormat
= GL_ALPHA
;
1558 case GL_COMPRESSED_LUMINANCE_ARB
:
1559 if (ctx
&& !ctx
->Extensions
.ARB_texture_compression
) {
1560 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1561 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1564 internalFormat
= GL_LUMINANCE
;
1566 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
1567 if (ctx
&& !ctx
->Extensions
.ARB_texture_compression
) {
1568 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1569 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1572 internalFormat
= GL_LUMINANCE_ALPHA
;
1574 case GL_COMPRESSED_INTENSITY_ARB
:
1575 if (ctx
&& !ctx
->Extensions
.ARB_texture_compression
) {
1576 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1577 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1580 internalFormat
= GL_INTENSITY
;
1582 case GL_COMPRESSED_RGB_ARB
:
1583 if (ctx
&& !ctx
->Extensions
.ARB_texture_compression
) {
1584 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1585 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1588 internalFormat
= GL_RGB
;
1590 case GL_COMPRESSED_RGBA_ARB
:
1591 if (ctx
&& !ctx
->Extensions
.ARB_texture_compression
) {
1592 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1593 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1596 internalFormat
= GL_RGBA
;
1599 /* silence compiler warning */
1602 return internalFormat
;
1607 * Called from the API. Note that width includes the border.
1610 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
1611 GLsizei width
, GLint border
, GLenum format
,
1612 GLenum type
, const GLvoid
*pixels
)
1614 GLsizei postConvWidth
= width
;
1615 GET_CURRENT_CONTEXT(ctx
);
1616 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1618 adjust_texture_size_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1620 if (target
==GL_TEXTURE_1D
) {
1621 struct gl_texture_unit
*texUnit
;
1622 struct gl_texture_object
*texObj
;
1623 struct gl_texture_image
*texImage
;
1626 ifmt
= get_specific_compressed_tex_format(ctx
, internalFormat
, 1,
1629 &border
, &format
, &type
);
1632 * The error here is that we were sent a generic compressed
1633 * format, but the extension is not supported.
1638 internalFormat
= ifmt
;
1641 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1642 format
, type
, 1, postConvWidth
, 1, 1, border
)) {
1643 return; /* error in texture image was detected */
1646 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1647 texObj
= texUnit
->Current1D
;
1648 texImage
= texObj
->Image
[level
];
1651 texImage
= _mesa_alloc_texture_image();
1652 texObj
->Image
[level
] = texImage
;
1654 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
1658 else if (texImage
->Data
) {
1659 FREE(texImage
->Data
);
1660 texImage
->Data
= NULL
;
1663 /* setup the teximage struct's fields */
1664 init_texture_image(ctx
, texImage
, postConvWidth
, 1, 1, border
, internalFormat
);
1666 if (ctx
->NewState
& _NEW_PIXEL
)
1667 gl_update_state(ctx
);
1669 /* process the texture image */
1671 GLboolean retain
= GL_TRUE
;
1672 GLboolean success
= GL_FALSE
;
1673 if (!ctx
->_ImageTransferState
&& ctx
->Driver
.TexImage1D
) {
1674 /* let device driver try to use raw image */
1675 success
= (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, format
,
1676 type
, pixels
, &ctx
->Unpack
,
1677 texObj
, texImage
, &retain
);
1679 if (retain
|| !success
) {
1680 /* make internal copy of the texture image */
1681 make_texture_image(ctx
, 1, texImage
, width
, 1, 1,
1682 format
, type
, pixels
, &ctx
->Unpack
);
1683 if (!success
&& ctx
->Driver
.TexImage1D
) {
1684 /* let device driver try to use unpacked image */
1685 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
1686 GL_UNSIGNED_BYTE
, texImage
->Data
,
1687 &_mesa_native_packing
,
1688 texObj
, texImage
, &retain
);
1691 if (!retain
&& texImage
->Data
) {
1692 FREE(texImage
->Data
);
1693 texImage
->Data
= NULL
;
1697 make_null_texture(texImage
);
1698 if (ctx
->Driver
.TexImage1D
) {
1700 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
1701 GL_UNSIGNED_BYTE
, texImage
->Data
,
1702 &_mesa_native_packing
,
1703 texObj
, texImage
, &retain
);
1708 texObj
->Complete
= GL_FALSE
;
1709 ctx
->NewState
|= _NEW_TEXTURE
;
1711 else if (target
== GL_PROXY_TEXTURE_1D
) {
1712 /* Proxy texture: check for errors and update proxy state */
1713 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1714 format
, type
, 1, width
, 1, 1, border
);
1715 if (!error
&& ctx
->Driver
.TestProxyTexImage
) {
1716 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1717 internalFormat
, format
, type
,
1718 width
, 1, 1, border
);
1721 /* if error, clear all proxy texture image parameters */
1722 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1723 clear_proxy_teximage(ctx
->Texture
.Proxy1D
->Image
[level
]);
1727 /* if no error, update proxy texture image parameters */
1728 init_texture_image(ctx
, ctx
->Texture
.Proxy1D
->Image
[level
],
1729 width
, 1, 1, border
, internalFormat
);
1733 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1740 _mesa_TexImage2D( GLenum target
, GLint level
, GLint internalFormat
,
1741 GLsizei width
, GLsizei height
, GLint border
,
1742 GLenum format
, GLenum type
,
1743 const GLvoid
*pixels
)
1745 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1746 GET_CURRENT_CONTEXT(ctx
);
1747 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1749 adjust_texture_size_for_convolution(ctx
, 2, &postConvWidth
,&postConvHeight
);
1751 if (target
==GL_TEXTURE_2D
||
1752 (ctx
->Extensions
.ARB_texture_cube_map
&&
1753 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1754 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
1755 struct gl_texture_unit
*texUnit
;
1756 struct gl_texture_object
*texObj
;
1757 struct gl_texture_image
*texImage
;
1760 ifmt
= get_specific_compressed_tex_format(ctx
, internalFormat
, 2,
1763 &border
, &format
, &type
);
1766 * The error here is that we were sent a generic compressed
1767 * format, but the extension is not supported.
1772 internalFormat
= ifmt
;
1775 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1776 format
, type
, 2, postConvWidth
, postConvHeight
,
1778 return; /* error in texture image was detected */
1781 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1782 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1783 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1786 texImage
= _mesa_alloc_texture_image();
1787 set_tex_image(texObj
, target
, level
, texImage
);
1788 /*texObj->Image[level] = texImage;*/
1790 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1794 else if (texImage
->Data
) {
1795 FREE(texImage
->Data
);
1796 texImage
->Data
= NULL
;
1799 /* setup the teximage struct's fields */
1800 init_texture_image(ctx
, texImage
, postConvWidth
, postConvHeight
,
1801 1, border
, internalFormat
);
1803 if (ctx
->NewState
& _NEW_PIXEL
)
1804 gl_update_state(ctx
);
1806 /* process the texture image */
1808 GLboolean retain
= GL_TRUE
;
1809 GLboolean success
= GL_FALSE
;
1810 if (!ctx
->_ImageTransferState
&& ctx
->Driver
.TexImage2D
) {
1811 /* let device driver try to use raw image */
1812 success
= (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, format
,
1813 type
, pixels
, &ctx
->Unpack
,
1814 texObj
, texImage
, &retain
);
1816 if (retain
|| !success
) {
1817 /* make internal copy of the texture image */
1818 make_texture_image(ctx
, 2, texImage
, width
, height
, 1,
1819 format
, type
, pixels
, &ctx
->Unpack
);
1820 if (!success
&& ctx
->Driver
.TexImage2D
) {
1821 /* let device driver try to use unpacked image */
1822 (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, texImage
->Format
,
1823 GL_UNSIGNED_BYTE
, texImage
->Data
,
1824 &_mesa_native_packing
,
1825 texObj
, texImage
, &retain
);
1828 if (!retain
&& texImage
->Data
) {
1829 FREE(texImage
->Data
);
1830 texImage
->Data
= NULL
;
1834 make_null_texture(texImage
);
1835 if (ctx
->Driver
.TexImage2D
) {
1837 (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, texImage
->Format
,
1838 GL_UNSIGNED_BYTE
, texImage
->Data
,
1839 &_mesa_native_packing
,
1840 texObj
, texImage
, &retain
);
1845 texObj
->Complete
= GL_FALSE
;
1846 ctx
->NewState
|= _NEW_TEXTURE
;
1848 else if (target
== GL_PROXY_TEXTURE_2D
) {
1849 /* Proxy texture: check for errors and update proxy state */
1850 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1851 format
, type
, 2, width
, height
, 1, border
);
1852 if (!error
&& ctx
->Driver
.TestProxyTexImage
) {
1853 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1854 internalFormat
, format
, type
,
1855 width
, height
, 1, border
);
1858 /* if error, clear all proxy texture image parameters */
1859 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1860 clear_proxy_teximage(ctx
->Texture
.Proxy2D
->Image
[level
]);
1864 /* if no error, update proxy texture image parameters */
1865 init_texture_image(ctx
,
1866 ctx
->Texture
.Proxy2D
->Image
[level
],
1867 width
, height
, 1, border
, internalFormat
);
1871 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1878 * Called by the API or display list executor.
1879 * Note that width and height include the border.
1882 _mesa_TexImage3D( GLenum target
, GLint level
, GLint internalFormat
,
1883 GLsizei width
, GLsizei height
, GLsizei depth
,
1884 GLint border
, GLenum format
, GLenum type
,
1885 const GLvoid
*pixels
)
1887 GET_CURRENT_CONTEXT(ctx
);
1888 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1890 if (target
==GL_TEXTURE_3D_EXT
) {
1891 struct gl_texture_unit
*texUnit
;
1892 struct gl_texture_object
*texObj
;
1893 struct gl_texture_image
*texImage
;
1896 ifmt
= get_specific_compressed_tex_format(ctx
, internalFormat
, 3,
1898 &width
, &height
, &depth
,
1899 &border
, &format
, &type
);
1902 * The error here is that we were sent a generic compressed
1903 * format, but the extension is not supported.
1908 internalFormat
= ifmt
;
1911 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1912 format
, type
, 3, width
, height
, depth
, border
)) {
1913 return; /* error in texture image was detected */
1916 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1917 texObj
= texUnit
->Current3D
;
1918 texImage
= texObj
->Image
[level
];
1921 texImage
= _mesa_alloc_texture_image();
1922 texObj
->Image
[level
] = texImage
;
1924 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
1928 else if (texImage
->Data
) {
1929 FREE(texImage
->Data
);
1930 texImage
->Data
= NULL
;
1933 /* setup the teximage struct's fields */
1934 init_texture_image(ctx
, texImage
, width
, height
, depth
,
1935 border
, internalFormat
);
1937 if (ctx
->NewState
& _NEW_PIXEL
)
1938 gl_update_state(ctx
);
1940 /* process the texture image */
1942 GLboolean retain
= GL_TRUE
;
1943 GLboolean success
= GL_FALSE
;
1944 if (!ctx
->_ImageTransferState
&& ctx
->Driver
.TexImage3D
) {
1945 /* let device driver try to use raw image */
1946 success
= (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, format
,
1947 type
, pixels
, &ctx
->Unpack
,
1948 texObj
, texImage
, &retain
);
1950 if (retain
|| !success
) {
1951 /* make internal copy of the texture image */
1952 make_texture_image(ctx
, 3, texImage
, width
, height
, depth
,
1953 format
, type
, pixels
, &ctx
->Unpack
);
1954 if (!success
&& ctx
->Driver
.TexImage3D
) {
1955 /* let device driver try to use unpacked image */
1956 (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, texImage
->Format
,
1957 GL_UNSIGNED_BYTE
, texImage
->Data
,
1958 &_mesa_native_packing
,
1959 texObj
, texImage
, &retain
);
1962 if (!retain
&& texImage
->Data
) {
1963 FREE(texImage
->Data
);
1964 texImage
->Data
= NULL
;
1968 make_null_texture(texImage
);
1969 if (ctx
->Driver
.TexImage3D
) {
1971 (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, texImage
->Format
,
1972 GL_UNSIGNED_BYTE
, texImage
->Data
,
1973 &_mesa_native_packing
,
1974 texObj
, texImage
, &retain
);
1979 texObj
->Complete
= GL_FALSE
;
1980 ctx
->NewState
|= _NEW_TEXTURE
;
1982 else if (target
== GL_PROXY_TEXTURE_3D
) {
1983 /* Proxy texture: check for errors and update proxy state */
1984 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1985 format
, type
, 3, width
, height
, depth
, border
);
1986 if (!error
&& ctx
->Driver
.TestProxyTexImage
) {
1987 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1988 internalFormat
, format
, type
,
1989 width
, height
, depth
, border
);
1992 /* if error, clear all proxy texture image parameters */
1993 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1994 clear_proxy_teximage(ctx
->Texture
.Proxy3D
->Image
[level
]);
1998 /* if no error, update proxy texture image parameters */
1999 init_texture_image(ctx
, ctx
->Texture
.Proxy3D
->Image
[level
],
2000 width
, height
, depth
, border
, internalFormat
);
2004 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
2011 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
2012 GLsizei width
, GLsizei height
, GLsizei depth
,
2013 GLint border
, GLenum format
, GLenum type
,
2014 const GLvoid
*pixels
)
2016 _mesa_TexImage3D(target
, level
, (GLint
) internalFormat
, width
, height
,
2017 depth
, border
, format
, type
, pixels
);
2022 * Fetch a texture image from the device driver.
2023 * Store the results in the given texture object at the given mipmap level.
2026 _mesa_get_teximage_from_driver( GLcontext
*ctx
, GLenum target
, GLint level
,
2027 const struct gl_texture_object
*texObj
)
2030 GLenum imgFormat
, imgType
;
2031 GLboolean freeImage
;
2032 struct gl_texture_image
*texImage
;
2033 GLint destComponents
, numPixels
, srcBytesPerTexel
;
2035 if (!ctx
->Driver
.GetTexImage
)
2038 image
= (*ctx
->Driver
.GetTexImage
)( ctx
, target
, level
, texObj
,
2039 &imgFormat
, &imgType
, &freeImage
);
2043 texImage
= texObj
->Image
[level
];
2048 destComponents
= components_in_intformat(texImage
->Format
);
2049 assert(destComponents
> 0);
2050 numPixels
= texImage
->Width
* texImage
->Height
* texImage
->Depth
;
2051 assert(numPixels
> 0);
2052 srcBytesPerTexel
= _mesa_bytes_per_pixel(imgFormat
, imgType
);
2053 assert(srcBytesPerTexel
> 0);
2055 if (!texImage
->Data
) {
2056 /* Allocate memory for the texture image data */
2057 texImage
->Data
= (GLchan
*) MALLOC(numPixels
* destComponents
2058 * sizeof(GLchan
) + EXTRA_BYTE
);
2061 if (imgFormat
== texImage
->Format
&& imgType
== GL_UNSIGNED_BYTE
) {
2062 /* We got lucky! The driver's format and type match Mesa's format. */
2063 if (texImage
->Data
) {
2064 MEMCPY(texImage
->Data
, image
, numPixels
* destComponents
);
2068 /* Convert the texture image from the driver's format to Mesa's
2071 const GLint width
= texImage
->Width
;
2072 const GLint height
= texImage
->Height
;
2073 const GLint depth
= texImage
->Depth
;
2074 const GLint destBytesPerRow
= width
* destComponents
* sizeof(GLchan
);
2075 const GLint srcBytesPerRow
= width
* srcBytesPerTexel
;
2076 const GLenum dstType
= GL_UNSIGNED_BYTE
;
2077 const GLenum dstFormat
= texImage
->Format
;
2078 const GLchan
*srcPtr
= (const GLchan
*) image
;
2079 GLchan
*destPtr
= texImage
->Data
;
2081 if (texImage
->Format
== GL_COLOR_INDEX
) {
2082 /* color index texture */
2084 assert(imgFormat
== GL_COLOR_INDEX
);
2085 for (img
= 0; img
< depth
; img
++) {
2086 for (row
= 0; row
< height
; row
++) {
2087 _mesa_unpack_index_span(ctx
, width
, dstType
, destPtr
,
2088 imgType
, srcPtr
, &_mesa_native_packing
, GL_FALSE
);
2089 destPtr
+= destBytesPerRow
;
2090 srcPtr
+= srcBytesPerRow
;
2097 for (img
= 0; img
< depth
; img
++) {
2098 for (row
= 0; row
< height
; row
++) {
2099 _mesa_unpack_chan_color_span(ctx
, width
, dstFormat
, destPtr
,
2100 imgFormat
, imgType
, srcPtr
, &_mesa_native_packing
, GL_FALSE
);
2101 destPtr
+= destBytesPerRow
;
2102 srcPtr
+= srcBytesPerRow
;
2114 * Get all the mipmap images for a texture object from the device driver.
2115 * Actually, only get mipmap images if we're using a mipmap filter.
2118 _mesa_get_teximages_from_driver(GLcontext
*ctx
,
2119 struct gl_texture_object
*texObj
)
2121 if (ctx
->Driver
.GetTexImage
) {
2122 static const GLenum targets
[] = {
2126 GL_TEXTURE_CUBE_MAP_ARB
,
2127 GL_TEXTURE_CUBE_MAP_ARB
,
2128 GL_TEXTURE_CUBE_MAP_ARB
2130 GLboolean needLambda
= (texObj
->MinFilter
!= texObj
->MagFilter
);
2131 GLenum target
= targets
[texObj
->Dimensions
- 1];
2134 /* Get images for all mipmap levels. We might not need them
2135 * all but this is easier. We're on a (slow) software path
2138 for (level
= texObj
->BaseLevel
; level
<= texObj
->_MaxLevel
; level
++) {
2139 struct gl_texture_image
*texImg
= texObj
->Image
[level
];
2140 if (texImg
&& !texImg
->Data
) {
2141 _mesa_get_teximage_from_driver(ctx
, target
, level
, texObj
);
2143 return GL_FALSE
; /* out of memory */
2148 GLint level
= texObj
->BaseLevel
;
2149 struct gl_texture_image
*texImg
= texObj
->Image
[level
];
2150 if (texImg
&& !texImg
->Data
) {
2151 _mesa_get_teximage_from_driver(ctx
, target
, level
, texObj
);
2153 return GL_FALSE
; /* out of memory */
2164 _mesa_GetTexImage( GLenum target
, GLint level
, GLenum format
,
2165 GLenum type
, GLvoid
*pixels
)
2167 GET_CURRENT_CONTEXT(ctx
);
2168 const struct gl_texture_unit
*texUnit
;
2169 const struct gl_texture_object
*texObj
;
2170 struct gl_texture_image
*texImage
;
2171 GLboolean discardImage
;
2173 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2175 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
2176 gl_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
2180 if (_mesa_sizeof_type(type
) <= 0) {
2181 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
2185 if (_mesa_components_in_format(format
) <= 0) {
2186 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
2193 texUnit
= &(ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
]);
2194 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2196 target
== GL_PROXY_TEXTURE_1D
||
2197 target
== GL_PROXY_TEXTURE_2D
||
2198 target
== GL_PROXY_TEXTURE_3D
) {
2199 gl_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)");
2203 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2205 /* invalid mipmap level, not an error */
2209 if (!texImage
->Data
) {
2210 /* try to get the texture image from the device driver */
2211 _mesa_get_teximage_from_driver(ctx
, target
, level
, texObj
);
2212 discardImage
= GL_TRUE
;
2215 discardImage
= GL_FALSE
;
2218 if (texImage
->Data
) {
2219 GLint width
= texImage
->Width
;
2220 GLint height
= texImage
->Height
;
2221 GLint depth
= texImage
->Depth
;
2224 if (ctx
->NewState
& _NEW_PIXEL
)
2225 gl_update_state(ctx
);
2227 if (ctx
->_ImageTransferState
& IMAGE_CONVOLUTION_BIT
) {
2228 /* convert texture image to GL_RGBA, GL_FLOAT */
2229 GLfloat
*tmpImage
, *convImage
;
2230 const GLint comps
= components_in_intformat(texImage
->Format
);
2232 tmpImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
2234 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
2237 convImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
2240 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
2244 for (img
= 0; img
< depth
; img
++) {
2245 GLint convWidth
, convHeight
;
2247 /* convert to GL_RGBA */
2248 for (row
= 0; row
< height
; row
++) {
2249 const GLchan
*src
= texImage
->Data
2250 + (img
* height
+ row
) * width
* comps
;
2251 GLfloat
*dst
= tmpImage
+ row
* width
* 4;
2252 _mesa_unpack_float_color_span(ctx
, width
, GL_RGBA
, dst
,
2253 texImage
->Format
, GL_UNSIGNED_BYTE
,
2254 src
, &_mesa_native_packing
,
2255 ctx
->_ImageTransferState
& IMAGE_PRE_CONVOLUTION_BITS
,
2260 convHeight
= height
;
2263 if (target
== GL_TEXTURE_1D
) {
2264 if (ctx
->Pixel
.Convolution1DEnabled
) {
2265 _mesa_convolve_1d_image(ctx
, &convWidth
, tmpImage
, convImage
);
2269 if (ctx
->Pixel
.Convolution2DEnabled
) {
2270 _mesa_convolve_2d_image(ctx
, &convWidth
, &convHeight
,
2271 tmpImage
, convImage
);
2273 else if (ctx
->Pixel
.Separable2DEnabled
) {
2274 _mesa_convolve_sep_image(ctx
, &convWidth
, &convHeight
,
2275 tmpImage
, convImage
);
2279 /* pack convolved image */
2280 for (row
= 0; row
< convHeight
; row
++) {
2281 const GLfloat
*src
= convImage
+ row
* convWidth
* 4;
2282 GLvoid
*dest
= _mesa_image_address(&ctx
->Pack
, pixels
,
2283 convWidth
, convHeight
,
2284 format
, type
, img
, row
, 0);
2285 _mesa_pack_float_rgba_span(ctx
, convWidth
,
2286 (const GLfloat(*)[4]) src
,
2287 format
, type
, dest
, &ctx
->Pack
,
2288 ctx
->_ImageTransferState
& IMAGE_POST_CONVOLUTION_BITS
);
2296 /* no convolution */
2297 for (img
= 0; img
< depth
; img
++) {
2298 for (row
= 0; row
< height
; row
++) {
2299 /* compute destination address in client memory */
2300 GLvoid
*dest
= _mesa_image_address( &ctx
->Unpack
, pixels
,
2301 width
, height
, format
, type
, img
, row
, 0);
2303 if (texImage
->Format
== GL_RGBA
) {
2305 const GLchan
*src
= texImage
->Data
2306 + (img
* height
+ row
) * width
* 4;
2307 _mesa_pack_rgba_span( ctx
, width
, (CONST
GLchan (*)[4]) src
,
2308 format
, type
, dest
, &ctx
->Pack
,
2309 ctx
->_ImageTransferState
);
2312 /* general case: convert row to RGBA format */
2313 GLchan rgba
[MAX_WIDTH
][4];
2316 switch (texImage
->Format
) {
2318 src
= texImage
->Data
+ row
* width
;
2319 for (i
= 0; i
< width
; i
++) {
2320 rgba
[i
][RCOMP
] = CHAN_MAX
;
2321 rgba
[i
][GCOMP
] = CHAN_MAX
;
2322 rgba
[i
][BCOMP
] = CHAN_MAX
;
2323 rgba
[i
][ACOMP
] = src
[i
];
2327 src
= texImage
->Data
+ row
* width
;
2328 for (i
= 0; i
< width
; i
++) {
2329 rgba
[i
][RCOMP
] = src
[i
];
2330 rgba
[i
][GCOMP
] = src
[i
];
2331 rgba
[i
][BCOMP
] = src
[i
];
2332 rgba
[i
][ACOMP
] = CHAN_MAX
;
2335 case GL_LUMINANCE_ALPHA
:
2336 src
= texImage
->Data
+ row
* 2 * width
;
2337 for (i
= 0; i
< width
; i
++) {
2338 rgba
[i
][RCOMP
] = src
[i
*2+0];
2339 rgba
[i
][GCOMP
] = src
[i
*2+0];
2340 rgba
[i
][BCOMP
] = src
[i
*2+0];
2341 rgba
[i
][ACOMP
] = src
[i
*2+1];
2345 src
= texImage
->Data
+ row
* width
;
2346 for (i
= 0; i
< width
; i
++) {
2347 rgba
[i
][RCOMP
] = src
[i
];
2348 rgba
[i
][GCOMP
] = src
[i
];
2349 rgba
[i
][BCOMP
] = src
[i
];
2350 rgba
[i
][ACOMP
] = CHAN_MAX
;
2354 src
= texImage
->Data
+ row
* 3 * width
;
2355 for (i
= 0; i
< width
; i
++) {
2356 rgba
[i
][RCOMP
] = src
[i
*3+0];
2357 rgba
[i
][GCOMP
] = src
[i
*3+1];
2358 rgba
[i
][BCOMP
] = src
[i
*3+2];
2359 rgba
[i
][ACOMP
] = CHAN_MAX
;
2362 case GL_COLOR_INDEX
:
2363 gl_problem( ctx
, "GL_COLOR_INDEX not implemented in gl_GetTexImage" );
2367 gl_problem( ctx
, "bad format in gl_GetTexImage" );
2369 _mesa_pack_rgba_span( ctx
, width
, (const GLchan (*)[4])rgba
,
2370 format
, type
, dest
, &ctx
->Pack
,
2371 ctx
->_ImageTransferState
);
2377 /* if we got the teximage from the device driver we'll discard it now */
2379 FREE(texImage
->Data
);
2380 texImage
->Data
= NULL
;
2388 _mesa_TexSubImage1D( GLenum target
, GLint level
,
2389 GLint xoffset
, GLsizei width
,
2390 GLenum format
, GLenum type
,
2391 const GLvoid
*pixels
)
2393 GLsizei postConvWidth
= width
;
2394 GET_CURRENT_CONTEXT(ctx
);
2395 struct gl_texture_unit
*texUnit
;
2396 struct gl_texture_object
*texObj
;
2397 struct gl_texture_image
*texImage
;
2398 GLboolean success
= GL_FALSE
;
2400 adjust_texture_size_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
2402 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
2403 postConvWidth
, 1, 1, format
, type
)) {
2404 return; /* error was detected */
2407 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2408 texObj
= texUnit
->Current1D
;
2409 texImage
= texObj
->Image
[level
];
2412 if (width
== 0 || !pixels
)
2413 return; /* no-op, not an error */
2415 if (ctx
->NewState
& _NEW_PIXEL
)
2416 gl_update_state(ctx
);
2418 if (!ctx
->_ImageTransferState
&& ctx
->Driver
.TexSubImage1D
) {
2419 success
= (*ctx
->Driver
.TexSubImage1D
)( ctx
, target
, level
, xoffset
,
2420 width
, format
, type
, pixels
,
2421 &ctx
->Unpack
, texObj
, texImage
);
2424 /* XXX if Driver.TexSubImage1D, unpack image and try again? */
2425 GLboolean retain
= GL_TRUE
;
2426 if (!texImage
->Data
) {
2427 _mesa_get_teximage_from_driver( ctx
, target
, level
, texObj
);
2428 if (!texImage
->Data
) {
2429 make_null_texture(texImage
);
2431 if (!texImage
->Data
)
2432 return; /* we're really out of luck! */
2435 fill_texture_image(ctx
, 1, texImage
->Format
, texImage
->Data
,
2436 width
, 1, 1, xoffset
+ texImage
->Border
, 0, 0, /* size and offsets */
2438 format
, type
, pixels
, &ctx
->Unpack
);
2440 if (ctx
->Driver
.TexImage1D
) {
2441 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
2442 GL_UNSIGNED_BYTE
, texImage
->Data
,
2443 &_mesa_native_packing
, texObj
, texImage
,
2447 if (!retain
&& texImage
->Data
) {
2448 FREE(texImage
->Data
);
2449 texImage
->Data
= NULL
;
2456 _mesa_TexSubImage2D( GLenum target
, GLint level
,
2457 GLint xoffset
, GLint yoffset
,
2458 GLsizei width
, GLsizei height
,
2459 GLenum format
, GLenum type
,
2460 const GLvoid
*pixels
)
2462 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2463 GET_CURRENT_CONTEXT(ctx
);
2464 struct gl_texture_unit
*texUnit
;
2465 struct gl_texture_object
*texObj
;
2466 struct gl_texture_image
*texImage
;
2467 GLboolean success
= GL_FALSE
;
2469 adjust_texture_size_for_convolution(ctx
, 2, &postConvWidth
,&postConvHeight
);
2471 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2472 postConvWidth
, postConvHeight
, 1, format
, type
)) {
2473 return; /* error was detected */
2476 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2477 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2478 texImage
= texObj
->Image
[level
];
2481 if (width
== 0 || height
== 0 || !pixels
)
2482 return; /* no-op, not an error */
2484 if (ctx
->NewState
& _NEW_PIXEL
)
2485 gl_update_state(ctx
);
2487 if (!ctx
->_ImageTransferState
&& ctx
->Driver
.TexSubImage2D
) {
2488 success
= (*ctx
->Driver
.TexSubImage2D
)( ctx
, target
, level
, xoffset
,
2489 yoffset
, width
, height
, format
, type
,
2490 pixels
, &ctx
->Unpack
, texObj
, texImage
);
2493 /* XXX if Driver.TexSubImage2D, unpack image and try again? */
2494 const GLint texComps
= components_in_intformat(texImage
->Format
);
2495 const GLint texRowStride
= texImage
->Width
* texComps
;
2496 GLboolean retain
= GL_TRUE
;
2498 if (!texImage
->Data
) {
2499 _mesa_get_teximage_from_driver( ctx
, target
, level
, texObj
);
2500 if (!texImage
->Data
) {
2501 make_null_texture(texImage
);
2503 if (!texImage
->Data
)
2504 return; /* we're really out of luck! */
2507 fill_texture_image(ctx
, 2, texImage
->Format
, texImage
->Data
,
2508 width
, height
, 1, xoffset
+ texImage
->Border
,
2509 yoffset
+ texImage
->Border
, 0, texRowStride
, 0,
2510 format
, type
, pixels
, &ctx
->Unpack
);
2512 if (ctx
->Driver
.TexImage2D
) {
2513 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, texImage
->Format
,
2514 GL_UNSIGNED_BYTE
, texImage
->Data
,
2515 &_mesa_native_packing
, texObj
, texImage
,
2519 if (!retain
&& texImage
->Data
) {
2520 FREE(texImage
->Data
);
2521 texImage
->Data
= NULL
;
2529 _mesa_TexSubImage3D( GLenum target
, GLint level
,
2530 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2531 GLsizei width
, GLsizei height
, GLsizei depth
,
2532 GLenum format
, GLenum type
,
2533 const GLvoid
*pixels
)
2535 GET_CURRENT_CONTEXT(ctx
);
2536 struct gl_texture_unit
*texUnit
;
2537 struct gl_texture_object
*texObj
;
2538 struct gl_texture_image
*texImage
;
2539 GLboolean success
= GL_FALSE
;
2541 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2542 width
, height
, depth
, format
, type
)) {
2543 return; /* error was detected */
2546 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2547 texObj
= texUnit
->Current3D
;
2548 texImage
= texObj
->Image
[level
];
2551 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
2552 return; /* no-op, not an error */
2554 if (ctx
->NewState
& _NEW_PIXEL
)
2555 gl_update_state(ctx
);
2557 if (!ctx
->_ImageTransferState
&& ctx
->Driver
.TexSubImage3D
) {
2558 success
= (*ctx
->Driver
.TexSubImage3D
)( ctx
, target
, level
, xoffset
,
2559 yoffset
, zoffset
, width
, height
, depth
, format
,
2560 type
, pixels
, &ctx
->Unpack
, texObj
, texImage
);
2563 /* XXX if Driver.TexSubImage3D, unpack image and try again? */
2564 const GLint texComps
= components_in_intformat(texImage
->Format
);
2565 const GLint texRowStride
= texImage
->Width
* texComps
;
2566 const GLint texImgStride
= texRowStride
* texImage
->Height
;
2567 GLboolean retain
= GL_TRUE
;
2569 if (!texImage
->Data
) {
2570 _mesa_get_teximage_from_driver( ctx
, target
, level
, texObj
);
2571 if (!texImage
->Data
) {
2572 make_null_texture(texImage
);
2574 if (!texImage
->Data
)
2575 return; /* we're really out of luck! */
2578 fill_texture_image(ctx
, 3, texImage
->Format
, texImage
->Data
,
2579 width
, height
, depth
, xoffset
+ texImage
->Border
,
2580 yoffset
+ texImage
->Border
,
2581 zoffset
+ texImage
->Border
, texRowStride
,
2582 texImgStride
, format
, type
, pixels
, &ctx
->Unpack
);
2584 if (ctx
->Driver
.TexImage3D
) {
2585 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, texImage
->Format
,
2586 GL_UNSIGNED_BYTE
, texImage
->Data
,
2587 &_mesa_native_packing
, texObj
, texImage
,
2591 if (!retain
&& texImage
->Data
) {
2592 FREE(texImage
->Data
);
2593 texImage
->Data
= NULL
;
2601 * Read an RGBA image from the frame buffer.
2602 * This is used by glCopyTex[Sub]Image[12]D().
2603 * Input: ctx - the context
2604 * x, y - lower left corner
2605 * width, height - size of region to read
2606 * Return: pointer to block of GL_RGBA, GLchan data.
2609 read_color_image( GLcontext
*ctx
, GLint x
, GLint y
,
2610 GLsizei width
, GLsizei height
)
2613 GLchan
*image
, *dst
;
2615 image
= (GLchan
*) MALLOC(width
* height
* 4 * sizeof(GLchan
));
2619 /* Select buffer to read from */
2620 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->ReadBuffer
,
2621 ctx
->Pixel
.DriverReadBuffer
);
2627 for (i
= 0; i
< height
; i
++) {
2628 gl_read_rgba_span( ctx
, ctx
->ReadBuffer
, width
, x
, y
+ i
,
2629 (GLchan (*)[4]) dst
);
2635 /* Read from draw buffer (the default) */
2636 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->DrawBuffer
,
2637 ctx
->Color
.DriverDrawBuffer
);
2645 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
2646 GLenum internalFormat
,
2648 GLsizei width
, GLint border
)
2650 GLsizei postConvWidth
= width
;
2651 GET_CURRENT_CONTEXT(ctx
);
2652 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2654 if (ctx
->NewState
& _NEW_PIXEL
)
2655 gl_update_state(ctx
);
2657 adjust_texture_size_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
2659 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
2660 postConvWidth
, 1, border
))
2663 if (ctx
->_ImageTransferState
|| !ctx
->Driver
.CopyTexImage1D
2664 || !(*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
,
2665 internalFormat
, x
, y
, width
, border
)) {
2666 struct gl_pixelstore_attrib unpackSave
;
2668 /* get image from framebuffer */
2669 GLchan
*image
= read_color_image( ctx
, x
, y
, width
, 1 );
2671 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D" );
2675 /* call glTexImage1D to redefine the texture */
2676 unpackSave
= ctx
->Unpack
;
2677 ctx
->Unpack
= _mesa_native_packing
;
2678 (*ctx
->Exec
->TexImage1D
)( target
, level
, internalFormat
, width
,
2679 border
, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2680 ctx
->Unpack
= unpackSave
;
2689 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
2690 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
2693 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2694 GET_CURRENT_CONTEXT(ctx
);
2695 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2697 if (ctx
->NewState
& _NEW_PIXEL
)
2698 gl_update_state(ctx
);
2700 adjust_texture_size_for_convolution(ctx
, 2, &postConvWidth
,&postConvHeight
);
2702 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
2703 postConvWidth
, postConvHeight
, border
))
2706 if (ctx
->_ImageTransferState
|| !ctx
->Driver
.CopyTexImage2D
2707 || !(*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
,
2708 internalFormat
, x
, y
, width
, height
, border
)) {
2709 struct gl_pixelstore_attrib unpackSave
;
2711 /* get image from framebuffer */
2712 GLchan
*image
= read_color_image( ctx
, x
, y
, width
, height
);
2714 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D" );
2718 /* call glTexImage2D to redefine the texture */
2719 unpackSave
= ctx
->Unpack
;
2720 ctx
->Unpack
= _mesa_native_packing
;
2721 (ctx
->Exec
->TexImage2D
)( target
, level
, internalFormat
, width
,
2722 height
, border
, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2723 ctx
->Unpack
= unpackSave
;
2732 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
2733 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
2735 GLsizei postConvWidth
= width
;
2736 GET_CURRENT_CONTEXT(ctx
);
2737 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2739 if (ctx
->NewState
& _NEW_PIXEL
)
2740 gl_update_state(ctx
);
2742 adjust_texture_size_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
2744 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
2745 xoffset
, 0, 0, postConvWidth
, 1))
2748 if (ctx
->_ImageTransferState
|| !ctx
->Driver
.CopyTexSubImage1D
2749 || !(*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
,
2750 xoffset
, x
, y
, width
)) {
2751 struct gl_texture_unit
*texUnit
;
2752 struct gl_texture_image
*teximage
;
2753 struct gl_pixelstore_attrib unpackSave
;
2756 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2757 teximage
= texUnit
->Current1D
->Image
[level
];
2760 /* get image from frame buffer */
2761 image
= read_color_image(ctx
, x
, y
, width
, 1);
2763 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage1D" );
2767 /* now call glTexSubImage1D to do the real work */
2768 unpackSave
= ctx
->Unpack
;
2769 ctx
->Unpack
= _mesa_native_packing
;
2770 _mesa_TexSubImage1D(target
, level
, xoffset
, width
,
2771 GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2772 ctx
->Unpack
= unpackSave
;
2781 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
2782 GLint xoffset
, GLint yoffset
,
2783 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2785 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2786 GET_CURRENT_CONTEXT(ctx
);
2787 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2789 if (ctx
->NewState
& _NEW_PIXEL
)
2790 gl_update_state(ctx
);
2792 adjust_texture_size_for_convolution(ctx
, 2, &postConvWidth
,&postConvHeight
);
2794 if (copytexsubimage_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2795 postConvWidth
, postConvHeight
))
2798 if (ctx
->_ImageTransferState
|| !ctx
->Driver
.CopyTexSubImage2D
2799 || !(*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
2800 xoffset
, yoffset
, x
, y
, width
, height
)) {
2801 struct gl_texture_unit
*texUnit
;
2802 struct gl_texture_image
*teximage
;
2803 struct gl_pixelstore_attrib unpackSave
;
2806 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2807 teximage
= texUnit
->Current2D
->Image
[level
];
2810 /* get image from frame buffer */
2811 image
= read_color_image(ctx
, x
, y
, width
, height
);
2813 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage2D" );
2817 /* now call glTexSubImage2D to do the real work */
2818 unpackSave
= ctx
->Unpack
;
2819 ctx
->Unpack
= _mesa_native_packing
;
2820 _mesa_TexSubImage2D(target
, level
, xoffset
, yoffset
, width
, height
,
2821 GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2822 ctx
->Unpack
= unpackSave
;
2831 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
2832 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2833 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2835 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2836 GET_CURRENT_CONTEXT(ctx
);
2837 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2839 if (ctx
->NewState
& _NEW_PIXEL
)
2840 gl_update_state(ctx
);
2842 adjust_texture_size_for_convolution(ctx
, 2, &postConvWidth
,&postConvHeight
);
2844 if (copytexsubimage_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
,
2845 zoffset
, postConvWidth
, postConvHeight
))
2848 if (ctx
->_ImageTransferState
|| !ctx
->Driver
.CopyTexSubImage3D
2849 || !(*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
2850 xoffset
, yoffset
, zoffset
, x
, y
, width
, height
)) {
2851 struct gl_texture_unit
*texUnit
;
2852 struct gl_texture_image
*teximage
;
2853 struct gl_pixelstore_attrib unpackSave
;
2856 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2857 teximage
= texUnit
->Current3D
->Image
[level
];
2860 /* get image from frame buffer */
2861 image
= read_color_image(ctx
, x
, y
, width
, height
);
2863 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage2D" );
2867 /* now call glTexSubImage2D to do the real work */
2868 unpackSave
= ctx
->Unpack
;
2869 ctx
->Unpack
= _mesa_native_packing
;
2870 _mesa_TexSubImage3D(target
, level
, xoffset
, yoffset
, zoffset
,
2871 width
, height
, 1, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2872 ctx
->Unpack
= unpackSave
;
2881 _mesa_CompressedTexImage1DARB(GLenum target
, GLint level
,
2882 GLenum internalFormat
, GLsizei width
,
2883 GLint border
, GLsizei imageSize
,
2886 GET_CURRENT_CONTEXT(ctx
);
2887 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2889 switch (internalFormat
) {
2890 case GL_COMPRESSED_ALPHA_ARB
:
2891 case GL_COMPRESSED_LUMINANCE_ARB
:
2892 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2893 case GL_COMPRESSED_INTENSITY_ARB
:
2894 case GL_COMPRESSED_RGB_ARB
:
2895 case GL_COMPRESSED_RGBA_ARB
:
2896 gl_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB");
2899 /* silence compiler warning */
2903 if (target
== GL_TEXTURE_1D
) {
2904 struct gl_texture_unit
*texUnit
;
2905 struct gl_texture_object
*texObj
;
2906 struct gl_texture_image
*texImage
;
2907 GLsizei computedImageSize
;
2909 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2910 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
2911 return; /* error in texture image was detected */
2914 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2915 texObj
= texUnit
->Current1D
;
2916 texImage
= texObj
->Image
[level
];
2919 texImage
= _mesa_alloc_texture_image();
2920 texObj
->Image
[level
] = texImage
;
2922 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage1DARB");
2926 else if (texImage
->Data
) {
2927 FREE(texImage
->Data
);
2928 texImage
->Data
= NULL
;
2931 /* setup the teximage struct's fields */
2932 init_texture_image(ctx
, texImage
, width
, 1, 1,
2933 border
, internalFormat
);
2935 /* process the texture image */
2937 GLboolean retain
= GL_TRUE
;
2938 GLboolean success
= GL_FALSE
;
2939 if (ctx
->Driver
.CompressedTexImage1D
) {
2940 success
= (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
,
2941 imageSize
, data
, texObj
, texImage
, &retain
);
2943 if (retain
|| !success
) {
2944 /* make internal copy of the texture image */
2945 computedImageSize
= _mesa_compressed_image_size(ctx
,
2951 if (computedImageSize
!= imageSize
) {
2952 gl_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexImage1DARB(imageSize)");
2955 texImage
->Data
= MALLOC(computedImageSize
);
2956 if (texImage
->Data
) {
2957 MEMCPY(texImage
->Data
, data
, computedImageSize
);
2960 if (!retain
&& texImage
->Data
) {
2961 FREE(texImage
->Data
);
2962 texImage
->Data
= NULL
;
2966 make_null_texture(texImage
);
2967 if (ctx
->Driver
.CompressedTexImage1D
) {
2969 (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
, 0,
2970 texImage
->Data
, texObj
,
2976 texObj
->Complete
= GL_FALSE
;
2977 ctx
->NewState
|= _NEW_TEXTURE
;
2979 else if (target
== GL_PROXY_TEXTURE_1D
) {
2980 /* Proxy texture: check for errors and update proxy state */
2981 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2982 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
);
2983 if (!error
&& ctx
->Driver
.TestProxyTexImage
) {
2984 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2985 internalFormat
, GL_NONE
, GL_NONE
,
2986 width
, 1, 1, border
);
2989 /* if error, clear all proxy texture image parameters */
2990 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
2991 clear_proxy_teximage(ctx
->Texture
.Proxy1D
->Image
[level
]);
2995 /* if no error, update proxy texture image parameters */
2996 init_texture_image(ctx
, ctx
->Texture
.Proxy1D
->Image
[level
],
2997 width
, 1, 1, border
, internalFormat
);
3001 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB(target)" );
3008 _mesa_CompressedTexImage2DARB(GLenum target
, GLint level
,
3009 GLenum internalFormat
, GLsizei width
,
3010 GLsizei height
, GLint border
, GLsizei imageSize
,
3013 GET_CURRENT_CONTEXT(ctx
);
3014 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
3016 switch (internalFormat
) {
3017 case GL_COMPRESSED_ALPHA_ARB
:
3018 case GL_COMPRESSED_LUMINANCE_ARB
:
3019 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
3020 case GL_COMPRESSED_INTENSITY_ARB
:
3021 case GL_COMPRESSED_RGB_ARB
:
3022 case GL_COMPRESSED_RGBA_ARB
:
3023 gl_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB");
3026 /* silence compiler warning */
3030 if (target
==GL_TEXTURE_2D
||
3031 (ctx
->Extensions
.ARB_texture_cube_map
&&
3032 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
3033 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
3034 struct gl_texture_unit
*texUnit
;
3035 struct gl_texture_object
*texObj
;
3036 struct gl_texture_image
*texImage
;
3037 GLsizei computedImageSize
;
3039 if (texture_error_check(ctx
, target
, level
, internalFormat
,
3040 GL_NONE
, GL_NONE
, 1, width
, height
, 1, border
)) {
3041 return; /* error in texture image was detected */
3044 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3045 texObj
= texUnit
->Current2D
;
3046 texImage
= texObj
->Image
[level
];
3049 texImage
= _mesa_alloc_texture_image();
3050 texObj
->Image
[level
] = texImage
;
3052 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
3056 else if (texImage
->Data
) {
3057 FREE(texImage
->Data
);
3058 texImage
->Data
= NULL
;
3061 /* setup the teximage struct's fields */
3062 init_texture_image(ctx
, texImage
, width
, height
, 1, border
, internalFormat
);
3064 /* process the texture image */
3066 GLboolean retain
= GL_TRUE
;
3067 GLboolean success
= GL_FALSE
;
3068 if (ctx
->Driver
.CompressedTexImage2D
) {
3069 success
= (*ctx
->Driver
.CompressedTexImage2D
)( ctx
,
3078 if (retain
|| !success
) {
3079 /* make internal copy of the texture image */
3080 computedImageSize
= _mesa_compressed_image_size(ctx
,
3086 if (computedImageSize
!= imageSize
) {
3087 gl_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexImage2DARB(imageSize)");
3090 texImage
->Data
= MALLOC(computedImageSize
);
3091 if (texImage
->Data
) {
3092 MEMCPY(texImage
->Data
, data
, computedImageSize
);
3095 if (!retain
&& texImage
->Data
) {
3096 FREE(texImage
->Data
);
3097 texImage
->Data
= NULL
;
3101 make_null_texture(texImage
);
3102 if (ctx
->Driver
.CompressedTexImage2D
) {
3104 (*ctx
->Driver
.CompressedTexImage2D
)( ctx
, target
, level
, 0,
3105 texImage
->Data
, texObj
,
3111 texObj
->Complete
= GL_FALSE
;
3112 ctx
->NewState
|= _NEW_TEXTURE
;
3114 else if (target
== GL_PROXY_TEXTURE_2D
) {
3115 /* Proxy texture: check for errors and update proxy state */
3116 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
3117 GL_NONE
, GL_NONE
, 2, width
, height
, 1, border
);
3118 if (!error
&& ctx
->Driver
.TestProxyTexImage
) {
3119 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
3120 internalFormat
, GL_NONE
, GL_NONE
,
3121 width
, height
, 1, border
);
3124 /* if error, clear all proxy texture image parameters */
3125 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
3126 clear_proxy_teximage(ctx
->Texture
.Proxy2D
->Image
[level
]);
3130 /* if no error, update proxy texture image parameters */
3131 init_texture_image(ctx
, ctx
->Texture
.Proxy2D
->Image
[level
],
3132 width
, 1, 1, border
, internalFormat
);
3136 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB(target)" );
3143 _mesa_CompressedTexImage3DARB(GLenum target
, GLint level
,
3144 GLenum internalFormat
, GLsizei width
,
3145 GLsizei height
, GLsizei depth
, GLint border
,
3146 GLsizei imageSize
, const GLvoid
*data
)
3148 GET_CURRENT_CONTEXT(ctx
);
3149 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
3151 switch (internalFormat
) {
3152 case GL_COMPRESSED_ALPHA_ARB
:
3153 case GL_COMPRESSED_LUMINANCE_ARB
:
3154 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
3155 case GL_COMPRESSED_INTENSITY_ARB
:
3156 case GL_COMPRESSED_RGB_ARB
:
3157 case GL_COMPRESSED_RGBA_ARB
:
3158 gl_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB");
3161 /* silence compiler warning */
3165 if (target
== GL_TEXTURE_3D
) {
3166 struct gl_texture_unit
*texUnit
;
3167 struct gl_texture_object
*texObj
;
3168 struct gl_texture_image
*texImage
;
3169 GLsizei computedImageSize
;
3171 if (texture_error_check(ctx
, target
, level
, internalFormat
,
3172 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
)) {
3173 return; /* error in texture image was detected */
3176 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3177 texObj
= texUnit
->Current3D
;
3178 texImage
= texObj
->Image
[level
];
3181 texImage
= _mesa_alloc_texture_image();
3182 texObj
->Image
[level
] = texImage
;
3184 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage3DARB");
3188 else if (texImage
->Data
) {
3189 FREE(texImage
->Data
);
3190 texImage
->Data
= NULL
;
3193 /* setup the teximage struct's fields */
3194 init_texture_image(ctx
, texImage
, width
, height
, depth
,
3195 border
, internalFormat
);
3197 /* process the texture image */
3199 GLboolean retain
= GL_TRUE
;
3200 GLboolean success
= GL_FALSE
;
3201 if (ctx
->Driver
.CompressedTexImage3D
) {
3202 success
= (*ctx
->Driver
.CompressedTexImage3D
)(ctx
, target
, level
,
3207 if (retain
|| !success
) {
3208 /* make internal copy of the texture image */
3209 computedImageSize
= _mesa_compressed_image_size(ctx
,
3215 if (computedImageSize
!= imageSize
) {
3216 gl_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexImage3DARB(imageSize)");
3219 texImage
->Data
= MALLOC(computedImageSize
);
3220 if (texImage
->Data
) {
3221 MEMCPY(texImage
->Data
, data
, computedImageSize
);
3224 if (!retain
&& texImage
->Data
) {
3225 FREE(texImage
->Data
);
3226 texImage
->Data
= NULL
;
3230 make_null_texture(texImage
);
3231 if (ctx
->Driver
.CompressedTexImage3D
) {
3233 (*ctx
->Driver
.CompressedTexImage3D
)( ctx
, target
, level
, 0,
3234 texImage
->Data
, texObj
,
3240 texObj
->Complete
= GL_FALSE
;
3241 ctx
->NewState
|= _NEW_TEXTURE
;
3243 else if (target
== GL_PROXY_TEXTURE_3D
) {
3244 /* Proxy texture: check for errors and update proxy state */
3245 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
3246 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
);
3247 if (!error
&& ctx
->Driver
.TestProxyTexImage
) {
3248 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
3249 internalFormat
, GL_NONE
, GL_NONE
,
3250 width
, height
, depth
, border
);
3253 /* if error, clear all proxy texture image parameters */
3254 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
3255 clear_proxy_teximage(ctx
->Texture
.Proxy3D
->Image
[level
]);
3259 /* if no error, update proxy texture image parameters */
3260 init_texture_image(ctx
, ctx
->Texture
.Proxy3D
->Image
[level
],
3261 width
, 1, 1, border
, internalFormat
);
3265 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB(target)" );
3272 _mesa_CompressedTexSubImage1DARB(GLenum target
, GLint level
, GLint xoffset
,
3273 GLsizei width
, GLenum format
,
3274 GLsizei imageSize
, const GLvoid
*data
)
3276 GET_CURRENT_CONTEXT(ctx
);
3277 struct gl_texture_unit
*texUnit
;
3278 struct gl_texture_object
*texObj
;
3279 struct gl_texture_image
*texImage
;
3280 GLboolean success
= GL_FALSE
;
3282 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
3283 width
, 1, 1, format
, GL_NONE
)) {
3284 return; /* error was detected */
3287 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3288 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
3289 texImage
= texObj
->Image
[level
];
3292 if (width
== 0 || !data
)
3293 return; /* no-op, not an error */
3295 if (ctx
->Driver
.CompressedTexSubImage1D
) {
3296 success
= (*ctx
->Driver
.CompressedTexSubImage1D
)(ctx
, target
, level
,
3297 xoffset
, width
, format
, imageSize
, data
, texObj
, texImage
);
3300 /* XXX what else can we do? */
3301 gl_problem(ctx
, "glCompressedTexSubImage1DARB failed!");
3308 _mesa_CompressedTexSubImage2DARB(GLenum target
, GLint level
, GLint xoffset
,
3309 GLint yoffset
, GLsizei width
, GLsizei height
,
3310 GLenum format
, GLsizei imageSize
,
3313 GET_CURRENT_CONTEXT(ctx
);
3314 struct gl_texture_unit
*texUnit
;
3315 struct gl_texture_object
*texObj
;
3316 struct gl_texture_image
*texImage
;
3317 GLboolean success
= GL_FALSE
;
3319 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
3320 width
, height
, 1, format
, GL_NONE
)) {
3321 return; /* error was detected */
3324 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3325 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
3326 texImage
= texObj
->Image
[level
];
3329 if (width
== 0 || height
== 0 || !data
)
3330 return; /* no-op, not an error */
3332 if (ctx
->Driver
.CompressedTexSubImage2D
) {
3333 success
= (*ctx
->Driver
.CompressedTexSubImage2D
)(ctx
, target
, level
,
3334 xoffset
, yoffset
, width
, height
, format
,
3335 imageSize
, data
, texObj
, texImage
);
3338 /* XXX what else can we do? */
3339 gl_problem(ctx
, "glCompressedTexSubImage2DARB failed!");
3346 _mesa_CompressedTexSubImage3DARB(GLenum target
, GLint level
, GLint xoffset
,
3347 GLint yoffset
, GLint zoffset
, GLsizei width
,
3348 GLsizei height
, GLsizei depth
, GLenum format
,
3349 GLsizei imageSize
, const GLvoid
*data
)
3351 GET_CURRENT_CONTEXT(ctx
);
3352 struct gl_texture_unit
*texUnit
;
3353 struct gl_texture_object
*texObj
;
3354 struct gl_texture_image
*texImage
;
3355 GLboolean success
= GL_FALSE
;
3357 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
3358 width
, height
, depth
, format
, GL_NONE
)) {
3359 return; /* error was detected */
3362 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3363 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
3364 texImage
= texObj
->Image
[level
];
3367 if (width
== 0 || height
== 0 || depth
== 0 || !data
)
3368 return; /* no-op, not an error */
3370 if (ctx
->Driver
.CompressedTexSubImage3D
) {
3371 success
= (*ctx
->Driver
.CompressedTexSubImage3D
)(ctx
, target
, level
,
3372 xoffset
, yoffset
, zoffset
, width
, height
, depth
,
3373 format
, imageSize
, data
, texObj
, texImage
);
3376 /* XXX what else can we do? */
3377 gl_problem(ctx
, "glCompressedTexSubImage3DARB failed!");
3384 _mesa_GetCompressedTexImageARB(GLenum target
, GLint level
, GLvoid
*img
)
3386 GET_CURRENT_CONTEXT(ctx
);
3387 const struct gl_texture_object
*texObj
;
3388 struct gl_texture_image
*texImage
;
3390 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
3392 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
3393 gl_error( ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)" );
3399 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].Current1D
;
3400 texImage
= texObj
->Image
[level
];
3403 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].Current2D
;
3404 texImage
= texObj
->Image
[level
];
3406 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
3407 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3408 texImage
= texObj
->Image
[level
];
3410 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
3411 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3412 texImage
= texObj
->NegX
[level
];
3414 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
3415 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3416 texImage
= texObj
->PosY
[level
];
3418 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
3419 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3420 texImage
= texObj
->NegY
[level
];
3422 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
3423 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3424 texImage
= texObj
->PosZ
[level
];
3426 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
3427 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3428 texImage
= texObj
->NegZ
[level
];
3431 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].Current3D
;
3432 texImage
= texObj
->Image
[level
];
3435 gl_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB(target)");
3440 /* invalid mipmap level */
3441 gl_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
3445 if (!texImage
->IsCompressed
) {
3446 gl_error(ctx
, GL_INVALID_OPERATION
, "glGetCompressedTexImageARB");
3453 if (ctx
->Driver
.GetCompressedTexImage
) {
3454 (*ctx
->Driver
.GetCompressedTexImage
)(ctx
, target
, level
, img
, texObj
,
3458 gl_problem(ctx
, "Driver doesn't implement GetCompressedTexImage");