1 /* $Id: teximage.c,v 1.56 2000/10/30 13:32:01 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.
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
->CurrentD
[1];
548 case GL_PROXY_TEXTURE_1D
:
549 return ctx
->Texture
.Proxy1D
;
551 return texUnit
->CurrentD
[2];
552 case GL_PROXY_TEXTURE_2D
:
553 return ctx
->Texture
.Proxy2D
;
555 return texUnit
->CurrentD
[3];
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
->CurrentD
[1]->Image
[level
];
588 case GL_PROXY_TEXTURE_1D
:
589 return ctx
->Texture
.Proxy1D
->Image
[level
];
591 return texUnit
->CurrentD
[2]->Image
[level
];
592 case GL_PROXY_TEXTURE_2D
:
593 return ctx
->Texture
.Proxy2D
->Image
[level
];
595 return texUnit
->CurrentD
[3]->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
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
) {
928 _mesa_update_image_transfer_state(ctx
);
931 if (ctx
->ImageTransferState
& IMAGE_CONVOLUTION_BIT
) {
932 adjust_texture_size_for_convolution(ctx
, dimensions
,
933 &convWidth
, &convHeight
);
936 texImage
->Data
= (GLchan
*) MALLOC(convWidth
* convHeight
* depth
937 * components
* sizeof(GLchan
) + EXTRA_BYTE
);
939 return; /* out of memory */
941 fill_texture_image(ctx
, dimensions
, texImage
->Format
, texImage
->Data
,
942 width
, height
, depth
, 0, 0, 0,
943 convWidth
* components
* sizeof(GLchan
),
944 convWidth
* convHeight
* components
* sizeof(GLchan
),
945 srcFormat
, srcType
, pixels
, srcPacking
);
951 * glTexImage[123]D can accept a NULL image pointer. In this case we
952 * create a texture image with unspecified image contents per the OpenGL
953 * spec. This function creates an empty image for the given texture image.
956 make_null_texture( struct gl_texture_image
*texImage
)
962 ASSERT(!texImage
->Data
);
964 components
= components_in_intformat(texImage
->IntFormat
);
965 numPixels
= texImage
->Width
* texImage
->Height
* texImage
->Depth
;
967 texImage
->Data
= (GLchan
*) MALLOC( numPixels
* components
* sizeof(GLchan
)
971 * Let's see if anyone finds this. If glTexImage2D() is called with
972 * a NULL image pointer then load the texture image with something
973 * interesting instead of leaving it indeterminate.
975 if (texImage
->Data
) {
976 static const char message
[8][32] = {
980 " X X XXXX XXX XXXXX ",
983 " X X XXXXX XXX X X ",
987 GLchan
*imgPtr
= texImage
->Data
;
989 for (i
= 0; i
< texImage
->Height
; i
++) {
990 GLint srcRow
= 7 - i
% 8;
991 for (j
= 0; j
< texImage
->Width
; j
++) {
992 GLint srcCol
= j
% 32;
993 GLint texel
= (message
[srcRow
][srcCol
]=='X') ? CHAN_MAX
: 70;
994 for (k
=0;k
<components
;k
++) {
995 *imgPtr
++ = (GLchan
) texel
;
1005 * This is called when a proxy texture test fails, we set all the
1006 * image members (except DriverData) to zero.
1009 clear_proxy_teximage(struct gl_texture_image
*img
)
1018 img
->IntensityBits
= 0;
1019 img
->LuminanceBits
= 0;
1029 img
->HeightLog2
= 0;
1032 img
->IsCompressed
= 0;
1033 img
->CompressedSize
= 0;
1039 * Test glTexImage[123]D() parameters for errors.
1041 * dimensions - must be 1 or 2 or 3
1042 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
1045 texture_error_check( GLcontext
*ctx
, GLenum target
,
1046 GLint level
, GLint internalFormat
,
1047 GLenum format
, GLenum type
,
1049 GLint width
, GLint height
,
1050 GLint depth
, GLint border
)
1055 if (dimensions
== 1) {
1056 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_1D
);
1057 if (target
!= GL_TEXTURE_1D
&& !isProxy
) {
1058 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1062 else if (dimensions
== 2) {
1063 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_2D
);
1064 if (target
!= GL_TEXTURE_2D
&& !isProxy
&&
1065 !(ctx
->Extensions
.ARB_texture_cube_map
&&
1066 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1067 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
1068 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1072 else if (dimensions
== 3) {
1073 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_3D
);
1074 if (target
!= GL_TEXTURE_3D
&& !isProxy
) {
1075 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1080 gl_problem( ctx
, "bad dims in texture_error_check" );
1085 if (border
!= 0 && border
!= 1) {
1088 sprintf(message
, "glTexImage%dD(border)", dimensions
);
1089 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1095 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
1096 || logbase2( width
- 2 * border
) < 0) {
1099 sprintf(message
, "glTexImage%dD(width)", dimensions
);
1100 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1106 if (dimensions
>= 2) {
1107 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
1108 || logbase2( height
- 2 * border
) < 0) {
1111 sprintf(message
, "glTexImage%dD(height)", dimensions
);
1112 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1118 /* For cube map, width must equal height */
1119 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1120 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
1121 if (width
!= height
) {
1123 gl_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
1130 if (dimensions
>= 3) {
1131 if (depth
< 2 * border
|| depth
> 2 + ctx
->Const
.MaxTextureSize
1132 || logbase2( depth
- 2 * border
) < 0) {
1134 gl_error( ctx
, GL_INVALID_VALUE
, "glTexImage3D(depth)" );
1141 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1144 sprintf(message
, "glTexImage%dD(level)", dimensions
);
1145 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1150 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
1154 sprintf(message
, "glTexImage%dD(internalFormat)", dimensions
);
1155 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1160 if (!is_compressed_format(ctx
, internalFormat
)) {
1161 if (!_mesa_is_legal_format_and_type( format
, type
)) {
1162 /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
1163 * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
1167 sprintf(message
, "glTexImage%dD(format or type)", dimensions
);
1168 gl_error(ctx
, GL_INVALID_OPERATION
, message
);
1174 /* if we get here, the parameters are OK */
1181 * Test glTexSubImage[123]D() parameters for errors.
1183 * dimensions - must be 1 or 2 or 3
1184 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
1187 subtexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
1188 GLenum target
, GLint level
,
1189 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1190 GLint width
, GLint height
, GLint depth
,
1191 GLenum format
, GLenum type
)
1193 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1194 struct gl_texture_image
*destTex
;
1196 if (dimensions
== 1) {
1197 if (target
!= GL_TEXTURE_1D
) {
1198 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(target)" );
1202 else if (dimensions
== 2) {
1203 if (ctx
->Extensions
.ARB_texture_cube_map
) {
1204 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1205 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1206 target
!= GL_TEXTURE_2D
) {
1207 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
1211 else if (target
!= GL_TEXTURE_2D
) {
1212 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
1216 else if (dimensions
== 3) {
1217 if (target
!= GL_TEXTURE_3D
) {
1218 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3D(target)" );
1223 gl_problem( ctx
, "bad dims in texture_error_check" );
1227 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1228 gl_error(ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(level)");
1234 sprintf(message
, "glTexSubImage%dD(width)", dimensions
);
1235 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1238 if (height
< 0 && dimensions
> 1) {
1240 sprintf(message
, "glTexSubImage%dD(height)", dimensions
);
1241 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1244 if (depth
< 0 && dimensions
> 2) {
1246 sprintf(message
, "glTexSubImage%dD(depth)", dimensions
);
1247 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1251 destTex
= texUnit
->CurrentD
[2]->Image
[level
];
1253 gl_error(ctx
, GL_INVALID_OPERATION
, "glTexSubImage2D");
1257 if (xoffset
< -((GLint
)destTex
->Border
)) {
1258 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset)");
1261 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
1262 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset+width)");
1265 if (dimensions
> 1) {
1266 if (yoffset
< -((GLint
)destTex
->Border
)) {
1267 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset)");
1270 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
1271 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset+height)");
1275 if (dimensions
> 2) {
1276 if (zoffset
< -((GLint
)destTex
->Border
)) {
1277 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset)");
1280 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+destTex
->Border
)) {
1281 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset+depth)");
1286 if (!is_compressed_format(ctx
, destTex
->IntFormat
)) {
1287 if (!_mesa_is_legal_format_and_type(format
, type
)) {
1289 sprintf(message
, "glTexSubImage%dD(format or type)", dimensions
);
1290 gl_error(ctx
, GL_INVALID_ENUM
, message
);
1300 * Test glCopyTexImage[12]D() parameters for errors.
1301 * Input: dimensions - must be 1 or 2 or 3
1302 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
1305 copytexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
1306 GLenum target
, GLint level
, GLint internalFormat
,
1307 GLint width
, GLint height
, GLint border
)
1311 if (dimensions
== 1) {
1312 if (target
!= GL_TEXTURE_1D
) {
1313 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
1317 else if (dimensions
== 2) {
1318 if (ctx
->Extensions
.ARB_texture_cube_map
) {
1319 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1320 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1321 target
!= GL_TEXTURE_2D
) {
1322 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1326 else if (target
!= GL_TEXTURE_2D
) {
1327 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1333 if (border
!=0 && border
!=1) {
1335 sprintf(message
, "glCopyTexImage%dD(border)", dimensions
);
1336 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1341 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
1342 || logbase2( width
- 2 * border
) < 0) {
1344 sprintf(message
, "glCopyTexImage%dD(width)", dimensions
);
1345 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1350 if (dimensions
>= 2) {
1351 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
1352 || logbase2( height
- 2 * border
) < 0) {
1354 sprintf(message
, "glCopyTexImage%dD(height)", dimensions
);
1355 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1360 /* For cube map, width must equal height */
1361 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1362 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
1363 if (width
!= height
) {
1364 gl_error(ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(width != height)");
1370 if (level
<0 || level
>=ctx
->Const
.MaxTextureLevels
) {
1372 sprintf(message
, "glCopyTexImage%dD(level)", dimensions
);
1373 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1377 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
1380 sprintf(message
, "glCopyTexImage%dD(internalFormat)", dimensions
);
1381 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1385 /* if we get here, the parameters are OK */
1391 copytexsubimage_error_check( GLcontext
*ctx
, GLuint dimensions
,
1392 GLenum target
, GLint level
,
1393 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1394 GLsizei width
, GLsizei height
)
1396 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1397 struct gl_texture_image
*teximage
;
1399 if (dimensions
== 1) {
1400 if (target
!= GL_TEXTURE_1D
) {
1401 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
1405 else if (dimensions
== 2) {
1406 if (ctx
->Extensions
.ARB_texture_cube_map
) {
1407 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1408 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1409 target
!= GL_TEXTURE_2D
) {
1410 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1414 else if (target
!= GL_TEXTURE_2D
) {
1415 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1419 else if (dimensions
== 3) {
1420 if (target
!= GL_TEXTURE_3D
) {
1421 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3D(target)" );
1426 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1428 sprintf(message
, "glCopyTexSubImage%dD(level)", dimensions
);
1429 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1435 sprintf(message
, "glCopyTexSubImage%dD(width)", dimensions
);
1436 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1439 if (dimensions
> 1 && height
< 0) {
1441 sprintf(message
, "glCopyTexSubImage%dD(height)", dimensions
);
1442 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1446 teximage
= texUnit
->CurrentD
[dimensions
]->Image
[level
];
1449 sprintf(message
, "glCopyTexSubImage%dD(undefined texture)", dimensions
);
1450 gl_error(ctx
, GL_INVALID_OPERATION
, message
);
1454 if (xoffset
< -((GLint
)teximage
->Border
)) {
1456 sprintf(message
, "glCopyTexSubImage%dD(xoffset)", dimensions
);
1457 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1460 if (xoffset
+width
> (GLint
) (teximage
->Width
+teximage
->Border
)) {
1462 sprintf(message
, "glCopyTexSubImage%dD(xoffset+width)", dimensions
);
1463 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1466 if (dimensions
> 1) {
1467 if (yoffset
< -((GLint
)teximage
->Border
)) {
1469 sprintf(message
, "glCopyTexSubImage%dD(yoffset)", dimensions
);
1470 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1473 /* NOTE: we're adding the border here, not subtracting! */
1474 if (yoffset
+height
> (GLint
) (teximage
->Height
+teximage
->Border
)) {
1476 sprintf(message
, "glCopyTexSubImage%dD(yoffset+height)", dimensions
);
1477 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1482 if (dimensions
> 2) {
1483 if (zoffset
< -((GLint
)teximage
->Border
)) {
1485 sprintf(message
, "glCopyTexSubImage%dD(zoffset)", dimensions
);
1486 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1489 if (zoffset
> (GLint
) (teximage
->Depth
+teximage
->Border
)) {
1491 sprintf(message
, "glCopyTexSubImage%dD(zoffset+depth)", dimensions
);
1492 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1497 /* if we get here, the parameters are OK */
1505 * Turn generic compressed formats into specific compressed format.
1506 * Some of the compressed formats we don't support, so we
1507 * fall back to the uncompressed format. (See issue 15 of
1508 * the GL_ARB_texture_compression specification.)
1511 get_specific_compressed_tex_format(GLcontext
*ctx
,
1512 GLint ifmt
, GLint numDimensions
,
1522 GLint internalFormat
= ifmt
;
1524 if (ctx
->Extensions
.ARB_texture_compression
1525 && ctx
->Driver
.SpecificCompressedTexFormat
) {
1527 * First, ask the driver for the specific format.
1528 * We do this for all formats, since we may want to
1529 * fake one compressed format for another.
1531 internalFormat
= (*ctx
->Driver
.SpecificCompressedTexFormat
)
1532 (ctx
, internalFormat
, numDimensions
,
1534 widthp
, heightp
, depthp
,
1535 borderp
, formatp
, typep
);
1539 * Now, convert any generic format left to an uncompressed
1540 * specific format. If the driver does not support compression
1541 * of the format, we must drop back to the uncompressed format.
1542 * See issue 15 of the GL_ARB_texture_compression specification.
1544 switch (internalFormat
) {
1545 case GL_COMPRESSED_ALPHA_ARB
:
1546 if (ctx
&& !ctx
->Extensions
.ARB_texture_compression
) {
1547 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1548 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1551 internalFormat
= GL_ALPHA
;
1553 case GL_COMPRESSED_LUMINANCE_ARB
:
1554 if (ctx
&& !ctx
->Extensions
.ARB_texture_compression
) {
1555 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1556 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1559 internalFormat
= GL_LUMINANCE
;
1561 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
1562 if (ctx
&& !ctx
->Extensions
.ARB_texture_compression
) {
1563 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1564 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1567 internalFormat
= GL_LUMINANCE_ALPHA
;
1569 case GL_COMPRESSED_INTENSITY_ARB
:
1570 if (ctx
&& !ctx
->Extensions
.ARB_texture_compression
) {
1571 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1572 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1575 internalFormat
= GL_INTENSITY
;
1577 case GL_COMPRESSED_RGB_ARB
:
1578 if (ctx
&& !ctx
->Extensions
.ARB_texture_compression
) {
1579 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1580 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1583 internalFormat
= GL_RGB
;
1585 case GL_COMPRESSED_RGBA_ARB
:
1586 if (ctx
&& !ctx
->Extensions
.ARB_texture_compression
) {
1587 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1588 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1591 internalFormat
= GL_RGBA
;
1594 /* silence compiler warning */
1597 return internalFormat
;
1602 * Called from the API. Note that width includes the border.
1605 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
1606 GLsizei width
, GLint border
, GLenum format
,
1607 GLenum type
, const GLvoid
*pixels
)
1609 GLsizei postConvWidth
;
1610 GET_CURRENT_CONTEXT(ctx
);
1611 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glTexImage1D");
1613 postConvWidth
= width
;
1614 adjust_texture_size_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1616 if (target
==GL_TEXTURE_1D
) {
1617 struct gl_texture_unit
*texUnit
;
1618 struct gl_texture_object
*texObj
;
1619 struct gl_texture_image
*texImage
;
1622 ifmt
= get_specific_compressed_tex_format(ctx
, internalFormat
, 1,
1625 &border
, &format
, &type
);
1628 * The error here is that we were sent a generic compressed
1629 * format, but the extension is not supported.
1634 internalFormat
= ifmt
;
1637 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1638 format
, type
, 1, postConvWidth
, 1, 1, border
)) {
1639 return; /* error in texture image was detected */
1642 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1643 texObj
= texUnit
->CurrentD
[1];
1644 texImage
= texObj
->Image
[level
];
1647 texImage
= _mesa_alloc_texture_image();
1648 texObj
->Image
[level
] = texImage
;
1650 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
1654 else if (texImage
->Data
) {
1655 FREE(texImage
->Data
);
1656 texImage
->Data
= NULL
;
1659 /* setup the teximage struct's fields */
1660 init_texture_image(ctx
, texImage
, postConvWidth
, 1, 1, border
, internalFormat
);
1662 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
1663 _mesa_update_image_transfer_state(ctx
);
1665 /* process the texture image */
1667 GLboolean retain
= GL_TRUE
;
1668 GLboolean success
= GL_FALSE
;
1669 if (!ctx
->ImageTransferState
&& ctx
->Driver
.TexImage1D
) {
1670 /* let device driver try to use raw image */
1671 success
= (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, format
,
1672 type
, pixels
, &ctx
->Unpack
,
1673 texObj
, texImage
, &retain
);
1675 if (retain
|| !success
) {
1676 /* make internal copy of the texture image */
1677 make_texture_image(ctx
, 1, texImage
, width
, 1, 1,
1678 format
, type
, pixels
, &ctx
->Unpack
);
1679 if (!success
&& ctx
->Driver
.TexImage1D
) {
1680 /* let device driver try to use unpacked image */
1681 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
1682 GL_UNSIGNED_BYTE
, texImage
->Data
,
1683 &_mesa_native_packing
,
1684 texObj
, texImage
, &retain
);
1687 if (!retain
&& texImage
->Data
) {
1688 FREE(texImage
->Data
);
1689 texImage
->Data
= NULL
;
1693 make_null_texture(texImage
);
1694 if (ctx
->Driver
.TexImage1D
) {
1696 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
1697 GL_UNSIGNED_BYTE
, texImage
->Data
,
1698 &_mesa_native_packing
,
1699 texObj
, texImage
, &retain
);
1704 gl_put_texobj_on_dirty_list( ctx
, texObj
);
1705 ctx
->NewState
|= _NEW_TEXTURE
;
1707 else if (target
== GL_PROXY_TEXTURE_1D
) {
1708 /* Proxy texture: check for errors and update proxy state */
1709 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1710 format
, type
, 1, width
, 1, 1, border
);
1711 if (!error
&& ctx
->Driver
.TestProxyTexImage
) {
1712 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1713 internalFormat
, format
, type
,
1714 width
, 1, 1, border
);
1717 /* if error, clear all proxy texture image parameters */
1718 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1719 clear_proxy_teximage(ctx
->Texture
.Proxy1D
->Image
[level
]);
1723 /* if no error, update proxy texture image parameters */
1724 init_texture_image(ctx
, ctx
->Texture
.Proxy1D
->Image
[level
],
1725 width
, 1, 1, border
, internalFormat
);
1729 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1736 _mesa_TexImage2D( GLenum target
, GLint level
, GLint internalFormat
,
1737 GLsizei width
, GLsizei height
, GLint border
,
1738 GLenum format
, GLenum type
,
1739 const GLvoid
*pixels
)
1741 GLsizei postConvWidth
, postConvHeight
;
1742 GET_CURRENT_CONTEXT(ctx
);
1743 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glTexImage2D");
1745 postConvWidth
= width
;
1746 postConvHeight
= height
;
1747 adjust_texture_size_for_convolution(ctx
, 2, &postConvWidth
,&postConvHeight
);
1749 if (target
==GL_TEXTURE_2D
||
1750 (ctx
->Extensions
.ARB_texture_cube_map
&&
1751 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1752 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
1753 struct gl_texture_unit
*texUnit
;
1754 struct gl_texture_object
*texObj
;
1755 struct gl_texture_image
*texImage
;
1758 ifmt
= get_specific_compressed_tex_format(ctx
, internalFormat
, 2,
1761 &border
, &format
, &type
);
1764 * The error here is that we were sent a generic compressed
1765 * format, but the extension is not supported.
1770 internalFormat
= ifmt
;
1773 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1774 format
, type
, 2, postConvWidth
, postConvHeight
,
1776 return; /* error in texture image was detected */
1779 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1780 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1781 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1784 texImage
= _mesa_alloc_texture_image();
1785 set_tex_image(texObj
, target
, level
, texImage
);
1786 /*texObj->Image[level] = texImage;*/
1788 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1792 else if (texImage
->Data
) {
1793 FREE(texImage
->Data
);
1794 texImage
->Data
= NULL
;
1797 /* setup the teximage struct's fields */
1798 init_texture_image(ctx
, texImage
, postConvWidth
, postConvHeight
,
1799 1, border
, internalFormat
);
1801 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
1802 _mesa_update_image_transfer_state(ctx
);
1804 /* process the texture image */
1806 GLboolean retain
= GL_TRUE
;
1807 GLboolean success
= GL_FALSE
;
1808 if (!ctx
->ImageTransferState
&& ctx
->Driver
.TexImage2D
) {
1809 /* let device driver try to use raw image */
1810 success
= (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, format
,
1811 type
, pixels
, &ctx
->Unpack
,
1812 texObj
, texImage
, &retain
);
1814 if (retain
|| !success
) {
1815 /* make internal copy of the texture image */
1816 make_texture_image(ctx
, 2, texImage
, width
, height
, 1,
1817 format
, type
, pixels
, &ctx
->Unpack
);
1818 if (!success
&& ctx
->Driver
.TexImage2D
) {
1819 /* let device driver try to use unpacked image */
1820 (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, texImage
->Format
,
1821 GL_UNSIGNED_BYTE
, texImage
->Data
,
1822 &_mesa_native_packing
,
1823 texObj
, texImage
, &retain
);
1826 if (!retain
&& texImage
->Data
) {
1827 FREE(texImage
->Data
);
1828 texImage
->Data
= NULL
;
1832 make_null_texture(texImage
);
1833 if (ctx
->Driver
.TexImage2D
) {
1835 (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, texImage
->Format
,
1836 GL_UNSIGNED_BYTE
, texImage
->Data
,
1837 &_mesa_native_packing
,
1838 texObj
, texImage
, &retain
);
1842 #define OLD_DD_TEXTURE
1843 #ifdef OLD_DD_TEXTURE
1844 /* XXX this will be removed in the future */
1845 if (ctx
->Driver
.TexImage
) {
1846 (*ctx
->Driver
.TexImage
)( ctx
, target
, texObj
, level
, internalFormat
,
1852 gl_put_texobj_on_dirty_list( ctx
, texObj
);
1853 ctx
->NewState
|= _NEW_TEXTURE
;
1855 else if (target
== GL_PROXY_TEXTURE_2D
) {
1856 /* Proxy texture: check for errors and update proxy state */
1857 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1858 format
, type
, 2, width
, height
, 1, border
);
1859 if (!error
&& ctx
->Driver
.TestProxyTexImage
) {
1860 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1861 internalFormat
, format
, type
,
1862 width
, height
, 1, border
);
1865 /* if error, clear all proxy texture image parameters */
1866 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1867 clear_proxy_teximage(ctx
->Texture
.Proxy2D
->Image
[level
]);
1871 /* if no error, update proxy texture image parameters */
1872 init_texture_image(ctx
,
1873 ctx
->Texture
.Proxy2D
->Image
[level
],
1874 width
, height
, 1, border
, internalFormat
);
1878 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1885 * Called by the API or display list executor.
1886 * Note that width and height include the border.
1889 _mesa_TexImage3D( GLenum target
, GLint level
, GLint internalFormat
,
1890 GLsizei width
, GLsizei height
, GLsizei depth
,
1891 GLint border
, GLenum format
, GLenum type
,
1892 const GLvoid
*pixels
)
1894 GET_CURRENT_CONTEXT(ctx
);
1895 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glTexImage3D");
1897 if (target
==GL_TEXTURE_3D_EXT
) {
1898 struct gl_texture_unit
*texUnit
;
1899 struct gl_texture_object
*texObj
;
1900 struct gl_texture_image
*texImage
;
1903 ifmt
= get_specific_compressed_tex_format(ctx
, internalFormat
, 3,
1905 &width
, &height
, &depth
,
1906 &border
, &format
, &type
);
1909 * The error here is that we were sent a generic compressed
1910 * format, but the extension is not supported.
1915 internalFormat
= ifmt
;
1918 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1919 format
, type
, 3, width
, height
, depth
, border
)) {
1920 return; /* error in texture image was detected */
1923 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1924 texObj
= texUnit
->CurrentD
[3];
1925 texImage
= texObj
->Image
[level
];
1928 texImage
= _mesa_alloc_texture_image();
1929 texObj
->Image
[level
] = texImage
;
1931 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
1935 else if (texImage
->Data
) {
1936 FREE(texImage
->Data
);
1937 texImage
->Data
= NULL
;
1940 /* setup the teximage struct's fields */
1941 init_texture_image(ctx
, texImage
, width
, height
, depth
,
1942 border
, internalFormat
);
1944 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
1945 _mesa_update_image_transfer_state(ctx
);
1947 /* process the texture image */
1949 GLboolean retain
= GL_TRUE
;
1950 GLboolean success
= GL_FALSE
;
1951 if (!ctx
->ImageTransferState
&& ctx
->Driver
.TexImage3D
) {
1952 /* let device driver try to use raw image */
1953 success
= (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, format
,
1954 type
, pixels
, &ctx
->Unpack
,
1955 texObj
, texImage
, &retain
);
1957 if (retain
|| !success
) {
1958 /* make internal copy of the texture image */
1959 make_texture_image(ctx
, 3, texImage
, width
, height
, depth
,
1960 format
, type
, pixels
, &ctx
->Unpack
);
1961 if (!success
&& ctx
->Driver
.TexImage3D
) {
1962 /* let device driver try to use unpacked image */
1963 (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, texImage
->Format
,
1964 GL_UNSIGNED_BYTE
, texImage
->Data
,
1965 &_mesa_native_packing
,
1966 texObj
, texImage
, &retain
);
1969 if (!retain
&& texImage
->Data
) {
1970 FREE(texImage
->Data
);
1971 texImage
->Data
= NULL
;
1975 make_null_texture(texImage
);
1976 if (ctx
->Driver
.TexImage3D
) {
1978 (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, texImage
->Format
,
1979 GL_UNSIGNED_BYTE
, texImage
->Data
,
1980 &_mesa_native_packing
,
1981 texObj
, texImage
, &retain
);
1986 gl_put_texobj_on_dirty_list( ctx
, texObj
);
1987 ctx
->NewState
|= _NEW_TEXTURE
;
1989 else if (target
== GL_PROXY_TEXTURE_3D
) {
1990 /* Proxy texture: check for errors and update proxy state */
1991 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1992 format
, type
, 3, width
, height
, depth
, border
);
1993 if (!error
&& ctx
->Driver
.TestProxyTexImage
) {
1994 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1995 internalFormat
, format
, type
,
1996 width
, height
, depth
, border
);
1999 /* if error, clear all proxy texture image parameters */
2000 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
2001 clear_proxy_teximage(ctx
->Texture
.Proxy3D
->Image
[level
]);
2005 /* if no error, update proxy texture image parameters */
2006 init_texture_image(ctx
, ctx
->Texture
.Proxy3D
->Image
[level
],
2007 width
, height
, depth
, border
, internalFormat
);
2011 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
2018 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
2019 GLsizei width
, GLsizei height
, GLsizei depth
,
2020 GLint border
, GLenum format
, GLenum type
,
2021 const GLvoid
*pixels
)
2023 _mesa_TexImage3D(target
, level
, (GLint
) internalFormat
, width
, height
,
2024 depth
, border
, format
, type
, pixels
);
2029 * Fetch a texture image from the device driver.
2030 * Store the results in the given texture object at the given mipmap level.
2033 _mesa_get_teximage_from_driver( GLcontext
*ctx
, GLenum target
, GLint level
,
2034 const struct gl_texture_object
*texObj
)
2037 GLenum imgFormat
, imgType
;
2038 GLboolean freeImage
;
2039 struct gl_texture_image
*texImage
;
2040 GLint destComponents
, numPixels
, srcBytesPerTexel
;
2042 if (!ctx
->Driver
.GetTexImage
)
2045 image
= (*ctx
->Driver
.GetTexImage
)( ctx
, target
, level
, texObj
,
2046 &imgFormat
, &imgType
, &freeImage
);
2050 texImage
= texObj
->Image
[level
];
2055 destComponents
= components_in_intformat(texImage
->Format
);
2056 assert(destComponents
> 0);
2057 numPixels
= texImage
->Width
* texImage
->Height
* texImage
->Depth
;
2058 assert(numPixels
> 0);
2059 srcBytesPerTexel
= _mesa_bytes_per_pixel(imgFormat
, imgType
);
2060 assert(srcBytesPerTexel
> 0);
2062 if (!texImage
->Data
) {
2063 /* Allocate memory for the texture image data */
2064 texImage
->Data
= (GLchan
*) MALLOC(numPixels
* destComponents
2065 * sizeof(GLchan
) + EXTRA_BYTE
);
2068 if (imgFormat
== texImage
->Format
&& imgType
== GL_UNSIGNED_BYTE
) {
2069 /* We got lucky! The driver's format and type match Mesa's format. */
2070 if (texImage
->Data
) {
2071 MEMCPY(texImage
->Data
, image
, numPixels
* destComponents
);
2075 /* Convert the texture image from the driver's format to Mesa's
2078 const GLint width
= texImage
->Width
;
2079 const GLint height
= texImage
->Height
;
2080 const GLint depth
= texImage
->Depth
;
2081 const GLint destBytesPerRow
= width
* destComponents
* sizeof(GLchan
);
2082 const GLint srcBytesPerRow
= width
* srcBytesPerTexel
;
2083 const GLenum dstType
= GL_UNSIGNED_BYTE
;
2084 const GLenum dstFormat
= texImage
->Format
;
2085 const GLchan
*srcPtr
= (const GLchan
*) image
;
2086 GLchan
*destPtr
= texImage
->Data
;
2088 if (texImage
->Format
== GL_COLOR_INDEX
) {
2089 /* color index texture */
2091 assert(imgFormat
== GL_COLOR_INDEX
);
2092 for (img
= 0; img
< depth
; img
++) {
2093 for (row
= 0; row
< height
; row
++) {
2094 _mesa_unpack_index_span(ctx
, width
, dstType
, destPtr
,
2095 imgType
, srcPtr
, &_mesa_native_packing
, GL_FALSE
);
2096 destPtr
+= destBytesPerRow
;
2097 srcPtr
+= srcBytesPerRow
;
2104 for (img
= 0; img
< depth
; img
++) {
2105 for (row
= 0; row
< height
; row
++) {
2106 _mesa_unpack_chan_color_span(ctx
, width
, dstFormat
, destPtr
,
2107 imgFormat
, imgType
, srcPtr
, &_mesa_native_packing
, GL_FALSE
);
2108 destPtr
+= destBytesPerRow
;
2109 srcPtr
+= srcBytesPerRow
;
2121 * Get all the mipmap images for a texture object from the device driver.
2122 * Actually, only get mipmap images if we're using a mipmap filter.
2125 _mesa_get_teximages_from_driver(GLcontext
*ctx
,
2126 struct gl_texture_object
*texObj
)
2128 if (ctx
->Driver
.GetTexImage
) {
2129 static const GLenum targets
[] = {
2133 GL_TEXTURE_CUBE_MAP_ARB
,
2134 GL_TEXTURE_CUBE_MAP_ARB
,
2135 GL_TEXTURE_CUBE_MAP_ARB
2137 GLboolean needLambda
= (texObj
->MinFilter
!= texObj
->MagFilter
);
2138 GLenum target
= targets
[texObj
->Dimensions
- 1];
2141 /* Get images for all mipmap levels. We might not need them
2142 * all but this is easier. We're on a (slow) software path
2145 for (level
= 0; level
<= texObj
->P
; level
++) {
2146 struct gl_texture_image
*texImg
= texObj
->Image
[level
];
2147 if (texImg
&& !texImg
->Data
) {
2148 _mesa_get_teximage_from_driver(ctx
, target
, level
, texObj
);
2150 return GL_FALSE
; /* out of memory */
2155 GLint level
= texObj
->BaseLevel
;
2156 struct gl_texture_image
*texImg
= texObj
->Image
[level
];
2157 if (texImg
&& !texImg
->Data
) {
2158 _mesa_get_teximage_from_driver(ctx
, target
, level
, texObj
);
2160 return GL_FALSE
; /* out of memory */
2171 _mesa_GetTexImage( GLenum target
, GLint level
, GLenum format
,
2172 GLenum type
, GLvoid
*pixels
)
2174 GET_CURRENT_CONTEXT(ctx
);
2175 const struct gl_texture_unit
*texUnit
;
2176 const struct gl_texture_object
*texObj
;
2177 struct gl_texture_image
*texImage
;
2178 GLboolean discardImage
;
2180 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetTexImage");
2182 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
2183 gl_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
2187 if (_mesa_sizeof_type(type
) <= 0) {
2188 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
2192 if (_mesa_components_in_format(format
) <= 0) {
2193 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
2200 texUnit
= &(ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
]);
2201 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2202 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2203 if (!texObj
|| !texImage
||
2204 target
== GL_PROXY_TEXTURE_1D
||
2205 target
== GL_PROXY_TEXTURE_2D
||
2206 target
== GL_PROXY_TEXTURE_3D
) {
2207 gl_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)");
2212 /* invalid mipmap level */
2216 if (!texImage
->Data
) {
2217 /* try to get the texture image from the device driver */
2218 _mesa_get_teximage_from_driver(ctx
, target
, level
, texObj
);
2219 discardImage
= GL_TRUE
;
2222 discardImage
= GL_FALSE
;
2225 if (texImage
->Data
) {
2226 GLint width
= texImage
->Width
;
2227 GLint height
= texImage
->Height
;
2228 GLint depth
= texImage
->Depth
;
2231 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
2232 _mesa_update_image_transfer_state(ctx
);
2234 if (ctx
->ImageTransferState
& IMAGE_CONVOLUTION_BIT
) {
2235 /* convert texture image to GL_RGBA, GL_FLOAT */
2236 GLfloat
*tmpImage
, *convImage
;
2237 const GLint comps
= components_in_intformat(texImage
->Format
);
2239 tmpImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
2241 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
2244 convImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
2247 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glGetTexImage");
2251 for (img
= 0; img
< depth
; img
++) {
2252 GLint convWidth
, convHeight
;
2254 /* convert to GL_RGBA */
2255 for (row
= 0; row
< height
; row
++) {
2256 const GLchan
*src
= texImage
->Data
2257 + (img
* height
+ row
) * width
* comps
;
2258 GLfloat
*dst
= tmpImage
+ row
* width
* 4;
2259 _mesa_unpack_float_color_span(ctx
, width
, GL_RGBA
, dst
,
2260 texImage
->Format
, GL_UNSIGNED_BYTE
,
2261 src
, &_mesa_native_packing
,
2262 ctx
->ImageTransferState
& IMAGE_PRE_CONVOLUTION_BITS
,
2267 convHeight
= height
;
2270 if (target
== GL_TEXTURE_1D
) {
2271 if (ctx
->Pixel
.Convolution1DEnabled
) {
2272 _mesa_convolve_1d_image(ctx
, &convWidth
, tmpImage
, convImage
);
2276 if (ctx
->Pixel
.Convolution2DEnabled
) {
2277 _mesa_convolve_2d_image(ctx
, &convWidth
, &convHeight
,
2278 tmpImage
, convImage
);
2280 else if (ctx
->Pixel
.Separable2DEnabled
) {
2281 _mesa_convolve_sep_image(ctx
, &convWidth
, &convHeight
,
2282 tmpImage
, convImage
);
2286 /* pack convolved image */
2287 for (row
= 0; row
< convHeight
; row
++) {
2288 const GLfloat
*src
= convImage
+ row
* convWidth
* 4;
2289 GLvoid
*dest
= _mesa_image_address(&ctx
->Pack
, pixels
,
2290 convWidth
, convHeight
,
2291 format
, type
, img
, row
, 0);
2292 _mesa_pack_float_rgba_span(ctx
, convWidth
,
2293 (const GLfloat(*)[4]) src
,
2294 format
, type
, dest
, &ctx
->Pack
,
2295 ctx
->ImageTransferState
& IMAGE_POST_CONVOLUTION_BITS
);
2303 /* no convolution */
2304 for (img
= 0; img
< depth
; img
++) {
2305 for (row
= 0; row
< height
; row
++) {
2306 /* compute destination address in client memory */
2307 GLvoid
*dest
= _mesa_image_address( &ctx
->Unpack
, pixels
,
2308 width
, height
, format
, type
, img
, row
, 0);
2310 if (texImage
->Format
== GL_RGBA
) {
2312 const GLchan
*src
= texImage
->Data
2313 + (img
* height
+ row
) * width
* 4;
2314 _mesa_pack_rgba_span( ctx
, width
, (CONST
GLchan (*)[4]) src
,
2315 format
, type
, dest
, &ctx
->Pack
,
2316 ctx
->ImageTransferState
);
2319 /* general case: convert row to RGBA format */
2320 GLchan rgba
[MAX_WIDTH
][4];
2323 switch (texImage
->Format
) {
2325 src
= texImage
->Data
+ row
* width
;
2326 for (i
= 0; i
< width
; i
++) {
2327 rgba
[i
][RCOMP
] = CHAN_MAX
;
2328 rgba
[i
][GCOMP
] = CHAN_MAX
;
2329 rgba
[i
][BCOMP
] = CHAN_MAX
;
2330 rgba
[i
][ACOMP
] = src
[i
];
2334 src
= texImage
->Data
+ row
* width
;
2335 for (i
= 0; i
< width
; i
++) {
2336 rgba
[i
][RCOMP
] = src
[i
];
2337 rgba
[i
][GCOMP
] = src
[i
];
2338 rgba
[i
][BCOMP
] = src
[i
];
2339 rgba
[i
][ACOMP
] = CHAN_MAX
;
2342 case GL_LUMINANCE_ALPHA
:
2343 src
= texImage
->Data
+ row
* 2 * width
;
2344 for (i
= 0; i
< width
; i
++) {
2345 rgba
[i
][RCOMP
] = src
[i
*2+0];
2346 rgba
[i
][GCOMP
] = src
[i
*2+0];
2347 rgba
[i
][BCOMP
] = src
[i
*2+0];
2348 rgba
[i
][ACOMP
] = src
[i
*2+1];
2352 src
= texImage
->Data
+ row
* width
;
2353 for (i
= 0; i
< width
; i
++) {
2354 rgba
[i
][RCOMP
] = src
[i
];
2355 rgba
[i
][GCOMP
] = src
[i
];
2356 rgba
[i
][BCOMP
] = src
[i
];
2357 rgba
[i
][ACOMP
] = CHAN_MAX
;
2361 src
= texImage
->Data
+ row
* 3 * width
;
2362 for (i
= 0; i
< width
; i
++) {
2363 rgba
[i
][RCOMP
] = src
[i
*3+0];
2364 rgba
[i
][GCOMP
] = src
[i
*3+1];
2365 rgba
[i
][BCOMP
] = src
[i
*3+2];
2366 rgba
[i
][ACOMP
] = CHAN_MAX
;
2369 case GL_COLOR_INDEX
:
2370 gl_problem( ctx
, "GL_COLOR_INDEX not implemented in gl_GetTexImage" );
2374 gl_problem( ctx
, "bad format in gl_GetTexImage" );
2376 _mesa_pack_rgba_span( ctx
, width
, (const GLchan (*)[4])rgba
,
2377 format
, type
, dest
, &ctx
->Pack
,
2378 ctx
->ImageTransferState
);
2384 /* if we got the teximage from the device driver we'll discard it now */
2386 FREE(texImage
->Data
);
2387 texImage
->Data
= NULL
;
2395 _mesa_TexSubImage1D( GLenum target
, GLint level
,
2396 GLint xoffset
, GLsizei width
,
2397 GLenum format
, GLenum type
,
2398 const GLvoid
*pixels
)
2400 GET_CURRENT_CONTEXT(ctx
);
2401 struct gl_texture_unit
*texUnit
;
2402 struct gl_texture_object
*texObj
;
2403 struct gl_texture_image
*texImage
;
2404 GLboolean success
= GL_FALSE
;
2405 GLsizei postConvWidth
;
2407 postConvWidth
= width
;
2408 adjust_texture_size_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
2410 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
2411 postConvWidth
, 1, 1, format
, type
)) {
2412 return; /* error was detected */
2415 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2416 texObj
= texUnit
->CurrentD
[1];
2417 texImage
= texObj
->Image
[level
];
2420 if (width
== 0 || !pixels
)
2421 return; /* no-op, not an error */
2423 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
2424 _mesa_update_image_transfer_state(ctx
);
2426 if (!ctx
->ImageTransferState
&& ctx
->Driver
.TexSubImage1D
) {
2427 success
= (*ctx
->Driver
.TexSubImage1D
)( ctx
, target
, level
, xoffset
,
2428 width
, format
, type
, pixels
,
2429 &ctx
->Unpack
, texObj
, texImage
);
2432 /* XXX if Driver.TexSubImage1D, unpack image and try again? */
2433 GLboolean retain
= GL_TRUE
;
2434 if (!texImage
->Data
) {
2435 _mesa_get_teximage_from_driver( ctx
, target
, level
, texObj
);
2436 if (!texImage
->Data
) {
2437 make_null_texture(texImage
);
2439 if (!texImage
->Data
)
2440 return; /* we're really out of luck! */
2443 fill_texture_image(ctx
, 1, texImage
->Format
, texImage
->Data
,
2444 width
, 1, 1, xoffset
, 0, 0, /* size and offsets */
2446 format
, type
, pixels
, &ctx
->Unpack
);
2448 if (ctx
->Driver
.TexImage1D
) {
2449 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
2450 GL_UNSIGNED_BYTE
, texImage
->Data
,
2451 &_mesa_native_packing
, texObj
, texImage
,
2455 if (!retain
&& texImage
->Data
) {
2456 FREE(texImage
->Data
);
2457 texImage
->Data
= NULL
;
2464 _mesa_TexSubImage2D( GLenum target
, GLint level
,
2465 GLint xoffset
, GLint yoffset
,
2466 GLsizei width
, GLsizei height
,
2467 GLenum format
, GLenum type
,
2468 const GLvoid
*pixels
)
2470 GET_CURRENT_CONTEXT(ctx
);
2471 struct gl_texture_unit
*texUnit
;
2472 struct gl_texture_object
*texObj
;
2473 struct gl_texture_image
*texImage
;
2474 GLboolean success
= GL_FALSE
;
2475 GLsizei postConvWidth
, postConvHeight
;
2477 postConvWidth
= width
;
2478 postConvHeight
= height
;
2479 adjust_texture_size_for_convolution(ctx
, 2, &postConvWidth
,&postConvHeight
);
2481 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2482 postConvWidth
, postConvHeight
, 1, format
, type
)) {
2483 return; /* error was detected */
2486 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2487 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2488 texImage
= texObj
->Image
[level
];
2491 if (width
== 0 || height
== 0 || !pixels
)
2492 return; /* no-op, not an error */
2494 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
2495 _mesa_update_image_transfer_state(ctx
);
2497 if (!ctx
->ImageTransferState
&& ctx
->Driver
.TexSubImage2D
) {
2498 success
= (*ctx
->Driver
.TexSubImage2D
)( ctx
, target
, level
, xoffset
,
2499 yoffset
, width
, height
, format
, type
,
2500 pixels
, &ctx
->Unpack
, texObj
, texImage
);
2503 /* XXX if Driver.TexSubImage2D, unpack image and try again? */
2504 const GLint texComps
= components_in_intformat(texImage
->Format
);
2505 const GLint texRowStride
= texImage
->Width
* texComps
;
2506 GLboolean retain
= GL_TRUE
;
2508 if (!texImage
->Data
) {
2509 _mesa_get_teximage_from_driver( ctx
, target
, level
, texObj
);
2510 if (!texImage
->Data
) {
2511 make_null_texture(texImage
);
2513 if (!texImage
->Data
)
2514 return; /* we're really out of luck! */
2517 fill_texture_image(ctx
, 2, texImage
->Format
, texImage
->Data
,
2518 width
, height
, 1, xoffset
, yoffset
, 0,
2520 format
, type
, pixels
, &ctx
->Unpack
);
2522 if (ctx
->Driver
.TexImage2D
) {
2523 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, texImage
->Format
,
2524 GL_UNSIGNED_BYTE
, texImage
->Data
,
2525 &_mesa_native_packing
, texObj
, texImage
,
2529 if (!retain
&& texImage
->Data
) {
2530 FREE(texImage
->Data
);
2531 texImage
->Data
= NULL
;
2534 #ifdef OLD_DD_TEXTURE
2535 /* XXX this will be removed in the future */
2536 if (ctx
->Driver
.TexSubImage
) {
2537 (*ctx
->Driver
.TexSubImage
)(ctx
, target
, texObj
, level
,
2538 xoffset
, yoffset
, width
, height
,
2539 texImage
->IntFormat
, texImage
);
2541 else if (ctx
->Driver
.TexImage
) {
2542 (*ctx
->Driver
.TexImage
)(ctx
, GL_TEXTURE_2D
, texObj
,
2543 level
, texImage
->IntFormat
, texImage
);
2552 _mesa_TexSubImage3D( GLenum target
, GLint level
,
2553 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2554 GLsizei width
, GLsizei height
, GLsizei depth
,
2555 GLenum format
, GLenum type
,
2556 const GLvoid
*pixels
)
2558 GET_CURRENT_CONTEXT(ctx
);
2559 struct gl_texture_unit
*texUnit
;
2560 struct gl_texture_object
*texObj
;
2561 struct gl_texture_image
*texImage
;
2562 GLboolean success
= GL_FALSE
;
2564 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2565 width
, height
, depth
, format
, type
)) {
2566 return; /* error was detected */
2569 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2570 texObj
= texUnit
->CurrentD
[3];
2571 texImage
= texObj
->Image
[level
];
2574 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
2575 return; /* no-op, not an error */
2577 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
2578 _mesa_update_image_transfer_state(ctx
);
2580 if (!ctx
->ImageTransferState
&& ctx
->Driver
.TexSubImage3D
) {
2581 success
= (*ctx
->Driver
.TexSubImage3D
)( ctx
, target
, level
, xoffset
,
2582 yoffset
, zoffset
, width
, height
, depth
, format
,
2583 type
, pixels
, &ctx
->Unpack
, texObj
, texImage
);
2586 /* XXX if Driver.TexSubImage3D, unpack image and try again? */
2587 const GLint texComps
= components_in_intformat(texImage
->Format
);
2588 const GLint texRowStride
= texImage
->Width
* texComps
;
2589 const GLint texImgStride
= texRowStride
* texImage
->Height
;
2590 GLboolean retain
= GL_TRUE
;
2592 if (!texImage
->Data
) {
2593 _mesa_get_teximage_from_driver( ctx
, target
, level
, texObj
);
2594 if (!texImage
->Data
) {
2595 make_null_texture(texImage
);
2597 if (!texImage
->Data
)
2598 return; /* we're really out of luck! */
2601 fill_texture_image(ctx
, 3, texImage
->Format
, texImage
->Data
,
2602 width
, height
, depth
, xoffset
, yoffset
, zoffset
,
2603 texRowStride
, texImgStride
,
2604 format
, type
, pixels
, &ctx
->Unpack
);
2606 if (ctx
->Driver
.TexImage3D
) {
2607 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, texImage
->Format
,
2608 GL_UNSIGNED_BYTE
, texImage
->Data
,
2609 &_mesa_native_packing
, texObj
, texImage
,
2613 if (!retain
&& texImage
->Data
) {
2614 FREE(texImage
->Data
);
2615 texImage
->Data
= NULL
;
2623 * Read an RGBA image from the frame buffer.
2624 * This is used by glCopyTex[Sub]Image[12]D().
2625 * Input: ctx - the context
2626 * x, y - lower left corner
2627 * width, height - size of region to read
2628 * Return: pointer to block of GL_RGBA, GLchan data.
2631 read_color_image( GLcontext
*ctx
, GLint x
, GLint y
,
2632 GLsizei width
, GLsizei height
)
2635 GLchan
*image
, *dst
;
2637 image
= (GLchan
*) MALLOC(width
* height
* 4 * sizeof(GLchan
));
2641 /* Select buffer to read from */
2642 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->ReadBuffer
,
2643 ctx
->Pixel
.DriverReadBuffer
);
2647 for (i
= 0; i
< height
; i
++) {
2648 gl_read_rgba_span( ctx
, ctx
->ReadBuffer
, width
, x
, y
+ i
,
2649 (GLchan (*)[4]) dst
);
2653 /* Read from draw buffer (the default) */
2654 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->DrawBuffer
,
2655 ctx
->Color
.DriverDrawBuffer
);
2663 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
2664 GLenum internalFormat
,
2666 GLsizei width
, GLint border
)
2668 GET_CURRENT_CONTEXT(ctx
);
2669 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexImage1D");
2671 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
2675 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
2676 _mesa_update_image_transfer_state(ctx
);
2678 if (ctx
->ImageTransferState
|| !ctx
->Driver
.CopyTexImage1D
2679 || !(*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
,
2680 internalFormat
, x
, y
, width
, border
)) {
2681 struct gl_pixelstore_attrib unpackSave
;
2683 /* get image from framebuffer */
2684 GLchan
*image
= read_color_image( ctx
, x
, y
, width
, 1 );
2686 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D" );
2690 /* call glTexImage1D to redefine the texture */
2691 unpackSave
= ctx
->Unpack
;
2692 ctx
->Unpack
= _mesa_native_packing
;
2693 (*ctx
->Exec
->TexImage1D
)( target
, level
, internalFormat
, width
,
2694 border
, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2695 ctx
->Unpack
= unpackSave
;
2704 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
2705 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
2708 GET_CURRENT_CONTEXT(ctx
);
2709 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexImage2D");
2711 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
2712 width
, height
, border
))
2715 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
2716 _mesa_update_image_transfer_state(ctx
);
2718 if (ctx
->ImageTransferState
|| !ctx
->Driver
.CopyTexImage2D
2719 || !(*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
,
2720 internalFormat
, x
, y
, width
, height
, border
)) {
2721 struct gl_pixelstore_attrib unpackSave
;
2723 /* get image from framebuffer */
2724 GLchan
*image
= read_color_image( ctx
, x
, y
, width
, height
);
2726 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D" );
2730 /* call glTexImage2D to redefine the texture */
2731 unpackSave
= ctx
->Unpack
;
2732 ctx
->Unpack
= _mesa_native_packing
;
2733 (ctx
->Exec
->TexImage2D
)( target
, level
, internalFormat
, width
,
2734 height
, border
, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2735 ctx
->Unpack
= unpackSave
;
2744 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
2745 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
2747 GET_CURRENT_CONTEXT(ctx
);
2748 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexSubImage1D");
2750 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
2751 xoffset
, 0, 0, width
, 1))
2754 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
2755 _mesa_update_image_transfer_state(ctx
);
2757 if (ctx
->ImageTransferState
|| !ctx
->Driver
.CopyTexSubImage1D
2758 || !(*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
,
2759 xoffset
, x
, y
, width
)) {
2760 struct gl_texture_unit
*texUnit
;
2761 struct gl_texture_image
*teximage
;
2762 struct gl_pixelstore_attrib unpackSave
;
2765 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2766 teximage
= texUnit
->CurrentD
[1]->Image
[level
];
2769 /* get image from frame buffer */
2770 image
= read_color_image(ctx
, x
, y
, width
, 1);
2772 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage2D" );
2776 /* now call glTexSubImage1D to do the real work */
2777 unpackSave
= ctx
->Unpack
;
2778 ctx
->Unpack
= _mesa_native_packing
;
2779 _mesa_TexSubImage1D(target
, level
, xoffset
, width
,
2780 GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2781 ctx
->Unpack
= unpackSave
;
2790 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
2791 GLint xoffset
, GLint yoffset
,
2792 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2794 GET_CURRENT_CONTEXT(ctx
);
2795 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexSubImage2D");
2797 if (copytexsubimage_error_check(ctx
, 2, target
, level
,
2798 xoffset
, yoffset
, 0, width
, height
))
2801 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
2802 _mesa_update_image_transfer_state(ctx
);
2804 if (ctx
->ImageTransferState
|| !ctx
->Driver
.CopyTexSubImage2D
2805 || !(*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
2806 xoffset
, yoffset
, x
, y
, width
, height
)) {
2807 struct gl_texture_unit
*texUnit
;
2808 struct gl_texture_image
*teximage
;
2809 struct gl_pixelstore_attrib unpackSave
;
2812 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2813 teximage
= texUnit
->CurrentD
[2]->Image
[level
];
2816 /* get image from frame buffer */
2817 image
= read_color_image(ctx
, x
, y
, width
, height
);
2819 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage2D" );
2823 /* now call glTexSubImage2D to do the real work */
2824 unpackSave
= ctx
->Unpack
;
2825 ctx
->Unpack
= _mesa_native_packing
;
2826 _mesa_TexSubImage2D(target
, level
, xoffset
, yoffset
, width
, height
,
2827 GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2828 ctx
->Unpack
= unpackSave
;
2837 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
2838 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2839 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2841 GET_CURRENT_CONTEXT(ctx
);
2842 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexSubImage3D");
2844 if (copytexsubimage_error_check(ctx
, 3, target
, level
,
2845 xoffset
, yoffset
, zoffset
, width
, height
))
2848 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
2849 _mesa_update_image_transfer_state(ctx
);
2851 if (ctx
->ImageTransferState
|| !ctx
->Driver
.CopyTexSubImage3D
2852 || !(*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
2853 xoffset
, yoffset
, zoffset
, x
, y
, width
, height
)) {
2854 struct gl_texture_unit
*texUnit
;
2855 struct gl_texture_image
*teximage
;
2856 struct gl_pixelstore_attrib unpackSave
;
2859 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2860 teximage
= texUnit
->CurrentD
[3]->Image
[level
];
2863 /* get image from frame buffer */
2864 image
= read_color_image(ctx
, x
, y
, width
, height
);
2866 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage2D" );
2870 /* now call glTexSubImage2D to do the real work */
2871 unpackSave
= ctx
->Unpack
;
2872 ctx
->Unpack
= _mesa_native_packing
;
2873 _mesa_TexSubImage3D(target
, level
, xoffset
, yoffset
, zoffset
,
2874 width
, height
, 1, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2875 ctx
->Unpack
= unpackSave
;
2884 _mesa_CompressedTexImage1DARB(GLenum target
, GLint level
,
2885 GLenum internalFormat
, GLsizei width
,
2886 GLint border
, GLsizei imageSize
,
2889 GET_CURRENT_CONTEXT(ctx
);
2890 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCompressedTexImage1DARB");
2892 switch (internalFormat
) {
2893 case GL_COMPRESSED_ALPHA_ARB
:
2894 case GL_COMPRESSED_LUMINANCE_ARB
:
2895 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2896 case GL_COMPRESSED_INTENSITY_ARB
:
2897 case GL_COMPRESSED_RGB_ARB
:
2898 case GL_COMPRESSED_RGBA_ARB
:
2899 gl_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB");
2902 /* silence compiler warning */
2906 if (target
== GL_TEXTURE_1D
) {
2907 struct gl_texture_unit
*texUnit
;
2908 struct gl_texture_object
*texObj
;
2909 struct gl_texture_image
*texImage
;
2910 GLsizei computedImageSize
;
2912 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2913 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
2914 return; /* error in texture image was detected */
2917 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2918 texObj
= texUnit
->CurrentD
[1];
2919 texImage
= texObj
->Image
[level
];
2922 texImage
= _mesa_alloc_texture_image();
2923 texObj
->Image
[level
] = texImage
;
2925 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage1DARB");
2929 else if (texImage
->Data
) {
2930 FREE(texImage
->Data
);
2931 texImage
->Data
= NULL
;
2934 /* setup the teximage struct's fields */
2935 init_texture_image(ctx
, texImage
, width
, 1, 1,
2936 border
, internalFormat
);
2938 /* process the texture image */
2940 GLboolean retain
= GL_TRUE
;
2941 GLboolean success
= GL_FALSE
;
2942 if (ctx
->Driver
.CompressedTexImage1D
) {
2943 success
= (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
,
2944 imageSize
, data
, texObj
, texImage
, &retain
);
2946 if (retain
|| !success
) {
2947 /* make internal copy of the texture image */
2948 computedImageSize
= _mesa_compressed_image_size(ctx
,
2954 if (computedImageSize
!= imageSize
) {
2955 gl_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexImage1DARB(imageSize)");
2958 texImage
->Data
= MALLOC(computedImageSize
);
2959 if (texImage
->Data
) {
2960 MEMCPY(texImage
->Data
, data
, computedImageSize
);
2963 if (!retain
&& texImage
->Data
) {
2964 FREE(texImage
->Data
);
2965 texImage
->Data
= NULL
;
2969 make_null_texture(texImage
);
2970 if (ctx
->Driver
.CompressedTexImage1D
) {
2972 (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
, 0,
2973 texImage
->Data
, texObj
,
2979 gl_put_texobj_on_dirty_list( ctx
, texObj
);
2980 ctx
->NewState
|= _NEW_TEXTURE
;
2982 else if (target
== GL_PROXY_TEXTURE_1D
) {
2983 /* Proxy texture: check for errors and update proxy state */
2984 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2985 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
);
2986 if (!error
&& ctx
->Driver
.TestProxyTexImage
) {
2987 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2988 internalFormat
, GL_NONE
, GL_NONE
,
2989 width
, 1, 1, border
);
2992 /* if error, clear all proxy texture image parameters */
2993 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
2994 clear_proxy_teximage(ctx
->Texture
.Proxy1D
->Image
[level
]);
2998 /* if no error, update proxy texture image parameters */
2999 init_texture_image(ctx
, ctx
->Texture
.Proxy1D
->Image
[level
],
3000 width
, 1, 1, border
, internalFormat
);
3004 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB(target)" );
3011 _mesa_CompressedTexImage2DARB(GLenum target
, GLint level
,
3012 GLenum internalFormat
, GLsizei width
,
3013 GLsizei height
, GLint border
, GLsizei imageSize
,
3016 GET_CURRENT_CONTEXT(ctx
);
3017 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCompressedTexImage2DARB");
3019 switch (internalFormat
) {
3020 case GL_COMPRESSED_ALPHA_ARB
:
3021 case GL_COMPRESSED_LUMINANCE_ARB
:
3022 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
3023 case GL_COMPRESSED_INTENSITY_ARB
:
3024 case GL_COMPRESSED_RGB_ARB
:
3025 case GL_COMPRESSED_RGBA_ARB
:
3026 gl_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB");
3029 /* silence compiler warning */
3033 if (target
==GL_TEXTURE_2D
||
3034 (ctx
->Extensions
.ARB_texture_cube_map
&&
3035 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
3036 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
3037 struct gl_texture_unit
*texUnit
;
3038 struct gl_texture_object
*texObj
;
3039 struct gl_texture_image
*texImage
;
3040 GLsizei computedImageSize
;
3042 if (texture_error_check(ctx
, target
, level
, internalFormat
,
3043 GL_NONE
, GL_NONE
, 1, width
, height
, 1, border
)) {
3044 return; /* error in texture image was detected */
3047 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3048 texObj
= texUnit
->CurrentD
[2];
3049 texImage
= texObj
->Image
[level
];
3052 texImage
= _mesa_alloc_texture_image();
3053 texObj
->Image
[level
] = texImage
;
3055 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
3059 else if (texImage
->Data
) {
3060 FREE(texImage
->Data
);
3061 texImage
->Data
= NULL
;
3064 /* setup the teximage struct's fields */
3065 init_texture_image(ctx
, texImage
, width
, height
, 1, border
, internalFormat
);
3067 /* process the texture image */
3069 GLboolean retain
= GL_TRUE
;
3070 GLboolean success
= GL_FALSE
;
3071 if (ctx
->Driver
.CompressedTexImage2D
) {
3072 success
= (*ctx
->Driver
.CompressedTexImage2D
)( ctx
,
3081 if (retain
|| !success
) {
3082 /* make internal copy of the texture image */
3083 computedImageSize
= _mesa_compressed_image_size(ctx
,
3089 if (computedImageSize
!= imageSize
) {
3090 gl_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexImage2DARB(imageSize)");
3093 texImage
->Data
= MALLOC(computedImageSize
);
3094 if (texImage
->Data
) {
3095 MEMCPY(texImage
->Data
, data
, computedImageSize
);
3098 if (!retain
&& texImage
->Data
) {
3099 FREE(texImage
->Data
);
3100 texImage
->Data
= NULL
;
3104 make_null_texture(texImage
);
3105 if (ctx
->Driver
.CompressedTexImage2D
) {
3107 (*ctx
->Driver
.CompressedTexImage2D
)( ctx
, target
, level
, 0,
3108 texImage
->Data
, texObj
,
3114 gl_put_texobj_on_dirty_list( ctx
, texObj
);
3115 ctx
->NewState
|= _NEW_TEXTURE
;
3117 else if (target
== GL_PROXY_TEXTURE_2D
) {
3118 /* Proxy texture: check for errors and update proxy state */
3119 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
3120 GL_NONE
, GL_NONE
, 2, width
, height
, 1, border
);
3121 if (!error
&& ctx
->Driver
.TestProxyTexImage
) {
3122 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
3123 internalFormat
, GL_NONE
, GL_NONE
,
3124 width
, height
, 1, border
);
3127 /* if error, clear all proxy texture image parameters */
3128 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
3129 clear_proxy_teximage(ctx
->Texture
.Proxy2D
->Image
[level
]);
3133 /* if no error, update proxy texture image parameters */
3134 init_texture_image(ctx
, ctx
->Texture
.Proxy2D
->Image
[level
],
3135 width
, 1, 1, border
, internalFormat
);
3139 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB(target)" );
3146 _mesa_CompressedTexImage3DARB(GLenum target
, GLint level
,
3147 GLenum internalFormat
, GLsizei width
,
3148 GLsizei height
, GLsizei depth
, GLint border
,
3149 GLsizei imageSize
, const GLvoid
*data
)
3151 GET_CURRENT_CONTEXT(ctx
);
3152 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCompressedTexImage3DARB");
3154 switch (internalFormat
) {
3155 case GL_COMPRESSED_ALPHA_ARB
:
3156 case GL_COMPRESSED_LUMINANCE_ARB
:
3157 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
3158 case GL_COMPRESSED_INTENSITY_ARB
:
3159 case GL_COMPRESSED_RGB_ARB
:
3160 case GL_COMPRESSED_RGBA_ARB
:
3161 gl_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB");
3164 /* silence compiler warning */
3168 if (target
== GL_TEXTURE_3D
) {
3169 struct gl_texture_unit
*texUnit
;
3170 struct gl_texture_object
*texObj
;
3171 struct gl_texture_image
*texImage
;
3172 GLsizei computedImageSize
;
3174 if (texture_error_check(ctx
, target
, level
, internalFormat
,
3175 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
)) {
3176 return; /* error in texture image was detected */
3179 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3180 texObj
= texUnit
->CurrentD
[3];
3181 texImage
= texObj
->Image
[level
];
3184 texImage
= _mesa_alloc_texture_image();
3185 texObj
->Image
[level
] = texImage
;
3187 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage3DARB");
3191 else if (texImage
->Data
) {
3192 FREE(texImage
->Data
);
3193 texImage
->Data
= NULL
;
3196 /* setup the teximage struct's fields */
3197 init_texture_image(ctx
, texImage
, width
, height
, depth
,
3198 border
, internalFormat
);
3200 /* process the texture image */
3202 GLboolean retain
= GL_TRUE
;
3203 GLboolean success
= GL_FALSE
;
3204 if (ctx
->Driver
.CompressedTexImage3D
) {
3205 success
= (*ctx
->Driver
.CompressedTexImage3D
)(ctx
, target
, level
,
3210 if (retain
|| !success
) {
3211 /* make internal copy of the texture image */
3212 computedImageSize
= _mesa_compressed_image_size(ctx
,
3218 if (computedImageSize
!= imageSize
) {
3219 gl_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexImage3DARB(imageSize)");
3222 texImage
->Data
= MALLOC(computedImageSize
);
3223 if (texImage
->Data
) {
3224 MEMCPY(texImage
->Data
, data
, computedImageSize
);
3227 if (!retain
&& texImage
->Data
) {
3228 FREE(texImage
->Data
);
3229 texImage
->Data
= NULL
;
3233 make_null_texture(texImage
);
3234 if (ctx
->Driver
.CompressedTexImage3D
) {
3236 (*ctx
->Driver
.CompressedTexImage3D
)( ctx
, target
, level
, 0,
3237 texImage
->Data
, texObj
,
3243 gl_put_texobj_on_dirty_list( ctx
, texObj
);
3244 ctx
->NewState
|= _NEW_TEXTURE
;
3246 else if (target
== GL_PROXY_TEXTURE_3D
) {
3247 /* Proxy texture: check for errors and update proxy state */
3248 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
3249 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
);
3250 if (!error
&& ctx
->Driver
.TestProxyTexImage
) {
3251 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
3252 internalFormat
, GL_NONE
, GL_NONE
,
3253 width
, height
, depth
, border
);
3256 /* if error, clear all proxy texture image parameters */
3257 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
3258 clear_proxy_teximage(ctx
->Texture
.Proxy3D
->Image
[level
]);
3262 /* if no error, update proxy texture image parameters */
3263 init_texture_image(ctx
, ctx
->Texture
.Proxy3D
->Image
[level
],
3264 width
, 1, 1, border
, internalFormat
);
3268 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB(target)" );
3275 _mesa_CompressedTexSubImage1DARB(GLenum target
, GLint level
, GLint xoffset
,
3276 GLsizei width
, GLenum format
,
3277 GLsizei imageSize
, const GLvoid
*data
)
3279 GET_CURRENT_CONTEXT(ctx
);
3280 struct gl_texture_unit
*texUnit
;
3281 struct gl_texture_object
*texObj
;
3282 struct gl_texture_image
*texImage
;
3283 GLboolean success
= GL_FALSE
;
3285 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
3286 width
, 1, 1, format
, GL_NONE
)) {
3287 return; /* error was detected */
3290 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3291 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
3292 texImage
= texObj
->Image
[level
];
3295 if (width
== 0 || !data
)
3296 return; /* no-op, not an error */
3298 if (ctx
->Driver
.CompressedTexSubImage1D
) {
3299 success
= (*ctx
->Driver
.CompressedTexSubImage1D
)(ctx
, target
, level
,
3300 xoffset
, width
, format
, imageSize
, data
, texObj
, texImage
);
3303 /* XXX what else can we do? */
3304 gl_problem(ctx
, "glCompressedTexSubImage1DARB failed!");
3311 _mesa_CompressedTexSubImage2DARB(GLenum target
, GLint level
, GLint xoffset
,
3312 GLint yoffset
, GLsizei width
, GLsizei height
,
3313 GLenum format
, GLsizei imageSize
,
3316 GET_CURRENT_CONTEXT(ctx
);
3317 struct gl_texture_unit
*texUnit
;
3318 struct gl_texture_object
*texObj
;
3319 struct gl_texture_image
*texImage
;
3320 GLboolean success
= GL_FALSE
;
3322 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
3323 width
, height
, 1, format
, GL_NONE
)) {
3324 return; /* error was detected */
3327 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3328 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
3329 texImage
= texObj
->Image
[level
];
3332 if (width
== 0 || height
== 0 || !data
)
3333 return; /* no-op, not an error */
3335 if (ctx
->Driver
.CompressedTexSubImage2D
) {
3336 success
= (*ctx
->Driver
.CompressedTexSubImage2D
)(ctx
, target
, level
,
3337 xoffset
, yoffset
, width
, height
, format
,
3338 imageSize
, data
, texObj
, texImage
);
3341 /* XXX what else can we do? */
3342 gl_problem(ctx
, "glCompressedTexSubImage2DARB failed!");
3349 _mesa_CompressedTexSubImage3DARB(GLenum target
, GLint level
, GLint xoffset
,
3350 GLint yoffset
, GLint zoffset
, GLsizei width
,
3351 GLsizei height
, GLsizei depth
, GLenum format
,
3352 GLsizei imageSize
, const GLvoid
*data
)
3354 GET_CURRENT_CONTEXT(ctx
);
3355 struct gl_texture_unit
*texUnit
;
3356 struct gl_texture_object
*texObj
;
3357 struct gl_texture_image
*texImage
;
3358 GLboolean success
= GL_FALSE
;
3360 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
3361 width
, height
, depth
, format
, GL_NONE
)) {
3362 return; /* error was detected */
3365 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3366 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
3367 texImage
= texObj
->Image
[level
];
3370 if (width
== 0 || height
== 0 || depth
== 0 || !data
)
3371 return; /* no-op, not an error */
3373 if (ctx
->Driver
.CompressedTexSubImage3D
) {
3374 success
= (*ctx
->Driver
.CompressedTexSubImage3D
)(ctx
, target
, level
,
3375 xoffset
, yoffset
, zoffset
, width
, height
, depth
,
3376 format
, imageSize
, data
, texObj
, texImage
);
3379 /* XXX what else can we do? */
3380 gl_problem(ctx
, "glCompressedTexSubImage3DARB failed!");
3387 _mesa_GetCompressedTexImageARB(GLenum target
, GLint level
, GLvoid
*img
)
3389 GET_CURRENT_CONTEXT(ctx
);
3390 const struct gl_texture_object
*texObj
;
3391 struct gl_texture_image
*texImage
;
3393 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetCompressedTexImageARB");
3395 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
3396 gl_error( ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)" );
3402 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[1];
3403 texImage
= texObj
->Image
[level
];
3406 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[2];
3407 texImage
= texObj
->Image
[level
];
3409 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
3410 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3411 texImage
= texObj
->Image
[level
];
3413 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
3414 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3415 texImage
= texObj
->NegX
[level
];
3417 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
3418 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3419 texImage
= texObj
->PosY
[level
];
3421 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
3422 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3423 texImage
= texObj
->NegY
[level
];
3425 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
3426 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3427 texImage
= texObj
->PosZ
[level
];
3429 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
3430 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3431 texImage
= texObj
->NegZ
[level
];
3434 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[3];
3435 texImage
= texObj
->Image
[level
];
3438 gl_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB(target)");
3443 /* invalid mipmap level */
3444 gl_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
3448 if (!texImage
->IsCompressed
) {
3449 gl_error(ctx
, GL_INVALID_OPERATION
, "glGetCompressedTexImageARB");
3456 if (ctx
->Driver
.GetCompressedTexImage
) {
3457 (*ctx
->Driver
.GetCompressedTexImage
)(ctx
, target
, level
, img
, texObj
,
3461 gl_problem(ctx
, "Driver doesn't implement GetCompressedTexImage");