1 /* $Id: teximage.c,v 1.69 2000/12/26 05:09:29 keithw 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
= texUnit
->Current2D
->Image
[level
];
1257 gl_error(ctx
, GL_INVALID_OPERATION
, "glTexSubImage2D");
1261 if (xoffset
< -((GLint
)destTex
->Border
)) {
1262 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset)");
1265 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
1266 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset+width)");
1269 if (dimensions
> 1) {
1270 if (yoffset
< -((GLint
)destTex
->Border
)) {
1271 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset)");
1274 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
1275 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset+height)");
1279 if (dimensions
> 2) {
1280 if (zoffset
< -((GLint
)destTex
->Border
)) {
1281 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset)");
1284 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+destTex
->Border
)) {
1285 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset+depth)");
1290 if (!is_compressed_format(ctx
, destTex
->IntFormat
)) {
1291 if (!_mesa_is_legal_format_and_type(format
, type
)) {
1293 sprintf(message
, "glTexSubImage%dD(format or type)", dimensions
);
1294 gl_error(ctx
, GL_INVALID_ENUM
, message
);
1304 * Test glCopyTexImage[12]D() parameters for errors.
1305 * Input: dimensions - must be 1 or 2 or 3
1306 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
1309 copytexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
1310 GLenum target
, GLint level
, GLint internalFormat
,
1311 GLint width
, GLint height
, GLint border
)
1315 if (dimensions
== 1) {
1316 if (target
!= GL_TEXTURE_1D
) {
1317 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
1321 else if (dimensions
== 2) {
1322 if (ctx
->Extensions
.ARB_texture_cube_map
) {
1323 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1324 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1325 target
!= GL_TEXTURE_2D
) {
1326 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1330 else if (target
!= GL_TEXTURE_2D
) {
1331 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1337 if (border
!=0 && border
!=1) {
1339 sprintf(message
, "glCopyTexImage%dD(border)", dimensions
);
1340 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1345 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
1346 || logbase2( width
- 2 * border
) < 0) {
1348 sprintf(message
, "glCopyTexImage%dD(width=%d)", dimensions
, width
);
1349 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1354 if (dimensions
>= 2) {
1355 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
1356 || logbase2( height
- 2 * border
) < 0) {
1358 sprintf(message
, "glCopyTexImage%dD(height=%d)", dimensions
, height
);
1359 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1364 /* For cube map, width must equal height */
1365 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1366 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
1367 if (width
!= height
) {
1368 gl_error(ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(width != height)");
1374 if (level
<0 || level
>=ctx
->Const
.MaxTextureLevels
) {
1376 sprintf(message
, "glCopyTexImage%dD(level=%d)", dimensions
, level
);
1377 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1381 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
1384 sprintf(message
, "glCopyTexImage%dD(internalFormat)", dimensions
);
1385 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1389 /* if we get here, the parameters are OK */
1395 copytexsubimage_error_check( GLcontext
*ctx
, GLuint dimensions
,
1396 GLenum target
, GLint level
,
1397 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1398 GLsizei width
, GLsizei height
)
1400 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1401 struct gl_texture_image
*teximage
;
1403 if (dimensions
== 1) {
1404 if (target
!= GL_TEXTURE_1D
) {
1405 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
1409 else if (dimensions
== 2) {
1410 if (ctx
->Extensions
.ARB_texture_cube_map
) {
1411 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1412 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1413 target
!= GL_TEXTURE_2D
) {
1414 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1418 else if (target
!= GL_TEXTURE_2D
) {
1419 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1423 else if (dimensions
== 3) {
1424 if (target
!= GL_TEXTURE_3D
) {
1425 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3D(target)" );
1430 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1432 sprintf(message
, "glCopyTexSubImage%dD(level=%d)", dimensions
, level
);
1433 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1439 sprintf(message
, "glCopyTexSubImage%dD(width=%d)", dimensions
, width
);
1440 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1443 if (dimensions
> 1 && height
< 0) {
1445 sprintf(message
, "glCopyTexSubImage%dD(height=%d)", dimensions
, height
);
1446 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1450 teximage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1453 sprintf(message
, "glCopyTexSubImage%dD(undefined texture)", dimensions
);
1454 gl_error(ctx
, GL_INVALID_OPERATION
, message
);
1458 if (xoffset
< -((GLint
)teximage
->Border
)) {
1460 sprintf(message
, "glCopyTexSubImage%dD(xoffset=%d)", dimensions
, xoffset
);
1461 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1464 if (xoffset
+width
> (GLint
) (teximage
->Width
+teximage
->Border
)) {
1466 sprintf(message
, "glCopyTexSubImage%dD(xoffset+width)", dimensions
);
1467 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1470 if (dimensions
> 1) {
1471 if (yoffset
< -((GLint
)teximage
->Border
)) {
1473 sprintf(message
, "glCopyTexSubImage%dD(yoffset=%d)", dimensions
, yoffset
);
1474 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1477 /* NOTE: we're adding the border here, not subtracting! */
1478 if (yoffset
+height
> (GLint
) (teximage
->Height
+teximage
->Border
)) {
1480 sprintf(message
, "glCopyTexSubImage%dD(yoffset+height)", dimensions
);
1481 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1486 if (dimensions
> 2) {
1487 if (zoffset
< -((GLint
)teximage
->Border
)) {
1489 sprintf(message
, "glCopyTexSubImage%dD(zoffset)", dimensions
);
1490 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1493 if (zoffset
> (GLint
) (teximage
->Depth
+teximage
->Border
)) {
1495 sprintf(message
, "glCopyTexSubImage%dD(zoffset+depth)", dimensions
);
1496 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1501 /* if we get here, the parameters are OK */
1509 * Turn generic compressed formats into specific compressed format.
1510 * Some of the compressed formats we don't support, so we
1511 * fall back to the uncompressed format. (See issue 15 of
1512 * the GL_ARB_texture_compression specification.)
1515 get_specific_compressed_tex_format(GLcontext
*ctx
,
1516 GLint ifmt
, GLint numDimensions
,
1526 GLint internalFormat
= ifmt
;
1528 if (ctx
->Extensions
.ARB_texture_compression
1529 && ctx
->Driver
.SpecificCompressedTexFormat
) {
1531 * First, ask the driver for the specific format.
1532 * We do this for all formats, since we may want to
1533 * fake one compressed format for another.
1535 internalFormat
= (*ctx
->Driver
.SpecificCompressedTexFormat
)
1536 (ctx
, internalFormat
, numDimensions
,
1538 widthp
, heightp
, depthp
,
1539 borderp
, formatp
, typep
);
1543 * Now, convert any generic format left to an uncompressed
1544 * specific format. If the driver does not support compression
1545 * of the format, we must drop back to the uncompressed format.
1546 * See issue 15 of the GL_ARB_texture_compression specification.
1548 switch (internalFormat
) {
1549 case GL_COMPRESSED_ALPHA_ARB
:
1550 if (ctx
&& !ctx
->Extensions
.ARB_texture_compression
) {
1551 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1552 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1555 internalFormat
= GL_ALPHA
;
1557 case GL_COMPRESSED_LUMINANCE_ARB
:
1558 if (ctx
&& !ctx
->Extensions
.ARB_texture_compression
) {
1559 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1560 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1563 internalFormat
= GL_LUMINANCE
;
1565 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
1566 if (ctx
&& !ctx
->Extensions
.ARB_texture_compression
) {
1567 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1568 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1571 internalFormat
= GL_LUMINANCE_ALPHA
;
1573 case GL_COMPRESSED_INTENSITY_ARB
:
1574 if (ctx
&& !ctx
->Extensions
.ARB_texture_compression
) {
1575 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1576 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1579 internalFormat
= GL_INTENSITY
;
1581 case GL_COMPRESSED_RGB_ARB
:
1582 if (ctx
&& !ctx
->Extensions
.ARB_texture_compression
) {
1583 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1584 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1587 internalFormat
= GL_RGB
;
1589 case GL_COMPRESSED_RGBA_ARB
:
1590 if (ctx
&& !ctx
->Extensions
.ARB_texture_compression
) {
1591 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1592 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1595 internalFormat
= GL_RGBA
;
1598 /* silence compiler warning */
1601 return internalFormat
;
1606 * Called from the API. Note that width includes the border.
1609 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
1610 GLsizei width
, GLint border
, GLenum format
,
1611 GLenum type
, const GLvoid
*pixels
)
1613 GLsizei postConvWidth
= width
;
1614 GET_CURRENT_CONTEXT(ctx
);
1615 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1617 adjust_texture_size_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1619 if (target
==GL_TEXTURE_1D
) {
1620 struct gl_texture_unit
*texUnit
;
1621 struct gl_texture_object
*texObj
;
1622 struct gl_texture_image
*texImage
;
1625 ifmt
= get_specific_compressed_tex_format(ctx
, internalFormat
, 1,
1628 &border
, &format
, &type
);
1631 * The error here is that we were sent a generic compressed
1632 * format, but the extension is not supported.
1637 internalFormat
= ifmt
;
1640 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1641 format
, type
, 1, postConvWidth
, 1, 1, border
)) {
1642 return; /* error in texture image was detected */
1645 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1646 texObj
= texUnit
->Current1D
;
1647 texImage
= texObj
->Image
[level
];
1650 texImage
= _mesa_alloc_texture_image();
1651 texObj
->Image
[level
] = texImage
;
1653 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
1657 else if (texImage
->Data
) {
1658 FREE(texImage
->Data
);
1659 texImage
->Data
= NULL
;
1662 /* setup the teximage struct's fields */
1663 init_texture_image(ctx
, texImage
, postConvWidth
, 1, 1, border
, internalFormat
);
1665 if (ctx
->NewState
& _NEW_PIXEL
)
1666 gl_update_state(ctx
);
1668 /* process the texture image */
1670 GLboolean retain
= GL_TRUE
;
1671 GLboolean success
= GL_FALSE
;
1672 if (!ctx
->_ImageTransferState
&& ctx
->Driver
.TexImage1D
) {
1673 /* let device driver try to use raw image */
1674 success
= (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, format
,
1675 type
, pixels
, &ctx
->Unpack
,
1676 texObj
, texImage
, &retain
);
1678 if (retain
|| !success
) {
1679 /* make internal copy of the texture image */
1680 make_texture_image(ctx
, 1, texImage
, width
, 1, 1,
1681 format
, type
, pixels
, &ctx
->Unpack
);
1682 if (!success
&& ctx
->Driver
.TexImage1D
) {
1683 /* let device driver try to use unpacked image */
1684 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
1685 GL_UNSIGNED_BYTE
, texImage
->Data
,
1686 &_mesa_native_packing
,
1687 texObj
, texImage
, &retain
);
1690 if (!retain
&& texImage
->Data
) {
1691 FREE(texImage
->Data
);
1692 texImage
->Data
= NULL
;
1696 make_null_texture(texImage
);
1697 if (ctx
->Driver
.TexImage1D
) {
1699 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
1700 GL_UNSIGNED_BYTE
, texImage
->Data
,
1701 &_mesa_native_packing
,
1702 texObj
, texImage
, &retain
);
1707 texObj
->Complete
= GL_FALSE
;
1708 ctx
->NewState
|= _NEW_TEXTURE
;
1710 else if (target
== GL_PROXY_TEXTURE_1D
) {
1711 /* Proxy texture: check for errors and update proxy state */
1712 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1713 format
, type
, 1, width
, 1, 1, border
);
1714 if (!error
&& ctx
->Driver
.TestProxyTexImage
) {
1715 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1716 internalFormat
, format
, type
,
1717 width
, 1, 1, border
);
1720 /* if error, clear all proxy texture image parameters */
1721 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1722 clear_proxy_teximage(ctx
->Texture
.Proxy1D
->Image
[level
]);
1726 /* if no error, update proxy texture image parameters */
1727 init_texture_image(ctx
, ctx
->Texture
.Proxy1D
->Image
[level
],
1728 width
, 1, 1, border
, internalFormat
);
1732 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1739 _mesa_TexImage2D( GLenum target
, GLint level
, GLint internalFormat
,
1740 GLsizei width
, GLsizei height
, GLint border
,
1741 GLenum format
, GLenum type
,
1742 const GLvoid
*pixels
)
1744 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1745 GET_CURRENT_CONTEXT(ctx
);
1746 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1748 adjust_texture_size_for_convolution(ctx
, 2, &postConvWidth
,&postConvHeight
);
1750 if (target
==GL_TEXTURE_2D
||
1751 (ctx
->Extensions
.ARB_texture_cube_map
&&
1752 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1753 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
1754 struct gl_texture_unit
*texUnit
;
1755 struct gl_texture_object
*texObj
;
1756 struct gl_texture_image
*texImage
;
1759 ifmt
= get_specific_compressed_tex_format(ctx
, internalFormat
, 2,
1762 &border
, &format
, &type
);
1765 * The error here is that we were sent a generic compressed
1766 * format, but the extension is not supported.
1771 internalFormat
= ifmt
;
1774 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1775 format
, type
, 2, postConvWidth
, postConvHeight
,
1777 return; /* error in texture image was detected */
1780 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1781 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1782 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1785 texImage
= _mesa_alloc_texture_image();
1786 set_tex_image(texObj
, target
, level
, texImage
);
1787 /*texObj->Image[level] = texImage;*/
1789 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1793 else if (texImage
->Data
) {
1794 FREE(texImage
->Data
);
1795 texImage
->Data
= NULL
;
1798 /* setup the teximage struct's fields */
1799 init_texture_image(ctx
, texImage
, postConvWidth
, postConvHeight
,
1800 1, border
, internalFormat
);
1802 if (ctx
->NewState
& _NEW_PIXEL
)
1803 gl_update_state(ctx
);
1805 /* process the texture image */
1807 GLboolean retain
= GL_TRUE
;
1808 GLboolean success
= GL_FALSE
;
1809 if (!ctx
->_ImageTransferState
&& ctx
->Driver
.TexImage2D
) {
1810 /* let device driver try to use raw image */
1811 success
= (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, format
,
1812 type
, pixels
, &ctx
->Unpack
,
1813 texObj
, texImage
, &retain
);
1815 if (retain
|| !success
) {
1816 /* make internal copy of the texture image */
1817 make_texture_image(ctx
, 2, texImage
, width
, height
, 1,
1818 format
, type
, pixels
, &ctx
->Unpack
);
1819 if (!success
&& ctx
->Driver
.TexImage2D
) {
1820 /* let device driver try to use unpacked image */
1821 (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, texImage
->Format
,
1822 GL_UNSIGNED_BYTE
, texImage
->Data
,
1823 &_mesa_native_packing
,
1824 texObj
, texImage
, &retain
);
1827 if (!retain
&& texImage
->Data
) {
1828 FREE(texImage
->Data
);
1829 texImage
->Data
= NULL
;
1833 make_null_texture(texImage
);
1834 if (ctx
->Driver
.TexImage2D
) {
1836 (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, texImage
->Format
,
1837 GL_UNSIGNED_BYTE
, texImage
->Data
,
1838 &_mesa_native_packing
,
1839 texObj
, texImage
, &retain
);
1844 texObj
->Complete
= GL_FALSE
;
1845 ctx
->NewState
|= _NEW_TEXTURE
;
1847 else if (target
== GL_PROXY_TEXTURE_2D
) {
1848 /* Proxy texture: check for errors and update proxy state */
1849 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1850 format
, type
, 2, width
, height
, 1, border
);
1851 if (!error
&& ctx
->Driver
.TestProxyTexImage
) {
1852 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1853 internalFormat
, format
, type
,
1854 width
, height
, 1, border
);
1857 /* if error, clear all proxy texture image parameters */
1858 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1859 clear_proxy_teximage(ctx
->Texture
.Proxy2D
->Image
[level
]);
1863 /* if no error, update proxy texture image parameters */
1864 init_texture_image(ctx
,
1865 ctx
->Texture
.Proxy2D
->Image
[level
],
1866 width
, height
, 1, border
, internalFormat
);
1870 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1877 * Called by the API or display list executor.
1878 * Note that width and height include the border.
1881 _mesa_TexImage3D( GLenum target
, GLint level
, GLint internalFormat
,
1882 GLsizei width
, GLsizei height
, GLsizei depth
,
1883 GLint border
, GLenum format
, GLenum type
,
1884 const GLvoid
*pixels
)
1886 GET_CURRENT_CONTEXT(ctx
);
1887 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1889 if (target
==GL_TEXTURE_3D_EXT
) {
1890 struct gl_texture_unit
*texUnit
;
1891 struct gl_texture_object
*texObj
;
1892 struct gl_texture_image
*texImage
;
1895 ifmt
= get_specific_compressed_tex_format(ctx
, internalFormat
, 3,
1897 &width
, &height
, &depth
,
1898 &border
, &format
, &type
);
1901 * The error here is that we were sent a generic compressed
1902 * format, but the extension is not supported.
1907 internalFormat
= ifmt
;
1910 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1911 format
, type
, 3, width
, height
, depth
, border
)) {
1912 return; /* error in texture image was detected */
1915 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1916 texObj
= texUnit
->Current3D
;
1917 texImage
= texObj
->Image
[level
];
1920 texImage
= _mesa_alloc_texture_image();
1921 texObj
->Image
[level
] = texImage
;
1923 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
1927 else if (texImage
->Data
) {
1928 FREE(texImage
->Data
);
1929 texImage
->Data
= NULL
;
1932 /* setup the teximage struct's fields */
1933 init_texture_image(ctx
, texImage
, width
, height
, depth
,
1934 border
, internalFormat
);
1936 if (ctx
->NewState
& _NEW_PIXEL
)
1937 gl_update_state(ctx
);
1939 /* process the texture image */
1941 GLboolean retain
= GL_TRUE
;
1942 GLboolean success
= GL_FALSE
;
1943 if (!ctx
->_ImageTransferState
&& ctx
->Driver
.TexImage3D
) {
1944 /* let device driver try to use raw image */
1945 success
= (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, format
,
1946 type
, pixels
, &ctx
->Unpack
,
1947 texObj
, texImage
, &retain
);
1949 if (retain
|| !success
) {
1950 /* make internal copy of the texture image */
1951 make_texture_image(ctx
, 3, texImage
, width
, height
, depth
,
1952 format
, type
, pixels
, &ctx
->Unpack
);
1953 if (!success
&& ctx
->Driver
.TexImage3D
) {
1954 /* let device driver try to use unpacked image */
1955 (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, texImage
->Format
,
1956 GL_UNSIGNED_BYTE
, texImage
->Data
,
1957 &_mesa_native_packing
,
1958 texObj
, texImage
, &retain
);
1961 if (!retain
&& texImage
->Data
) {
1962 FREE(texImage
->Data
);
1963 texImage
->Data
= NULL
;
1967 make_null_texture(texImage
);
1968 if (ctx
->Driver
.TexImage3D
) {
1970 (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, texImage
->Format
,
1971 GL_UNSIGNED_BYTE
, texImage
->Data
,
1972 &_mesa_native_packing
,
1973 texObj
, texImage
, &retain
);
1978 texObj
->Complete
= GL_FALSE
;
1979 ctx
->NewState
|= _NEW_TEXTURE
;
1981 else if (target
== GL_PROXY_TEXTURE_3D
) {
1982 /* Proxy texture: check for errors and update proxy state */
1983 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1984 format
, type
, 3, width
, height
, depth
, border
);
1985 if (!error
&& ctx
->Driver
.TestProxyTexImage
) {
1986 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1987 internalFormat
, format
, type
,
1988 width
, height
, depth
, border
);
1991 /* if error, clear all proxy texture image parameters */
1992 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1993 clear_proxy_teximage(ctx
->Texture
.Proxy3D
->Image
[level
]);
1997 /* if no error, update proxy texture image parameters */
1998 init_texture_image(ctx
, ctx
->Texture
.Proxy3D
->Image
[level
],
1999 width
, height
, depth
, border
, internalFormat
);
2003 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
2010 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
2011 GLsizei width
, GLsizei height
, GLsizei depth
,
2012 GLint border
, GLenum format
, GLenum type
,
2013 const GLvoid
*pixels
)
2015 _mesa_TexImage3D(target
, level
, (GLint
) internalFormat
, width
, height
,
2016 depth
, border
, format
, type
, pixels
);
2021 * Fetch a texture image from the device driver.
2022 * Store the results in the given texture object at the given mipmap level.
2025 _mesa_get_teximage_from_driver( GLcontext
*ctx
, GLenum target
, GLint level
,
2026 const struct gl_texture_object
*texObj
)
2029 GLenum imgFormat
, imgType
;
2030 GLboolean freeImage
;
2031 struct gl_texture_image
*texImage
;
2032 GLint destComponents
, numPixels
, srcBytesPerTexel
;
2034 if (!ctx
->Driver
.GetTexImage
)
2037 image
= (*ctx
->Driver
.GetTexImage
)( ctx
, target
, level
, texObj
,
2038 &imgFormat
, &imgType
, &freeImage
);
2042 texImage
= texObj
->Image
[level
];
2047 destComponents
= components_in_intformat(texImage
->Format
);
2048 assert(destComponents
> 0);
2049 numPixels
= texImage
->Width
* texImage
->Height
* texImage
->Depth
;
2050 assert(numPixels
> 0);
2051 srcBytesPerTexel
= _mesa_bytes_per_pixel(imgFormat
, imgType
);
2052 assert(srcBytesPerTexel
> 0);
2054 if (!texImage
->Data
) {
2055 /* Allocate memory for the texture image data */
2056 texImage
->Data
= (GLchan
*) MALLOC(numPixels
* destComponents
2057 * sizeof(GLchan
) + EXTRA_BYTE
);
2060 if (imgFormat
== texImage
->Format
&& imgType
== GL_UNSIGNED_BYTE
) {
2061 /* We got lucky! The driver's format and type match Mesa's format. */
2062 if (texImage
->Data
) {
2063 MEMCPY(texImage
->Data
, image
, numPixels
* destComponents
);
2067 /* Convert the texture image from the driver's format to Mesa's
2070 const GLint width
= texImage
->Width
;
2071 const GLint height
= texImage
->Height
;
2072 const GLint depth
= texImage
->Depth
;
2073 const GLint destBytesPerRow
= width
* destComponents
* sizeof(GLchan
);
2074 const GLint srcBytesPerRow
= width
* srcBytesPerTexel
;
2075 const GLenum dstType
= GL_UNSIGNED_BYTE
;
2076 const GLenum dstFormat
= texImage
->Format
;
2077 const GLchan
*srcPtr
= (const GLchan
*) image
;
2078 GLchan
*destPtr
= texImage
->Data
;
2080 if (texImage
->Format
== GL_COLOR_INDEX
) {
2081 /* color index texture */
2083 assert(imgFormat
== GL_COLOR_INDEX
);
2084 for (img
= 0; img
< depth
; img
++) {
2085 for (row
= 0; row
< height
; row
++) {
2086 _mesa_unpack_index_span(ctx
, width
, dstType
, destPtr
,
2087 imgType
, srcPtr
, &_mesa_native_packing
, GL_FALSE
);
2088 destPtr
+= destBytesPerRow
;
2089 srcPtr
+= srcBytesPerRow
;
2096 for (img
= 0; img
< depth
; img
++) {
2097 for (row
= 0; row
< height
; row
++) {
2098 _mesa_unpack_chan_color_span(ctx
, width
, dstFormat
, destPtr
,
2099 imgFormat
, imgType
, srcPtr
, &_mesa_native_packing
, GL_FALSE
);
2100 destPtr
+= destBytesPerRow
;
2101 srcPtr
+= srcBytesPerRow
;
2113 * Get all the mipmap images for a texture object from the device driver.
2114 * Actually, only get mipmap images if we're using a mipmap filter.
2117 _mesa_get_teximages_from_driver(GLcontext
*ctx
,
2118 struct gl_texture_object
*texObj
)
2120 if (ctx
->Driver
.GetTexImage
) {
2121 static const GLenum targets
[] = {
2125 GL_TEXTURE_CUBE_MAP_ARB
,
2126 GL_TEXTURE_CUBE_MAP_ARB
,
2127 GL_TEXTURE_CUBE_MAP_ARB
2129 GLboolean needLambda
= (texObj
->MinFilter
!= texObj
->MagFilter
);
2130 GLenum target
= targets
[texObj
->Dimensions
- 1];
2133 /* Get images for all mipmap levels. We might not need them
2134 * all but this is easier. We're on a (slow) software path
2137 for (level
= texObj
->BaseLevel
; level
<= texObj
->_MaxLevel
; level
++) {
2138 struct gl_texture_image
*texImg
= texObj
->Image
[level
];
2139 if (texImg
&& !texImg
->Data
) {
2140 _mesa_get_teximage_from_driver(ctx
, target
, level
, texObj
);
2142 return GL_FALSE
; /* out of memory */
2147 GLint level
= texObj
->BaseLevel
;
2148 struct gl_texture_image
*texImg
= texObj
->Image
[level
];
2149 if (texImg
&& !texImg
->Data
) {
2150 _mesa_get_teximage_from_driver(ctx
, target
, level
, texObj
);
2152 return GL_FALSE
; /* out of memory */
2163 _mesa_GetTexImage( GLenum target
, GLint level
, GLenum format
,
2164 GLenum type
, GLvoid
*pixels
)
2166 GET_CURRENT_CONTEXT(ctx
);
2167 const struct gl_texture_unit
*texUnit
;
2168 const struct gl_texture_object
*texObj
;
2169 struct gl_texture_image
*texImage
;
2170 GLboolean discardImage
;
2172 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2174 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
2175 gl_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
2179 if (_mesa_sizeof_type(type
) <= 0) {
2180 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
2184 if (_mesa_components_in_format(format
) <= 0) {
2185 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
2192 texUnit
= &(ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
]);
2193 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2195 target
== GL_PROXY_TEXTURE_1D
||
2196 target
== GL_PROXY_TEXTURE_2D
||
2197 target
== GL_PROXY_TEXTURE_3D
) {
2198 gl_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)");
2202 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2204 /* invalid mipmap level, not an error */
2208 if (!texImage
->Data
) {
2209 /* try to get the texture image from the device driver */
2210 _mesa_get_teximage_from_driver(ctx
, target
, level
, texObj
);
2211 discardImage
= GL_TRUE
;
2214 discardImage
= GL_FALSE
;
2217 if (texImage
->Data
) {
2218 GLint width
= texImage
->Width
;
2219 GLint height
= texImage
->Height
;
2220 GLint depth
= texImage
->Depth
;
2223 if (ctx
->NewState
& _NEW_PIXEL
)
2224 gl_update_state(ctx
);
2226 if (ctx
->_ImageTransferState
& IMAGE_CONVOLUTION_BIT
) {
2227 /* convert texture image to GL_RGBA, GL_FLOAT */
2228 GLfloat
*tmpImage
, *convImage
;
2229 const GLint comps
= components_in_intformat(texImage
->Format
);
2231 tmpImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
2233 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
2236 convImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
2239 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
2243 for (img
= 0; img
< depth
; img
++) {
2244 GLint convWidth
, convHeight
;
2246 /* convert to GL_RGBA */
2247 for (row
= 0; row
< height
; row
++) {
2248 const GLchan
*src
= texImage
->Data
2249 + (img
* height
+ row
) * width
* comps
;
2250 GLfloat
*dst
= tmpImage
+ row
* width
* 4;
2251 _mesa_unpack_float_color_span(ctx
, width
, GL_RGBA
, dst
,
2252 texImage
->Format
, GL_UNSIGNED_BYTE
,
2253 src
, &_mesa_native_packing
,
2254 ctx
->_ImageTransferState
& IMAGE_PRE_CONVOLUTION_BITS
,
2259 convHeight
= height
;
2262 if (target
== GL_TEXTURE_1D
) {
2263 if (ctx
->Pixel
.Convolution1DEnabled
) {
2264 _mesa_convolve_1d_image(ctx
, &convWidth
, tmpImage
, convImage
);
2268 if (ctx
->Pixel
.Convolution2DEnabled
) {
2269 _mesa_convolve_2d_image(ctx
, &convWidth
, &convHeight
,
2270 tmpImage
, convImage
);
2272 else if (ctx
->Pixel
.Separable2DEnabled
) {
2273 _mesa_convolve_sep_image(ctx
, &convWidth
, &convHeight
,
2274 tmpImage
, convImage
);
2278 /* pack convolved image */
2279 for (row
= 0; row
< convHeight
; row
++) {
2280 const GLfloat
*src
= convImage
+ row
* convWidth
* 4;
2281 GLvoid
*dest
= _mesa_image_address(&ctx
->Pack
, pixels
,
2282 convWidth
, convHeight
,
2283 format
, type
, img
, row
, 0);
2284 _mesa_pack_float_rgba_span(ctx
, convWidth
,
2285 (const GLfloat(*)[4]) src
,
2286 format
, type
, dest
, &ctx
->Pack
,
2287 ctx
->_ImageTransferState
& IMAGE_POST_CONVOLUTION_BITS
);
2295 /* no convolution */
2296 for (img
= 0; img
< depth
; img
++) {
2297 for (row
= 0; row
< height
; row
++) {
2298 /* compute destination address in client memory */
2299 GLvoid
*dest
= _mesa_image_address( &ctx
->Unpack
, pixels
,
2300 width
, height
, format
, type
, img
, row
, 0);
2302 if (texImage
->Format
== GL_RGBA
) {
2304 const GLchan
*src
= texImage
->Data
2305 + (img
* height
+ row
) * width
* 4;
2306 _mesa_pack_rgba_span( ctx
, width
, (CONST
GLchan (*)[4]) src
,
2307 format
, type
, dest
, &ctx
->Pack
,
2308 ctx
->_ImageTransferState
);
2311 /* general case: convert row to RGBA format */
2312 GLchan rgba
[MAX_WIDTH
][4];
2315 switch (texImage
->Format
) {
2317 src
= texImage
->Data
+ row
* width
;
2318 for (i
= 0; i
< width
; i
++) {
2319 rgba
[i
][RCOMP
] = CHAN_MAX
;
2320 rgba
[i
][GCOMP
] = CHAN_MAX
;
2321 rgba
[i
][BCOMP
] = CHAN_MAX
;
2322 rgba
[i
][ACOMP
] = src
[i
];
2326 src
= texImage
->Data
+ row
* width
;
2327 for (i
= 0; i
< width
; i
++) {
2328 rgba
[i
][RCOMP
] = src
[i
];
2329 rgba
[i
][GCOMP
] = src
[i
];
2330 rgba
[i
][BCOMP
] = src
[i
];
2331 rgba
[i
][ACOMP
] = CHAN_MAX
;
2334 case GL_LUMINANCE_ALPHA
:
2335 src
= texImage
->Data
+ row
* 2 * width
;
2336 for (i
= 0; i
< width
; i
++) {
2337 rgba
[i
][RCOMP
] = src
[i
*2+0];
2338 rgba
[i
][GCOMP
] = src
[i
*2+0];
2339 rgba
[i
][BCOMP
] = src
[i
*2+0];
2340 rgba
[i
][ACOMP
] = src
[i
*2+1];
2344 src
= texImage
->Data
+ row
* width
;
2345 for (i
= 0; i
< width
; i
++) {
2346 rgba
[i
][RCOMP
] = src
[i
];
2347 rgba
[i
][GCOMP
] = src
[i
];
2348 rgba
[i
][BCOMP
] = src
[i
];
2349 rgba
[i
][ACOMP
] = CHAN_MAX
;
2353 src
= texImage
->Data
+ row
* 3 * width
;
2354 for (i
= 0; i
< width
; i
++) {
2355 rgba
[i
][RCOMP
] = src
[i
*3+0];
2356 rgba
[i
][GCOMP
] = src
[i
*3+1];
2357 rgba
[i
][BCOMP
] = src
[i
*3+2];
2358 rgba
[i
][ACOMP
] = CHAN_MAX
;
2361 case GL_COLOR_INDEX
:
2362 gl_problem( ctx
, "GL_COLOR_INDEX not implemented in gl_GetTexImage" );
2366 gl_problem( ctx
, "bad format in gl_GetTexImage" );
2368 _mesa_pack_rgba_span( ctx
, width
, (const GLchan (*)[4])rgba
,
2369 format
, type
, dest
, &ctx
->Pack
,
2370 ctx
->_ImageTransferState
);
2376 /* if we got the teximage from the device driver we'll discard it now */
2378 FREE(texImage
->Data
);
2379 texImage
->Data
= NULL
;
2387 _mesa_TexSubImage1D( GLenum target
, GLint level
,
2388 GLint xoffset
, GLsizei width
,
2389 GLenum format
, GLenum type
,
2390 const GLvoid
*pixels
)
2392 GLsizei postConvWidth
= width
;
2393 GET_CURRENT_CONTEXT(ctx
);
2394 struct gl_texture_unit
*texUnit
;
2395 struct gl_texture_object
*texObj
;
2396 struct gl_texture_image
*texImage
;
2397 GLboolean success
= GL_FALSE
;
2399 adjust_texture_size_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
2401 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
2402 postConvWidth
, 1, 1, format
, type
)) {
2403 return; /* error was detected */
2406 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2407 texObj
= texUnit
->Current1D
;
2408 texImage
= texObj
->Image
[level
];
2411 if (width
== 0 || !pixels
)
2412 return; /* no-op, not an error */
2414 if (ctx
->NewState
& _NEW_PIXEL
)
2415 gl_update_state(ctx
);
2417 if (!ctx
->_ImageTransferState
&& ctx
->Driver
.TexSubImage1D
) {
2418 success
= (*ctx
->Driver
.TexSubImage1D
)( ctx
, target
, level
, xoffset
,
2419 width
, format
, type
, pixels
,
2420 &ctx
->Unpack
, texObj
, texImage
);
2423 /* XXX if Driver.TexSubImage1D, unpack image and try again? */
2424 GLboolean retain
= GL_TRUE
;
2425 if (!texImage
->Data
) {
2426 _mesa_get_teximage_from_driver( ctx
, target
, level
, texObj
);
2427 if (!texImage
->Data
) {
2428 make_null_texture(texImage
);
2430 if (!texImage
->Data
)
2431 return; /* we're really out of luck! */
2434 fill_texture_image(ctx
, 1, texImage
->Format
, texImage
->Data
,
2435 width
, 1, 1, xoffset
+ texImage
->Border
, 0, 0, /* size and offsets */
2437 format
, type
, pixels
, &ctx
->Unpack
);
2439 if (ctx
->Driver
.TexImage1D
) {
2440 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
2441 GL_UNSIGNED_BYTE
, texImage
->Data
,
2442 &_mesa_native_packing
, texObj
, texImage
,
2446 if (!retain
&& texImage
->Data
) {
2447 FREE(texImage
->Data
);
2448 texImage
->Data
= NULL
;
2455 _mesa_TexSubImage2D( GLenum target
, GLint level
,
2456 GLint xoffset
, GLint yoffset
,
2457 GLsizei width
, GLsizei height
,
2458 GLenum format
, GLenum type
,
2459 const GLvoid
*pixels
)
2461 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2462 GET_CURRENT_CONTEXT(ctx
);
2463 struct gl_texture_unit
*texUnit
;
2464 struct gl_texture_object
*texObj
;
2465 struct gl_texture_image
*texImage
;
2466 GLboolean success
= GL_FALSE
;
2468 adjust_texture_size_for_convolution(ctx
, 2, &postConvWidth
,&postConvHeight
);
2470 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2471 postConvWidth
, postConvHeight
, 1, format
, type
)) {
2472 return; /* error was detected */
2475 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2476 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2477 texImage
= texObj
->Image
[level
];
2480 if (width
== 0 || height
== 0 || !pixels
)
2481 return; /* no-op, not an error */
2483 if (ctx
->NewState
& _NEW_PIXEL
)
2484 gl_update_state(ctx
);
2486 if (!ctx
->_ImageTransferState
&& ctx
->Driver
.TexSubImage2D
) {
2487 success
= (*ctx
->Driver
.TexSubImage2D
)( ctx
, target
, level
, xoffset
,
2488 yoffset
, width
, height
, format
, type
,
2489 pixels
, &ctx
->Unpack
, texObj
, texImage
);
2492 /* XXX if Driver.TexSubImage2D, unpack image and try again? */
2493 const GLint texComps
= components_in_intformat(texImage
->Format
);
2494 const GLint texRowStride
= texImage
->Width
* texComps
;
2495 GLboolean retain
= GL_TRUE
;
2497 if (!texImage
->Data
) {
2498 _mesa_get_teximage_from_driver( ctx
, target
, level
, texObj
);
2499 if (!texImage
->Data
) {
2500 make_null_texture(texImage
);
2502 if (!texImage
->Data
)
2503 return; /* we're really out of luck! */
2506 fill_texture_image(ctx
, 2, texImage
->Format
, texImage
->Data
,
2507 width
, height
, 1, xoffset
+ texImage
->Border
,
2508 yoffset
+ texImage
->Border
, 0, texRowStride
, 0,
2509 format
, type
, pixels
, &ctx
->Unpack
);
2511 if (ctx
->Driver
.TexImage2D
) {
2512 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, texImage
->Format
,
2513 GL_UNSIGNED_BYTE
, texImage
->Data
,
2514 &_mesa_native_packing
, texObj
, texImage
,
2518 if (!retain
&& texImage
->Data
) {
2519 FREE(texImage
->Data
);
2520 texImage
->Data
= NULL
;
2528 _mesa_TexSubImage3D( GLenum target
, GLint level
,
2529 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2530 GLsizei width
, GLsizei height
, GLsizei depth
,
2531 GLenum format
, GLenum type
,
2532 const GLvoid
*pixels
)
2534 GET_CURRENT_CONTEXT(ctx
);
2535 struct gl_texture_unit
*texUnit
;
2536 struct gl_texture_object
*texObj
;
2537 struct gl_texture_image
*texImage
;
2538 GLboolean success
= GL_FALSE
;
2540 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2541 width
, height
, depth
, format
, type
)) {
2542 return; /* error was detected */
2545 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2546 texObj
= texUnit
->Current3D
;
2547 texImage
= texObj
->Image
[level
];
2550 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
2551 return; /* no-op, not an error */
2553 if (ctx
->NewState
& _NEW_PIXEL
)
2554 gl_update_state(ctx
);
2556 if (!ctx
->_ImageTransferState
&& ctx
->Driver
.TexSubImage3D
) {
2557 success
= (*ctx
->Driver
.TexSubImage3D
)( ctx
, target
, level
, xoffset
,
2558 yoffset
, zoffset
, width
, height
, depth
, format
,
2559 type
, pixels
, &ctx
->Unpack
, texObj
, texImage
);
2562 /* XXX if Driver.TexSubImage3D, unpack image and try again? */
2563 const GLint texComps
= components_in_intformat(texImage
->Format
);
2564 const GLint texRowStride
= texImage
->Width
* texComps
;
2565 const GLint texImgStride
= texRowStride
* texImage
->Height
;
2566 GLboolean retain
= GL_TRUE
;
2568 if (!texImage
->Data
) {
2569 _mesa_get_teximage_from_driver( ctx
, target
, level
, texObj
);
2570 if (!texImage
->Data
) {
2571 make_null_texture(texImage
);
2573 if (!texImage
->Data
)
2574 return; /* we're really out of luck! */
2577 fill_texture_image(ctx
, 3, texImage
->Format
, texImage
->Data
,
2578 width
, height
, depth
, xoffset
+ texImage
->Border
,
2579 yoffset
+ texImage
->Border
,
2580 zoffset
+ texImage
->Border
, texRowStride
,
2581 texImgStride
, format
, type
, pixels
, &ctx
->Unpack
);
2583 if (ctx
->Driver
.TexImage3D
) {
2584 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, texImage
->Format
,
2585 GL_UNSIGNED_BYTE
, texImage
->Data
,
2586 &_mesa_native_packing
, texObj
, texImage
,
2590 if (!retain
&& texImage
->Data
) {
2591 FREE(texImage
->Data
);
2592 texImage
->Data
= NULL
;
2600 * Read an RGBA image from the frame buffer.
2601 * This is used by glCopyTex[Sub]Image[12]D().
2602 * Input: ctx - the context
2603 * x, y - lower left corner
2604 * width, height - size of region to read
2605 * Return: pointer to block of GL_RGBA, GLchan data.
2608 read_color_image( GLcontext
*ctx
, GLint x
, GLint y
,
2609 GLsizei width
, GLsizei height
)
2612 GLchan
*image
, *dst
;
2614 image
= (GLchan
*) MALLOC(width
* height
* 4 * sizeof(GLchan
));
2618 /* Select buffer to read from */
2619 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->ReadBuffer
,
2620 ctx
->Pixel
.DriverReadBuffer
);
2626 for (i
= 0; i
< height
; i
++) {
2627 gl_read_rgba_span( ctx
, ctx
->ReadBuffer
, width
, x
, y
+ i
,
2628 (GLchan (*)[4]) dst
);
2634 /* Read from draw buffer (the default) */
2635 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->DrawBuffer
,
2636 ctx
->Color
.DriverDrawBuffer
);
2644 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
2645 GLenum internalFormat
,
2647 GLsizei width
, GLint border
)
2649 GLsizei postConvWidth
= width
;
2650 GET_CURRENT_CONTEXT(ctx
);
2651 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2653 if (ctx
->NewState
& _NEW_PIXEL
)
2654 gl_update_state(ctx
);
2656 adjust_texture_size_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
2658 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
2659 postConvWidth
, 1, border
))
2662 if (ctx
->_ImageTransferState
|| !ctx
->Driver
.CopyTexImage1D
2663 || !(*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
,
2664 internalFormat
, x
, y
, width
, border
)) {
2665 struct gl_pixelstore_attrib unpackSave
;
2667 /* get image from framebuffer */
2668 GLchan
*image
= read_color_image( ctx
, x
, y
, width
, 1 );
2670 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D" );
2674 /* call glTexImage1D to redefine the texture */
2675 unpackSave
= ctx
->Unpack
;
2676 ctx
->Unpack
= _mesa_native_packing
;
2677 (*ctx
->Exec
->TexImage1D
)( target
, level
, internalFormat
, width
,
2678 border
, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2679 ctx
->Unpack
= unpackSave
;
2688 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
2689 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
2692 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2693 GET_CURRENT_CONTEXT(ctx
);
2694 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2696 if (ctx
->NewState
& _NEW_PIXEL
)
2697 gl_update_state(ctx
);
2699 adjust_texture_size_for_convolution(ctx
, 2, &postConvWidth
,&postConvHeight
);
2701 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
2702 postConvWidth
, postConvHeight
, border
))
2705 if (ctx
->_ImageTransferState
|| !ctx
->Driver
.CopyTexImage2D
2706 || !(*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
,
2707 internalFormat
, x
, y
, width
, height
, border
)) {
2708 struct gl_pixelstore_attrib unpackSave
;
2710 /* get image from framebuffer */
2711 GLchan
*image
= read_color_image( ctx
, x
, y
, width
, height
);
2713 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D" );
2717 /* call glTexImage2D to redefine the texture */
2718 unpackSave
= ctx
->Unpack
;
2719 ctx
->Unpack
= _mesa_native_packing
;
2720 (ctx
->Exec
->TexImage2D
)( target
, level
, internalFormat
, width
,
2721 height
, border
, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2722 ctx
->Unpack
= unpackSave
;
2731 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
2732 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
2734 GLsizei postConvWidth
= width
;
2735 GET_CURRENT_CONTEXT(ctx
);
2736 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2738 if (ctx
->NewState
& _NEW_PIXEL
)
2739 gl_update_state(ctx
);
2741 adjust_texture_size_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
2743 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
2744 xoffset
, 0, 0, postConvWidth
, 1))
2747 if (ctx
->_ImageTransferState
|| !ctx
->Driver
.CopyTexSubImage1D
2748 || !(*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
,
2749 xoffset
, x
, y
, width
)) {
2750 struct gl_texture_unit
*texUnit
;
2751 struct gl_texture_image
*teximage
;
2752 struct gl_pixelstore_attrib unpackSave
;
2755 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2756 teximage
= texUnit
->Current1D
->Image
[level
];
2759 /* get image from frame buffer */
2760 image
= read_color_image(ctx
, x
, y
, width
, 1);
2762 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage1D" );
2766 /* now call glTexSubImage1D to do the real work */
2767 unpackSave
= ctx
->Unpack
;
2768 ctx
->Unpack
= _mesa_native_packing
;
2769 _mesa_TexSubImage1D(target
, level
, xoffset
, width
,
2770 GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2771 ctx
->Unpack
= unpackSave
;
2780 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
2781 GLint xoffset
, GLint yoffset
,
2782 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2784 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2785 GET_CURRENT_CONTEXT(ctx
);
2786 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2788 if (ctx
->NewState
& _NEW_PIXEL
)
2789 gl_update_state(ctx
);
2791 adjust_texture_size_for_convolution(ctx
, 2, &postConvWidth
,&postConvHeight
);
2793 if (copytexsubimage_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2794 postConvWidth
, postConvHeight
))
2797 if (ctx
->_ImageTransferState
|| !ctx
->Driver
.CopyTexSubImage2D
2798 || !(*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
2799 xoffset
, yoffset
, x
, y
, width
, height
)) {
2800 struct gl_texture_unit
*texUnit
;
2801 struct gl_texture_image
*teximage
;
2802 struct gl_pixelstore_attrib unpackSave
;
2805 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2806 teximage
= texUnit
->Current2D
->Image
[level
];
2809 /* get image from frame buffer */
2810 image
= read_color_image(ctx
, x
, y
, width
, height
);
2812 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage2D" );
2816 /* now call glTexSubImage2D to do the real work */
2817 unpackSave
= ctx
->Unpack
;
2818 ctx
->Unpack
= _mesa_native_packing
;
2819 _mesa_TexSubImage2D(target
, level
, xoffset
, yoffset
, width
, height
,
2820 GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2821 ctx
->Unpack
= unpackSave
;
2830 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
2831 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2832 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2834 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2835 GET_CURRENT_CONTEXT(ctx
);
2836 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2838 if (ctx
->NewState
& _NEW_PIXEL
)
2839 gl_update_state(ctx
);
2841 adjust_texture_size_for_convolution(ctx
, 2, &postConvWidth
,&postConvHeight
);
2843 if (copytexsubimage_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
,
2844 zoffset
, postConvWidth
, postConvHeight
))
2847 if (ctx
->_ImageTransferState
|| !ctx
->Driver
.CopyTexSubImage3D
2848 || !(*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
2849 xoffset
, yoffset
, zoffset
, x
, y
, width
, height
)) {
2850 struct gl_texture_unit
*texUnit
;
2851 struct gl_texture_image
*teximage
;
2852 struct gl_pixelstore_attrib unpackSave
;
2855 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2856 teximage
= texUnit
->Current3D
->Image
[level
];
2859 /* get image from frame buffer */
2860 image
= read_color_image(ctx
, x
, y
, width
, height
);
2862 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage2D" );
2866 /* now call glTexSubImage2D to do the real work */
2867 unpackSave
= ctx
->Unpack
;
2868 ctx
->Unpack
= _mesa_native_packing
;
2869 _mesa_TexSubImage3D(target
, level
, xoffset
, yoffset
, zoffset
,
2870 width
, height
, 1, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2871 ctx
->Unpack
= unpackSave
;
2880 _mesa_CompressedTexImage1DARB(GLenum target
, GLint level
,
2881 GLenum internalFormat
, GLsizei width
,
2882 GLint border
, GLsizei imageSize
,
2885 GET_CURRENT_CONTEXT(ctx
);
2886 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2888 switch (internalFormat
) {
2889 case GL_COMPRESSED_ALPHA_ARB
:
2890 case GL_COMPRESSED_LUMINANCE_ARB
:
2891 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2892 case GL_COMPRESSED_INTENSITY_ARB
:
2893 case GL_COMPRESSED_RGB_ARB
:
2894 case GL_COMPRESSED_RGBA_ARB
:
2895 gl_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB");
2898 /* silence compiler warning */
2902 if (target
== GL_TEXTURE_1D
) {
2903 struct gl_texture_unit
*texUnit
;
2904 struct gl_texture_object
*texObj
;
2905 struct gl_texture_image
*texImage
;
2906 GLsizei computedImageSize
;
2908 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2909 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
2910 return; /* error in texture image was detected */
2913 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2914 texObj
= texUnit
->Current1D
;
2915 texImage
= texObj
->Image
[level
];
2918 texImage
= _mesa_alloc_texture_image();
2919 texObj
->Image
[level
] = texImage
;
2921 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage1DARB");
2925 else if (texImage
->Data
) {
2926 FREE(texImage
->Data
);
2927 texImage
->Data
= NULL
;
2930 /* setup the teximage struct's fields */
2931 init_texture_image(ctx
, texImage
, width
, 1, 1,
2932 border
, internalFormat
);
2934 /* process the texture image */
2936 GLboolean retain
= GL_TRUE
;
2937 GLboolean success
= GL_FALSE
;
2938 if (ctx
->Driver
.CompressedTexImage1D
) {
2939 success
= (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
,
2940 imageSize
, data
, texObj
, texImage
, &retain
);
2942 if (retain
|| !success
) {
2943 /* make internal copy of the texture image */
2944 computedImageSize
= _mesa_compressed_image_size(ctx
,
2950 if (computedImageSize
!= imageSize
) {
2951 gl_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexImage1DARB(imageSize)");
2954 texImage
->Data
= MALLOC(computedImageSize
);
2955 if (texImage
->Data
) {
2956 MEMCPY(texImage
->Data
, data
, computedImageSize
);
2959 if (!retain
&& texImage
->Data
) {
2960 FREE(texImage
->Data
);
2961 texImage
->Data
= NULL
;
2965 make_null_texture(texImage
);
2966 if (ctx
->Driver
.CompressedTexImage1D
) {
2968 (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
, 0,
2969 texImage
->Data
, texObj
,
2975 texObj
->Complete
= GL_FALSE
;
2976 ctx
->NewState
|= _NEW_TEXTURE
;
2978 else if (target
== GL_PROXY_TEXTURE_1D
) {
2979 /* Proxy texture: check for errors and update proxy state */
2980 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2981 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
);
2982 if (!error
&& ctx
->Driver
.TestProxyTexImage
) {
2983 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2984 internalFormat
, GL_NONE
, GL_NONE
,
2985 width
, 1, 1, border
);
2988 /* if error, clear all proxy texture image parameters */
2989 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
2990 clear_proxy_teximage(ctx
->Texture
.Proxy1D
->Image
[level
]);
2994 /* if no error, update proxy texture image parameters */
2995 init_texture_image(ctx
, ctx
->Texture
.Proxy1D
->Image
[level
],
2996 width
, 1, 1, border
, internalFormat
);
3000 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB(target)" );
3007 _mesa_CompressedTexImage2DARB(GLenum target
, GLint level
,
3008 GLenum internalFormat
, GLsizei width
,
3009 GLsizei height
, GLint border
, GLsizei imageSize
,
3012 GET_CURRENT_CONTEXT(ctx
);
3013 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
3015 switch (internalFormat
) {
3016 case GL_COMPRESSED_ALPHA_ARB
:
3017 case GL_COMPRESSED_LUMINANCE_ARB
:
3018 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
3019 case GL_COMPRESSED_INTENSITY_ARB
:
3020 case GL_COMPRESSED_RGB_ARB
:
3021 case GL_COMPRESSED_RGBA_ARB
:
3022 gl_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB");
3025 /* silence compiler warning */
3029 if (target
==GL_TEXTURE_2D
||
3030 (ctx
->Extensions
.ARB_texture_cube_map
&&
3031 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
3032 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
3033 struct gl_texture_unit
*texUnit
;
3034 struct gl_texture_object
*texObj
;
3035 struct gl_texture_image
*texImage
;
3036 GLsizei computedImageSize
;
3038 if (texture_error_check(ctx
, target
, level
, internalFormat
,
3039 GL_NONE
, GL_NONE
, 1, width
, height
, 1, border
)) {
3040 return; /* error in texture image was detected */
3043 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3044 texObj
= texUnit
->Current2D
;
3045 texImage
= texObj
->Image
[level
];
3048 texImage
= _mesa_alloc_texture_image();
3049 texObj
->Image
[level
] = texImage
;
3051 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
3055 else if (texImage
->Data
) {
3056 FREE(texImage
->Data
);
3057 texImage
->Data
= NULL
;
3060 /* setup the teximage struct's fields */
3061 init_texture_image(ctx
, texImage
, width
, height
, 1, border
, internalFormat
);
3063 /* process the texture image */
3065 GLboolean retain
= GL_TRUE
;
3066 GLboolean success
= GL_FALSE
;
3067 if (ctx
->Driver
.CompressedTexImage2D
) {
3068 success
= (*ctx
->Driver
.CompressedTexImage2D
)( ctx
,
3077 if (retain
|| !success
) {
3078 /* make internal copy of the texture image */
3079 computedImageSize
= _mesa_compressed_image_size(ctx
,
3085 if (computedImageSize
!= imageSize
) {
3086 gl_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexImage2DARB(imageSize)");
3089 texImage
->Data
= MALLOC(computedImageSize
);
3090 if (texImage
->Data
) {
3091 MEMCPY(texImage
->Data
, data
, computedImageSize
);
3094 if (!retain
&& texImage
->Data
) {
3095 FREE(texImage
->Data
);
3096 texImage
->Data
= NULL
;
3100 make_null_texture(texImage
);
3101 if (ctx
->Driver
.CompressedTexImage2D
) {
3103 (*ctx
->Driver
.CompressedTexImage2D
)( ctx
, target
, level
, 0,
3104 texImage
->Data
, texObj
,
3110 texObj
->Complete
= GL_FALSE
;
3111 ctx
->NewState
|= _NEW_TEXTURE
;
3113 else if (target
== GL_PROXY_TEXTURE_2D
) {
3114 /* Proxy texture: check for errors and update proxy state */
3115 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
3116 GL_NONE
, GL_NONE
, 2, width
, height
, 1, border
);
3117 if (!error
&& ctx
->Driver
.TestProxyTexImage
) {
3118 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
3119 internalFormat
, GL_NONE
, GL_NONE
,
3120 width
, height
, 1, border
);
3123 /* if error, clear all proxy texture image parameters */
3124 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
3125 clear_proxy_teximage(ctx
->Texture
.Proxy2D
->Image
[level
]);
3129 /* if no error, update proxy texture image parameters */
3130 init_texture_image(ctx
, ctx
->Texture
.Proxy2D
->Image
[level
],
3131 width
, 1, 1, border
, internalFormat
);
3135 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB(target)" );
3142 _mesa_CompressedTexImage3DARB(GLenum target
, GLint level
,
3143 GLenum internalFormat
, GLsizei width
,
3144 GLsizei height
, GLsizei depth
, GLint border
,
3145 GLsizei imageSize
, const GLvoid
*data
)
3147 GET_CURRENT_CONTEXT(ctx
);
3148 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
3150 switch (internalFormat
) {
3151 case GL_COMPRESSED_ALPHA_ARB
:
3152 case GL_COMPRESSED_LUMINANCE_ARB
:
3153 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
3154 case GL_COMPRESSED_INTENSITY_ARB
:
3155 case GL_COMPRESSED_RGB_ARB
:
3156 case GL_COMPRESSED_RGBA_ARB
:
3157 gl_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB");
3160 /* silence compiler warning */
3164 if (target
== GL_TEXTURE_3D
) {
3165 struct gl_texture_unit
*texUnit
;
3166 struct gl_texture_object
*texObj
;
3167 struct gl_texture_image
*texImage
;
3168 GLsizei computedImageSize
;
3170 if (texture_error_check(ctx
, target
, level
, internalFormat
,
3171 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
)) {
3172 return; /* error in texture image was detected */
3175 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3176 texObj
= texUnit
->Current3D
;
3177 texImage
= texObj
->Image
[level
];
3180 texImage
= _mesa_alloc_texture_image();
3181 texObj
->Image
[level
] = texImage
;
3183 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage3DARB");
3187 else if (texImage
->Data
) {
3188 FREE(texImage
->Data
);
3189 texImage
->Data
= NULL
;
3192 /* setup the teximage struct's fields */
3193 init_texture_image(ctx
, texImage
, width
, height
, depth
,
3194 border
, internalFormat
);
3196 /* process the texture image */
3198 GLboolean retain
= GL_TRUE
;
3199 GLboolean success
= GL_FALSE
;
3200 if (ctx
->Driver
.CompressedTexImage3D
) {
3201 success
= (*ctx
->Driver
.CompressedTexImage3D
)(ctx
, target
, level
,
3206 if (retain
|| !success
) {
3207 /* make internal copy of the texture image */
3208 computedImageSize
= _mesa_compressed_image_size(ctx
,
3214 if (computedImageSize
!= imageSize
) {
3215 gl_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexImage3DARB(imageSize)");
3218 texImage
->Data
= MALLOC(computedImageSize
);
3219 if (texImage
->Data
) {
3220 MEMCPY(texImage
->Data
, data
, computedImageSize
);
3223 if (!retain
&& texImage
->Data
) {
3224 FREE(texImage
->Data
);
3225 texImage
->Data
= NULL
;
3229 make_null_texture(texImage
);
3230 if (ctx
->Driver
.CompressedTexImage3D
) {
3232 (*ctx
->Driver
.CompressedTexImage3D
)( ctx
, target
, level
, 0,
3233 texImage
->Data
, texObj
,
3239 texObj
->Complete
= GL_FALSE
;
3240 ctx
->NewState
|= _NEW_TEXTURE
;
3242 else if (target
== GL_PROXY_TEXTURE_3D
) {
3243 /* Proxy texture: check for errors and update proxy state */
3244 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
3245 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
);
3246 if (!error
&& ctx
->Driver
.TestProxyTexImage
) {
3247 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
3248 internalFormat
, GL_NONE
, GL_NONE
,
3249 width
, height
, depth
, border
);
3252 /* if error, clear all proxy texture image parameters */
3253 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
3254 clear_proxy_teximage(ctx
->Texture
.Proxy3D
->Image
[level
]);
3258 /* if no error, update proxy texture image parameters */
3259 init_texture_image(ctx
, ctx
->Texture
.Proxy3D
->Image
[level
],
3260 width
, 1, 1, border
, internalFormat
);
3264 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB(target)" );
3271 _mesa_CompressedTexSubImage1DARB(GLenum target
, GLint level
, GLint xoffset
,
3272 GLsizei width
, GLenum format
,
3273 GLsizei imageSize
, const GLvoid
*data
)
3275 GET_CURRENT_CONTEXT(ctx
);
3276 struct gl_texture_unit
*texUnit
;
3277 struct gl_texture_object
*texObj
;
3278 struct gl_texture_image
*texImage
;
3279 GLboolean success
= GL_FALSE
;
3281 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
3282 width
, 1, 1, format
, GL_NONE
)) {
3283 return; /* error was detected */
3286 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3287 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
3288 texImage
= texObj
->Image
[level
];
3291 if (width
== 0 || !data
)
3292 return; /* no-op, not an error */
3294 if (ctx
->Driver
.CompressedTexSubImage1D
) {
3295 success
= (*ctx
->Driver
.CompressedTexSubImage1D
)(ctx
, target
, level
,
3296 xoffset
, width
, format
, imageSize
, data
, texObj
, texImage
);
3299 /* XXX what else can we do? */
3300 gl_problem(ctx
, "glCompressedTexSubImage1DARB failed!");
3307 _mesa_CompressedTexSubImage2DARB(GLenum target
, GLint level
, GLint xoffset
,
3308 GLint yoffset
, GLsizei width
, GLsizei height
,
3309 GLenum format
, GLsizei imageSize
,
3312 GET_CURRENT_CONTEXT(ctx
);
3313 struct gl_texture_unit
*texUnit
;
3314 struct gl_texture_object
*texObj
;
3315 struct gl_texture_image
*texImage
;
3316 GLboolean success
= GL_FALSE
;
3318 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
3319 width
, height
, 1, format
, GL_NONE
)) {
3320 return; /* error was detected */
3323 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3324 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
3325 texImage
= texObj
->Image
[level
];
3328 if (width
== 0 || height
== 0 || !data
)
3329 return; /* no-op, not an error */
3331 if (ctx
->Driver
.CompressedTexSubImage2D
) {
3332 success
= (*ctx
->Driver
.CompressedTexSubImage2D
)(ctx
, target
, level
,
3333 xoffset
, yoffset
, width
, height
, format
,
3334 imageSize
, data
, texObj
, texImage
);
3337 /* XXX what else can we do? */
3338 gl_problem(ctx
, "glCompressedTexSubImage2DARB failed!");
3345 _mesa_CompressedTexSubImage3DARB(GLenum target
, GLint level
, GLint xoffset
,
3346 GLint yoffset
, GLint zoffset
, GLsizei width
,
3347 GLsizei height
, GLsizei depth
, GLenum format
,
3348 GLsizei imageSize
, const GLvoid
*data
)
3350 GET_CURRENT_CONTEXT(ctx
);
3351 struct gl_texture_unit
*texUnit
;
3352 struct gl_texture_object
*texObj
;
3353 struct gl_texture_image
*texImage
;
3354 GLboolean success
= GL_FALSE
;
3356 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
3357 width
, height
, depth
, format
, GL_NONE
)) {
3358 return; /* error was detected */
3361 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3362 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
3363 texImage
= texObj
->Image
[level
];
3366 if (width
== 0 || height
== 0 || depth
== 0 || !data
)
3367 return; /* no-op, not an error */
3369 if (ctx
->Driver
.CompressedTexSubImage3D
) {
3370 success
= (*ctx
->Driver
.CompressedTexSubImage3D
)(ctx
, target
, level
,
3371 xoffset
, yoffset
, zoffset
, width
, height
, depth
,
3372 format
, imageSize
, data
, texObj
, texImage
);
3375 /* XXX what else can we do? */
3376 gl_problem(ctx
, "glCompressedTexSubImage3DARB failed!");
3383 _mesa_GetCompressedTexImageARB(GLenum target
, GLint level
, GLvoid
*img
)
3385 GET_CURRENT_CONTEXT(ctx
);
3386 const struct gl_texture_object
*texObj
;
3387 struct gl_texture_image
*texImage
;
3389 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
3391 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
3392 gl_error( ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)" );
3398 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].Current1D
;
3399 texImage
= texObj
->Image
[level
];
3402 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].Current2D
;
3403 texImage
= texObj
->Image
[level
];
3405 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
3406 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3407 texImage
= texObj
->Image
[level
];
3409 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
3410 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3411 texImage
= texObj
->NegX
[level
];
3413 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
3414 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3415 texImage
= texObj
->PosY
[level
];
3417 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
3418 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3419 texImage
= texObj
->NegY
[level
];
3421 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
3422 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3423 texImage
= texObj
->PosZ
[level
];
3425 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
3426 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3427 texImage
= texObj
->NegZ
[level
];
3430 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].Current3D
;
3431 texImage
= texObj
->Image
[level
];
3434 gl_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB(target)");
3439 /* invalid mipmap level */
3440 gl_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
3444 if (!texImage
->IsCompressed
) {
3445 gl_error(ctx
, GL_INVALID_OPERATION
, "glGetCompressedTexImageARB");
3452 if (ctx
->Driver
.GetCompressedTexImage
) {
3453 (*ctx
->Driver
.GetCompressedTexImage
)(ctx
, target
, level
, img
, texObj
,
3457 gl_problem(ctx
, "Driver doesn't implement GetCompressedTexImage");