1 /* $Id: teximage.c,v 1.43 2000/08/31 15:24:39 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
48 * Mesa's native texture datatype is GLubyte. Native formats are
49 * GL_ALPHA, GL_LUMINANCE, GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, GL_RGBA,
51 * Device drivers are free to implement any internal format they want.
56 static void PrintTexture(const struct gl_texture_image
*img
)
59 GLubyte
*data
= img
->Data
;
62 printf("No texture data\n");
66 switch (img
->Format
) {
73 case GL_LUMINANCE_ALPHA
:
83 gl_problem(NULL
, "error in PrintTexture\n");
88 for (i
= 0; i
< img
->Height
; i
++) {
89 for (j
= 0; j
< img
->Width
; j
++) {
91 printf("%02x ", data
[0]);
93 printf("%02x%02x ", data
[0], data
[1]);
95 printf("%02x%02x%02x ", data
[0], data
[1], data
[2]);
97 printf("%02x%02x%02x%02x ", data
[0], data
[1], data
[2], data
[3]);
108 * Compute log base 2 of n.
109 * If n isn't an exact power of two return -1.
137 * Given an internal texture format enum or 1, 2, 3, 4 return the
138 * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE,
139 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.
140 * Return -1 if invalid enum.
143 _mesa_base_tex_format( GLcontext
*ctx
, GLint format
)
146 * Ask the driver for the base format, if it doesn't
147 * know, it will return -1;
149 if (ctx
->Driver
.BaseCompressedTexFormat
) {
150 GLint ifmt
= (*ctx
->Driver
.BaseCompressedTexFormat
)(ctx
, format
);
170 case GL_LUMINANCE_ALPHA
:
171 case GL_LUMINANCE4_ALPHA4
:
172 case GL_LUMINANCE6_ALPHA2
:
173 case GL_LUMINANCE8_ALPHA8
:
174 case GL_LUMINANCE12_ALPHA4
:
175 case GL_LUMINANCE12_ALPHA12
:
176 case GL_LUMINANCE16_ALPHA16
:
177 return GL_LUMINANCE_ALPHA
;
205 case GL_COLOR_INDEX1_EXT
:
206 case GL_COLOR_INDEX2_EXT
:
207 case GL_COLOR_INDEX4_EXT
:
208 case GL_COLOR_INDEX8_EXT
:
209 case GL_COLOR_INDEX12_EXT
:
210 case GL_COLOR_INDEX16_EXT
:
211 return GL_COLOR_INDEX
;
213 return -1; /* error */
220 * Given an internal texture format enum or 1, 2, 3, 4 return the
221 * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE,
222 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA. Return the
223 * number of components for the format. Return -1 if invalid enum.
226 components_in_intformat( GLint format
)
243 case GL_LUMINANCE_ALPHA
:
244 case GL_LUMINANCE4_ALPHA4
:
245 case GL_LUMINANCE6_ALPHA2
:
246 case GL_LUMINANCE8_ALPHA8
:
247 case GL_LUMINANCE12_ALPHA4
:
248 case GL_LUMINANCE12_ALPHA12
:
249 case GL_LUMINANCE16_ALPHA16
:
278 case GL_COLOR_INDEX1_EXT
:
279 case GL_COLOR_INDEX2_EXT
:
280 case GL_COLOR_INDEX4_EXT
:
281 case GL_COLOR_INDEX8_EXT
:
282 case GL_COLOR_INDEX12_EXT
:
283 case GL_COLOR_INDEX16_EXT
:
286 return -1; /* error */
292 * Return GL_TRUE if internalFormat is a compressed format, return GL_FALSE
296 is_compressed_format(GLcontext
*ctx
, GLenum internalFormat
)
298 if (ctx
->Driver
.IsCompressedFormat
) {
299 return (*ctx
->Driver
.IsCompressedFormat
)(ctx
, internalFormat
);
307 * Examine the texImage->Format field and set the Red, Green, Blue, etc
308 * texel component sizes to default values.
309 * These fields are set only here by core Mesa but device drivers may
310 * overwritting these fields to indicate true texel resolution.
313 set_teximage_component_sizes( struct gl_texture_image
*texImage
)
315 switch (texImage
->Format
) {
317 texImage
->RedBits
= 0;
318 texImage
->GreenBits
= 0;
319 texImage
->BlueBits
= 0;
320 texImage
->AlphaBits
= 8;
321 texImage
->IntensityBits
= 0;
322 texImage
->LuminanceBits
= 0;
323 texImage
->IndexBits
= 0;
326 texImage
->RedBits
= 0;
327 texImage
->GreenBits
= 0;
328 texImage
->BlueBits
= 0;
329 texImage
->AlphaBits
= 0;
330 texImage
->IntensityBits
= 0;
331 texImage
->LuminanceBits
= 8;
332 texImage
->IndexBits
= 0;
334 case GL_LUMINANCE_ALPHA
:
335 texImage
->RedBits
= 0;
336 texImage
->GreenBits
= 0;
337 texImage
->BlueBits
= 0;
338 texImage
->AlphaBits
= 8;
339 texImage
->IntensityBits
= 0;
340 texImage
->LuminanceBits
= 8;
341 texImage
->IndexBits
= 0;
344 texImage
->RedBits
= 0;
345 texImage
->GreenBits
= 0;
346 texImage
->BlueBits
= 0;
347 texImage
->AlphaBits
= 0;
348 texImage
->IntensityBits
= 8;
349 texImage
->LuminanceBits
= 0;
350 texImage
->IndexBits
= 0;
353 texImage
->RedBits
= 8;
354 texImage
->GreenBits
= 0;
355 texImage
->BlueBits
= 0;
356 texImage
->AlphaBits
= 0;
357 texImage
->IntensityBits
= 0;
358 texImage
->LuminanceBits
= 0;
359 texImage
->IndexBits
= 0;
362 texImage
->RedBits
= 0;
363 texImage
->GreenBits
= 8;
364 texImage
->BlueBits
= 0;
365 texImage
->AlphaBits
= 0;
366 texImage
->IntensityBits
= 0;
367 texImage
->LuminanceBits
= 0;
368 texImage
->IndexBits
= 0;
371 texImage
->RedBits
= 0;
372 texImage
->GreenBits
= 0;
373 texImage
->BlueBits
= 8;
374 texImage
->AlphaBits
= 0;
375 texImage
->IntensityBits
= 0;
376 texImage
->LuminanceBits
= 0;
377 texImage
->IndexBits
= 0;
381 texImage
->RedBits
= 8;
382 texImage
->GreenBits
= 8;
383 texImage
->BlueBits
= 8;
384 texImage
->AlphaBits
= 0;
385 texImage
->IntensityBits
= 0;
386 texImage
->LuminanceBits
= 0;
387 texImage
->IndexBits
= 0;
392 texImage
->RedBits
= 8;
393 texImage
->GreenBits
= 8;
394 texImage
->BlueBits
= 8;
395 texImage
->AlphaBits
= 8;
396 texImage
->IntensityBits
= 0;
397 texImage
->LuminanceBits
= 0;
398 texImage
->IndexBits
= 0;
401 texImage
->RedBits
= 0;
402 texImage
->GreenBits
= 0;
403 texImage
->BlueBits
= 0;
404 texImage
->AlphaBits
= 0;
405 texImage
->IntensityBits
= 0;
406 texImage
->LuminanceBits
= 0;
407 texImage
->IndexBits
= 8;
410 gl_problem(NULL
, "unexpected format in set_teximage_component_sizes");
416 set_tex_image(struct gl_texture_object
*tObj
,
417 GLenum target
, GLint level
,
418 struct gl_texture_image
*texImage
)
424 tObj
->Image
[level
] = texImage
;
426 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
427 tObj
->Image
[level
] = texImage
;
429 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
430 tObj
->NegX
[level
] = texImage
;
432 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
433 tObj
->PosY
[level
] = texImage
;
435 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
436 tObj
->NegY
[level
] = texImage
;
438 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
439 tObj
->PosZ
[level
] = texImage
;
441 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
442 tObj
->NegZ
[level
] = texImage
;
445 gl_problem(NULL
, "bad target in set_tex_image()");
452 * Return new gl_texture_image struct with all fields initialized to zero.
454 struct gl_texture_image
*
455 _mesa_alloc_texture_image( void )
457 return CALLOC_STRUCT(gl_texture_image
);
463 * Initialize most fields of a gl_texture_image struct.
466 init_texture_image( GLcontext
*ctx
,
467 struct gl_texture_image
*img
,
468 GLsizei width
, GLsizei height
, GLsizei depth
,
469 GLint border
, GLenum internalFormat
)
473 img
->Format
= (GLenum
) _mesa_base_tex_format(ctx
, internalFormat
);
474 set_teximage_component_sizes( img
);
475 img
->IntFormat
= (GLenum
) internalFormat
;
476 img
->Border
= border
;
478 img
->Height
= height
;
480 img
->WidthLog2
= logbase2(width
- 2 * border
);
481 if (height
== 1) /* 1-D texture */
484 img
->HeightLog2
= logbase2(height
- 2 * border
);
485 if (depth
== 1) /* 2-D texture */
488 img
->DepthLog2
= logbase2(depth
- 2 * border
);
489 img
->Width2
= 1 << img
->WidthLog2
;
490 img
->Height2
= 1 << img
->HeightLog2
;
491 img
->Depth2
= 1 << img
->DepthLog2
;
492 img
->MaxLog2
= MAX2(img
->WidthLog2
, img
->HeightLog2
);
493 img
->IsCompressed
= is_compressed_format(ctx
, internalFormat
);
499 _mesa_free_texture_image( struct gl_texture_image
*teximage
)
501 if (teximage
->Data
) {
502 FREE( teximage
->Data
);
503 teximage
->Data
= NULL
;
511 * Return number of bytes of storage needed to store a compressed texture
512 * image. Only the driver knows for sure. If the driver can't help us,
516 _mesa_compressed_image_size(GLcontext
*ctx
,
517 GLenum internalFormat
,
523 if (ctx
->Driver
.CompressedImageSize
) {
524 return (*ctx
->Driver
.CompressedImageSize
)(ctx
, internalFormat
,
526 width
, height
, depth
);
529 /* Shouldn't this be an internal error of some sort? */
537 * Given a texture unit and a texture target, return the corresponding
540 struct gl_texture_object
*
541 _mesa_select_tex_object(GLcontext
*ctx
, struct gl_texture_unit
*texUnit
,
546 return texUnit
->CurrentD
[1];
547 case GL_PROXY_TEXTURE_1D
:
548 return ctx
->Texture
.Proxy1D
;
550 return texUnit
->CurrentD
[2];
551 case GL_PROXY_TEXTURE_2D
:
552 return ctx
->Texture
.Proxy2D
;
554 return texUnit
->CurrentD
[3];
555 case GL_PROXY_TEXTURE_3D
:
556 return ctx
->Texture
.Proxy3D
;
557 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
558 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
559 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
560 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
561 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
562 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
563 return ctx
->Extensions
.HaveTextureCubeMap
564 ? texUnit
->CurrentCubeMap
: NULL
;
565 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
566 return ctx
->Extensions
.HaveTextureCubeMap
567 ? ctx
->Texture
.ProxyCubeMap
: NULL
;
569 gl_problem(NULL
, "bad target in _mesa_select_tex_object()");
576 * Return the texture image struct which corresponds to target and level
577 * for the given texture unit.
579 struct gl_texture_image
*
580 _mesa_select_tex_image(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
581 GLenum target
, GLint level
)
586 return texUnit
->CurrentD
[1]->Image
[level
];
587 case GL_PROXY_TEXTURE_1D
:
588 return ctx
->Texture
.Proxy1D
->Image
[level
];
590 return texUnit
->CurrentD
[2]->Image
[level
];
591 case GL_PROXY_TEXTURE_2D
:
592 return ctx
->Texture
.Proxy2D
->Image
[level
];
594 return texUnit
->CurrentD
[3]->Image
[level
];
595 case GL_PROXY_TEXTURE_3D
:
596 return ctx
->Texture
.Proxy3D
->Image
[level
];
597 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
598 if (ctx
->Extensions
.HaveTextureCubeMap
)
599 return texUnit
->CurrentCubeMap
->Image
[level
];
602 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
603 if (ctx
->Extensions
.HaveTextureCubeMap
)
604 return texUnit
->CurrentCubeMap
->NegX
[level
];
607 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
608 if (ctx
->Extensions
.HaveTextureCubeMap
)
609 return texUnit
->CurrentCubeMap
->PosY
[level
];
612 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
613 if (ctx
->Extensions
.HaveTextureCubeMap
)
614 return texUnit
->CurrentCubeMap
->NegY
[level
];
617 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
618 if (ctx
->Extensions
.HaveTextureCubeMap
)
619 return texUnit
->CurrentCubeMap
->PosZ
[level
];
622 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
623 if (ctx
->Extensions
.HaveTextureCubeMap
)
624 return texUnit
->CurrentCubeMap
->NegZ
[level
];
627 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
628 if (ctx
->Extensions
.HaveTextureCubeMap
)
629 return ctx
->Texture
.ProxyCubeMap
->Image
[level
];
633 gl_problem(ctx
, "bad target in _mesa_select_tex_image()");
641 * Calling glTexImage and related functions when convolution is enabled
642 * with GL_REDUCE border mode causes some complications.
643 * The incoming image must be extra large so that the post-convolution
644 * image size is reduced to a power of two size (plus 2 * border).
645 * This function adjusts a texture width and height accordingly if
646 * convolution with GL_REDUCE is enabled.
649 adjust_texture_size_for_convolution(const GLcontext
*ctx
, GLuint dimensions
,
650 GLsizei
*width
, GLsizei
*height
)
652 if (ctx
->Pixel
.Convolution1DEnabled
654 && ctx
->Pixel
.ConvolutionBorderMode
[0] == GL_REDUCE
) {
655 *width
= *width
- (MAX2(ctx
->Convolution1D
.Width
, 1) - 1);
657 else if (ctx
->Pixel
.Convolution2DEnabled
659 && ctx
->Pixel
.ConvolutionBorderMode
[1] == GL_REDUCE
) {
660 *width
= *width
- (MAX2(ctx
->Convolution2D
.Width
, 1) - 1);
661 *height
= *height
- (MAX2(ctx
->Convolution2D
.Height
, 1) - 1);
663 else if (ctx
->Pixel
.Separable2DEnabled
665 && ctx
->Pixel
.ConvolutionBorderMode
[2] == GL_REDUCE
) {
666 *width
= *width
- (MAX2(ctx
->Separable2D
.Width
, 1) - 1);
667 *height
= *height
- (MAX2(ctx
->Separable2D
.Height
, 1) - 1);
673 /* Need this to prevent an out-of-bounds memory access when using
674 * X86 optimized code.
677 # define EXTRA_BYTE 1
679 # define EXTRA_BYTE 0
685 * Called by glTexImage[123]D. Fill in a texture image with data given
686 * by the client. All pixel transfer and unpack modes are handled here.
687 * Input: dimensions (1, 2, or 3)
688 * texImage - destination texture image (we'll malloc the memory)
689 * width, height, depth - size of source image
690 * srcFormat, srcType - source image format and type
691 * pixels - source image data
692 * srcPacking - source image packing parameters
694 * NOTE: All texture image parameters should have already been error checked.
696 * NOTE: the texImage dimensions and source image dimensions must be correct
697 * with respect to convolution with border mode = reduce.
700 make_texture_image( GLcontext
*ctx
, GLuint dimensions
,
701 struct gl_texture_image
*texImage
,
702 GLint width
, GLint height
, GLint depth
,
703 GLenum srcFormat
, GLenum srcType
, const GLvoid
*pixels
,
704 const struct gl_pixelstore_attrib
*srcPacking
)
706 GLint components
, numPixels
;
707 GLint internalFormat
, border
;
711 ASSERT(!texImage
->Data
);
715 internalFormat
= texImage
->IntFormat
;
716 border
= texImage
->Border
;
717 components
= components_in_intformat(internalFormat
);
722 ASSERT(border
== 0 || border
== 1);
725 numPixels
= width
* height
* depth
;
727 texImage
->Data
= (GLubyte
*) MALLOC(numPixels
* components
+ EXTRA_BYTE
);
729 return; /* out of memory */
732 * OK, the texture image struct has been initialized and the texture
733 * image memory has been allocated.
734 * Now fill in the texture image from the source data.
735 * This includes applying the pixel transfer operations.
738 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
739 _mesa_update_image_transfer_state(ctx
);
741 /* try common 2D texture cases first */
742 if (!ctx
->ImageTransferState
&& srcType
== GL_UNSIGNED_BYTE
&& depth
== 1) {
744 if (srcFormat
== internalFormat
||
745 (srcFormat
== GL_LUMINANCE
&& internalFormat
== 1) ||
746 (srcFormat
== GL_LUMINANCE_ALPHA
&& internalFormat
== 2) ||
747 (srcFormat
== GL_RGB
&& internalFormat
== 3) ||
748 (srcFormat
== GL_RGBA
&& internalFormat
== 4)) {
749 /* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA,
750 * GL_LUMINANCE_ALPHA, etc. texture formats.
752 const GLubyte
*src
= (const GLubyte
*) _mesa_image_address(
753 srcPacking
, pixels
, width
, height
, srcFormat
, srcType
, 0, 0, 0);
754 const GLint srcStride
= _mesa_image_row_stride(srcPacking
, width
,
756 GLubyte
*dst
= texImage
->Data
;
757 GLint dstBytesPerRow
= width
* components
* sizeof(GLubyte
);
758 if (srcStride
== dstBytesPerRow
) {
759 MEMCPY(dst
, src
, height
* dstBytesPerRow
);
763 for (i
= 0; i
< height
; i
++) {
764 MEMCPY(dst
, src
, dstBytesPerRow
);
766 dst
+= dstBytesPerRow
;
769 return; /* all done */
771 else if (srcFormat
== GL_RGBA
&& internalFormat
== GL_RGB
) {
772 /* commonly used by Quake */
773 const GLubyte
*src
= (const GLubyte
*) _mesa_image_address(
774 srcPacking
, pixels
, width
, height
, srcFormat
, srcType
, 0, 0, 0);
775 const GLint srcStride
= _mesa_image_row_stride(srcPacking
, width
,
777 GLubyte
*dst
= texImage
->Data
;
779 for (i
= 0; i
< height
; i
++) {
780 const GLubyte
*s
= src
;
781 for (j
= 0; j
< width
; j
++) {
782 *dst
++ = *s
++; /*red*/
783 *dst
++ = *s
++; /*green*/
784 *dst
++ = *s
++; /*blue*/
789 return; /* all done */
795 * General case solutions
797 if (texImage
->Format
== GL_COLOR_INDEX
) {
798 /* color index texture */
799 const GLint destBytesPerRow
= width
* components
* sizeof(GLubyte
);
800 const GLenum dstType
= GL_UNSIGNED_BYTE
;
801 GLubyte
*destTex
= texImage
->Data
;
803 for (img
= 0; img
< depth
; img
++) {
804 for (row
= 0; row
< height
; row
++) {
805 const GLvoid
*srcAddr
= _mesa_image_address(srcPacking
,
806 pixels
, width
, height
, srcFormat
, srcType
, img
, row
, 0);
807 _mesa_unpack_index_span(ctx
, width
, dstType
, destTex
,
808 srcType
, srcAddr
, srcPacking
,
809 ctx
->ImageTransferState
);
810 destTex
+= destBytesPerRow
;
815 /* regular, color texture */
816 GLint destBytesPerRow
;
817 const GLenum dstFormat
= texImage
->Format
;
818 GLubyte
*destTex
= texImage
->Data
;
820 GLint convWidth
= width
, convHeight
= height
;
822 if ((dimensions
== 1 && ctx
->Pixel
.Convolution1DEnabled
) ||
824 (ctx
->Pixel
.Convolution2DEnabled
|| ctx
->Pixel
.Separable2DEnabled
)
826 GLfloat
*tmpImage
, *convImage
;
827 tmpImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
829 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage");
832 convImage
= (GLfloat
*) MALLOC(width
* height
* 4 * sizeof(GLfloat
));
834 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage");
839 for (img
= 0; img
< depth
; img
++) {
841 GLfloat
*dstf
= tmpImage
;
842 /* unpack and do transfer ops up to convolution */
843 for (row
= 0; row
< height
; row
++) {
844 const GLvoid
*srcAddr
= _mesa_image_address(srcPacking
,
845 pixels
, width
, height
, srcFormat
, srcType
, img
, row
, 0);
846 _mesa_unpack_float_color_span(ctx
, width
, GL_RGBA
, dstf
,
847 srcFormat
, srcType
, srcAddr
, srcPacking
,
848 ctx
->ImageTransferState
& IMAGE_PRE_CONVOLUTION_BITS
,
854 if (dimensions
== 1) {
855 ASSERT(ctx
->Pixel
.Convolution1DEnabled
);
856 _mesa_convolve_1d_image(ctx
, &convWidth
, tmpImage
, convImage
);
859 if (ctx
->Pixel
.Convolution2DEnabled
) {
860 _mesa_convolve_2d_image(ctx
, &convWidth
, &convHeight
,
861 tmpImage
, convImage
);
864 ASSERT(ctx
->Pixel
.Separable2DEnabled
);
865 _mesa_convolve_sep_image(ctx
, &convWidth
, &convHeight
,
866 tmpImage
, convImage
);
870 /* packing and transfer ops after convolution */
872 destBytesPerRow
= convWidth
* components
* sizeof(GLubyte
);
873 for (row
= 0; row
< convHeight
; row
++) {
874 _mesa_pack_float_rgba_span(ctx
, convWidth
,
875 (const GLfloat (*)[4]) srcf
,
876 dstFormat
, GL_UNSIGNED_BYTE
,
877 destTex
, &_mesa_native_packing
,
878 ctx
->ImageTransferState
879 & IMAGE_POST_CONVOLUTION_BITS
);
880 srcf
+= convWidth
* 4;
881 destTex
+= destBytesPerRow
;
890 for (img
= 0; img
< depth
; img
++) {
891 for (row
= 0; row
< height
; row
++) {
892 const GLvoid
*srcAddr
= _mesa_image_address(srcPacking
,
893 pixels
, width
, height
, srcFormat
, srcType
, img
, row
, 0);
894 _mesa_unpack_ubyte_color_span(ctx
, width
, dstFormat
, destTex
,
895 srcFormat
, srcType
, srcAddr
, srcPacking
,
896 ctx
->ImageTransferState
);
897 destTex
+= destBytesPerRow
;
907 * glTexImage[123]D can accept a NULL image pointer. In this case we
908 * create a texture image with unspecified image contents per the OpenGL
909 * spec. This function creates an empty image for the given texture image.
912 make_null_texture( struct gl_texture_image
*texImage
)
918 ASSERT(!texImage
->Data
);
920 components
= components_in_intformat(texImage
->IntFormat
);
921 numPixels
= texImage
->Width
* texImage
->Height
* texImage
->Depth
;
923 texImage
->Data
= (GLubyte
*) MALLOC( numPixels
* components
+ EXTRA_BYTE
);
926 * Let's see if anyone finds this. If glTexImage2D() is called with
927 * a NULL image pointer then load the texture image with something
928 * interesting instead of leaving it indeterminate.
930 if (texImage
->Data
) {
931 static const char message
[8][32] = {
935 " X X XXXX XXX XXXXX ",
938 " X X XXXXX XXX X X ",
942 GLubyte
*imgPtr
= texImage
->Data
;
944 for (i
= 0; i
< texImage
->Height
; i
++) {
945 GLint srcRow
= 7 - i
% 8;
946 for (j
= 0; j
< texImage
->Width
; j
++) {
947 GLint srcCol
= j
% 32;
948 GLint texel
= (message
[srcRow
][srcCol
]=='X') ? 255 : 70;
949 for (k
=0;k
<components
;k
++) {
950 *imgPtr
++ = (GLubyte
) texel
;
960 * Test glTexImage[123]D() parameters for errors.
962 * dimensions - must be 1 or 2 or 3
963 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
966 texture_error_check( GLcontext
*ctx
, GLenum target
,
967 GLint level
, GLint internalFormat
,
968 GLenum format
, GLenum type
,
970 GLint width
, GLint height
,
971 GLint depth
, GLint border
)
976 if (dimensions
== 1) {
977 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_1D
);
978 if (target
!= GL_TEXTURE_1D
&& !isProxy
) {
979 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
983 else if (dimensions
== 2) {
984 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_2D
);
985 if (target
!= GL_TEXTURE_2D
&& !isProxy
&&
986 !(ctx
->Extensions
.HaveTextureCubeMap
&&
987 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
988 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
989 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
993 else if (dimensions
== 3) {
994 isProxy
= (GLboolean
) (target
== GL_PROXY_TEXTURE_3D
);
995 if (target
!= GL_TEXTURE_3D
&& !isProxy
) {
996 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1001 gl_problem( ctx
, "bad dims in texture_error_check" );
1006 if (border
!= 0 && border
!= 1) {
1009 sprintf(message
, "glTexImage%dD(border)", dimensions
);
1010 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1016 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
1017 || logbase2( width
- 2 * border
) < 0) {
1020 sprintf(message
, "glTexImage%dD(width)", dimensions
);
1021 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1027 if (dimensions
>= 2) {
1028 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
1029 || logbase2( height
- 2 * border
) < 0) {
1032 sprintf(message
, "glTexImage%dD(height)", dimensions
);
1033 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1039 /* For cube map, width must equal height */
1040 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1041 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
1042 if (width
!= height
) {
1044 gl_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
1051 if (dimensions
>= 3) {
1052 if (depth
< 2 * border
|| depth
> 2 + ctx
->Const
.MaxTextureSize
1053 || logbase2( depth
- 2 * border
) < 0) {
1055 gl_error( ctx
, GL_INVALID_VALUE
, "glTexImage3D(depth)" );
1062 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1065 sprintf(message
, "glTexImage%dD(level)", dimensions
);
1066 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1071 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
1075 sprintf(message
, "glTexImage%dD(internalFormat)", dimensions
);
1076 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1081 if (!is_compressed_format(ctx
, internalFormat
)) {
1082 if (!_mesa_is_legal_format_and_type( format
, type
)) {
1083 /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
1084 * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
1088 sprintf(message
, "glTexImage%dD(format or type)", dimensions
);
1089 gl_error(ctx
, GL_INVALID_OPERATION
, message
);
1095 /* if we get here, the parameters are OK */
1102 * Test glTexSubImage[123]D() parameters for errors.
1104 * dimensions - must be 1 or 2 or 3
1105 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
1108 subtexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
1109 GLenum target
, GLint level
,
1110 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1111 GLint width
, GLint height
, GLint depth
,
1112 GLenum format
, GLenum type
)
1114 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1115 struct gl_texture_image
*destTex
;
1117 if (dimensions
== 1) {
1118 if (target
!= GL_TEXTURE_1D
) {
1119 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(target)" );
1123 else if (dimensions
== 2) {
1124 if (ctx
->Extensions
.HaveTextureCubeMap
) {
1125 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1126 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1127 target
!= GL_TEXTURE_2D
) {
1128 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
1132 else if (target
!= GL_TEXTURE_2D
) {
1133 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
1137 else if (dimensions
== 3) {
1138 if (target
!= GL_TEXTURE_3D
) {
1139 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3D(target)" );
1144 gl_problem( ctx
, "bad dims in texture_error_check" );
1148 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1149 gl_error(ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(level)");
1155 sprintf(message
, "glTexSubImage%dD(width)", dimensions
);
1156 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1159 if (height
< 0 && dimensions
> 1) {
1161 sprintf(message
, "glTexSubImage%dD(height)", dimensions
);
1162 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1165 if (depth
< 0 && dimensions
> 2) {
1167 sprintf(message
, "glTexSubImage%dD(depth)", dimensions
);
1168 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1172 destTex
= texUnit
->CurrentD
[2]->Image
[level
];
1174 gl_error(ctx
, GL_INVALID_OPERATION
, "glTexSubImage2D");
1178 if (xoffset
< -((GLint
)destTex
->Border
)) {
1179 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset)");
1182 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
1183 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset+width)");
1186 if (dimensions
> 1) {
1187 if (yoffset
< -((GLint
)destTex
->Border
)) {
1188 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset)");
1191 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
1192 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset+height)");
1196 if (dimensions
> 2) {
1197 if (zoffset
< -((GLint
)destTex
->Border
)) {
1198 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset)");
1201 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+destTex
->Border
)) {
1202 gl_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset+depth)");
1207 if (!is_compressed_format(ctx
, destTex
->IntFormat
)) {
1208 if (!_mesa_is_legal_format_and_type(format
, type
)) {
1210 sprintf(message
, "glTexSubImage%dD(format or type)", dimensions
);
1211 gl_error(ctx
, GL_INVALID_ENUM
, message
);
1221 * Test glCopyTexImage[12]D() parameters for errors.
1222 * Input: dimensions - must be 1 or 2 or 3
1223 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
1226 copytexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
1227 GLenum target
, GLint level
, GLint internalFormat
,
1228 GLint width
, GLint height
, GLint border
)
1232 if (dimensions
== 1) {
1233 if (target
!= GL_TEXTURE_1D
) {
1234 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
1238 else if (dimensions
== 2) {
1239 if (ctx
->Extensions
.HaveTextureCubeMap
) {
1240 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1241 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1242 target
!= GL_TEXTURE_2D
) {
1243 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1247 else if (target
!= GL_TEXTURE_2D
) {
1248 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1254 if (border
!=0 && border
!=1) {
1256 sprintf(message
, "glCopyTexImage%dD(border)", dimensions
);
1257 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1262 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
1263 || logbase2( width
- 2 * border
) < 0) {
1265 sprintf(message
, "glCopyTexImage%dD(width)", dimensions
);
1266 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1271 if (dimensions
>= 2) {
1272 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
1273 || logbase2( height
- 2 * border
) < 0) {
1275 sprintf(message
, "glCopyTexImage%dD(height)", dimensions
);
1276 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1281 /* For cube map, width must equal height */
1282 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1283 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
1284 if (width
!= height
) {
1285 gl_error(ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(width != height)");
1291 if (level
<0 || level
>=ctx
->Const
.MaxTextureLevels
) {
1293 sprintf(message
, "glCopyTexImage%dD(level)", dimensions
);
1294 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1298 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
1301 sprintf(message
, "glCopyTexImage%dD(internalFormat)", dimensions
);
1302 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1306 /* if we get here, the parameters are OK */
1312 copytexsubimage_error_check( GLcontext
*ctx
, GLuint dimensions
,
1313 GLenum target
, GLint level
,
1314 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1315 GLsizei width
, GLsizei height
)
1317 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1318 struct gl_texture_image
*teximage
;
1320 if (dimensions
== 1) {
1321 if (target
!= GL_TEXTURE_1D
) {
1322 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
1326 else if (dimensions
== 2) {
1327 if (ctx
->Extensions
.HaveTextureCubeMap
) {
1328 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1329 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1330 target
!= GL_TEXTURE_2D
) {
1331 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1335 else if (target
!= GL_TEXTURE_2D
) {
1336 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1340 else if (dimensions
== 3) {
1341 if (target
!= GL_TEXTURE_3D
) {
1342 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3D(target)" );
1347 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1349 sprintf(message
, "glCopyTexSubImage%dD(level)", dimensions
);
1350 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1356 sprintf(message
, "glCopyTexSubImage%dD(width)", dimensions
);
1357 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1360 if (dimensions
> 1 && height
< 0) {
1362 sprintf(message
, "glCopyTexSubImage%dD(height)", dimensions
);
1363 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1367 teximage
= texUnit
->CurrentD
[dimensions
]->Image
[level
];
1370 sprintf(message
, "glCopyTexSubImage%dD(undefined texture)", dimensions
);
1371 gl_error(ctx
, GL_INVALID_OPERATION
, message
);
1375 if (xoffset
< -((GLint
)teximage
->Border
)) {
1377 sprintf(message
, "glCopyTexSubImage%dD(xoffset)", dimensions
);
1378 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1381 if (xoffset
+width
> (GLint
) (teximage
->Width
+teximage
->Border
)) {
1383 sprintf(message
, "glCopyTexSubImage%dD(xoffset+width)", dimensions
);
1384 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1387 if (dimensions
> 1) {
1388 if (yoffset
< -((GLint
)teximage
->Border
)) {
1390 sprintf(message
, "glCopyTexSubImage%dD(yoffset)", dimensions
);
1391 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1394 /* NOTE: we're adding the border here, not subtracting! */
1395 if (yoffset
+height
> (GLint
) (teximage
->Height
+teximage
->Border
)) {
1397 sprintf(message
, "glCopyTexSubImage%dD(yoffset+height)", dimensions
);
1398 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1403 if (dimensions
> 2) {
1404 if (zoffset
< -((GLint
)teximage
->Border
)) {
1406 sprintf(message
, "glCopyTexSubImage%dD(zoffset)", dimensions
);
1407 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1410 if (zoffset
> (GLint
) (teximage
->Depth
+teximage
->Border
)) {
1412 sprintf(message
, "glCopyTexSubImage%dD(zoffset+depth)", dimensions
);
1413 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1418 /* if we get here, the parameters are OK */
1426 * Turn generic compressed formats into specific compressed format.
1427 * Some of the compressed formats we don't support, so we
1428 * fall back to the uncompressed format. (See issue 15 of
1429 * the GL_ARB_texture_compression specification.)
1432 get_specific_compressed_tex_format(GLcontext
*ctx
,
1433 GLint ifmt
, GLint numDimensions
)
1436 GLint internalFormat
= ifmt
;
1438 if (ctx
->Extensions
.HaveTextureCompression
1439 && ctx
->Driver
.SpecificCompressedTexFormat
) {
1441 * First, ask the driver for the specific format.
1443 switch (internalFormat
) {
1444 case GL_COMPRESSED_ALPHA_ARB
:
1445 case GL_COMPRESSED_LUMINANCE_ARB
:
1446 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
1447 case GL_COMPRESSED_INTENSITY_ARB
:
1448 case GL_COMPRESSED_RGB_ARB
:
1449 case GL_COMPRESSED_RGBA_ARB
:
1450 internalFormat
= (*ctx
->Driver
.SpecificCompressedTexFormat
)
1451 (ctx
, internalFormat
, numDimensions
);
1452 /* XXX shouldn't we return now? */
1455 /* silence compiler warnings */
1461 * Now, convert any generic format left to an uncompressed
1462 * specific format. If the driver does not support compression
1463 * of the format, we must drop back to the uncompressed format.
1464 * See issue 15 of the GL_ARB_texture_compression specification.
1466 switch (internalFormat
) {
1467 case GL_COMPRESSED_ALPHA_ARB
:
1468 if (ctx
&& !ctx
->Extensions
.HaveTextureCompression
) {
1469 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1470 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1473 internalFormat
= GL_ALPHA
;
1475 case GL_COMPRESSED_LUMINANCE_ARB
:
1476 if (ctx
&& !ctx
->Extensions
.HaveTextureCompression
) {
1477 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1478 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1481 internalFormat
= GL_LUMINANCE
;
1483 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
1484 if (ctx
&& !ctx
->Extensions
.HaveTextureCompression
) {
1485 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1486 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1489 internalFormat
= GL_LUMINANCE_ALPHA
;
1491 case GL_COMPRESSED_INTENSITY_ARB
:
1492 if (ctx
&& !ctx
->Extensions
.HaveTextureCompression
) {
1493 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1494 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1497 internalFormat
= GL_INTENSITY
;
1499 case GL_COMPRESSED_RGB_ARB
:
1500 if (ctx
&& !ctx
->Extensions
.HaveTextureCompression
) {
1501 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1502 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1505 internalFormat
= GL_RGB
;
1507 case GL_COMPRESSED_RGBA_ARB
:
1508 if (ctx
&& !ctx
->Extensions
.HaveTextureCompression
) {
1509 sprintf(message
, "glTexImage%dD(internalFormat)", numDimensions
);
1510 gl_error(ctx
, GL_INVALID_VALUE
, message
);
1513 internalFormat
= GL_RGBA
;
1516 /* silence compiler warning */
1519 return internalFormat
;
1525 * Called from the API. Note that width includes the border.
1528 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
1529 GLsizei width
, GLint border
, GLenum format
,
1530 GLenum type
, const GLvoid
*pixels
)
1532 GLsizei postConvWidth
;
1533 GET_CURRENT_CONTEXT(ctx
);
1534 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glTexImage1D");
1536 postConvWidth
= width
;
1537 adjust_texture_size_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1539 if (target
==GL_TEXTURE_1D
) {
1540 struct gl_texture_unit
*texUnit
;
1541 struct gl_texture_object
*texObj
;
1542 struct gl_texture_image
*texImage
;
1545 ifmt
= get_specific_compressed_tex_format(ctx
, internalFormat
, 1);
1548 * The error here is that we were sent a generic compressed
1549 * format, but the extension is not supported.
1554 internalFormat
= ifmt
;
1557 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1558 format
, type
, 1, postConvWidth
, 1, 1, border
)) {
1559 return; /* error in texture image was detected */
1562 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1563 texObj
= texUnit
->CurrentD
[1];
1564 texImage
= texObj
->Image
[level
];
1567 texImage
= _mesa_alloc_texture_image();
1568 texObj
->Image
[level
] = texImage
;
1570 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
1574 else if (texImage
->Data
) {
1575 FREE(texImage
->Data
);
1576 texImage
->Data
= NULL
;
1579 /* setup the teximage struct's fields */
1580 init_texture_image(ctx
, texImage
, postConvWidth
, 1, 1, border
, internalFormat
);
1582 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
1583 _mesa_update_image_transfer_state(ctx
);
1585 /* process the texture image */
1587 GLboolean retain
= GL_TRUE
;
1588 GLboolean success
= GL_FALSE
;
1589 if (!ctx
->ImageTransferState
&& ctx
->Driver
.TexImage1D
) {
1590 /* let device driver try to use raw image */
1591 success
= (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, format
,
1592 type
, pixels
, &ctx
->Unpack
,
1593 texObj
, texImage
, &retain
);
1595 if (retain
|| !success
) {
1596 /* make internal copy of the texture image */
1597 make_texture_image(ctx
, 1, texImage
, width
, 1, 1,
1598 format
, type
, pixels
, &ctx
->Unpack
);
1599 if (!success
&& ctx
->Driver
.TexImage1D
) {
1600 /* let device driver try to use unpacked image */
1601 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
1602 GL_UNSIGNED_BYTE
, texImage
->Data
,
1603 &_mesa_native_packing
,
1604 texObj
, texImage
, &retain
);
1607 if (!retain
&& texImage
->Data
) {
1608 FREE(texImage
->Data
);
1609 texImage
->Data
= NULL
;
1613 make_null_texture(texImage
);
1614 if (ctx
->Driver
.TexImage1D
) {
1616 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
1617 GL_UNSIGNED_BYTE
, texImage
->Data
,
1618 &_mesa_native_packing
,
1619 texObj
, texImage
, &retain
);
1624 gl_put_texobj_on_dirty_list( ctx
, texObj
);
1625 ctx
->NewState
|= NEW_TEXTURING
;
1627 else if (target
==GL_PROXY_TEXTURE_1D
) {
1628 /* Proxy texture: check for errors and update proxy state */
1629 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1630 format
, type
, 1, postConvWidth
, 1, 1, border
)) {
1631 /* if error, clear all proxy texture image parameters */
1632 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1633 MEMSET( ctx
->Texture
.Proxy1D
->Image
[level
], 0,
1634 sizeof(struct gl_texture_image
) );
1638 /* if no error, update proxy texture image parameters */
1639 init_texture_image(ctx
, ctx
->Texture
.Proxy1D
->Image
[level
],
1640 width
, 1, 1, border
, internalFormat
);
1644 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1651 _mesa_TexImage2D( GLenum target
, GLint level
, GLint internalFormat
,
1652 GLsizei width
, GLsizei height
, GLint border
,
1653 GLenum format
, GLenum type
,
1654 const GLvoid
*pixels
)
1656 GLsizei postConvWidth
, postConvHeight
;
1657 GET_CURRENT_CONTEXT(ctx
);
1658 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glTexImage2D");
1660 postConvWidth
= width
;
1661 postConvHeight
= height
;
1662 adjust_texture_size_for_convolution(ctx
, 2, &postConvWidth
,&postConvHeight
);
1664 if (target
==GL_TEXTURE_2D
||
1665 (ctx
->Extensions
.HaveTextureCubeMap
&&
1666 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1667 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
1668 struct gl_texture_unit
*texUnit
;
1669 struct gl_texture_object
*texObj
;
1670 struct gl_texture_image
*texImage
;
1673 ifmt
= get_specific_compressed_tex_format(ctx
, internalFormat
, 2);
1676 * The error here is that we were sent a generic compressed
1677 * format, but the extension is not supported.
1682 internalFormat
= ifmt
;
1685 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1686 format
, type
, 2, postConvWidth
, postConvHeight
,
1688 return; /* error in texture image was detected */
1691 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1692 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1693 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1696 texImage
= _mesa_alloc_texture_image();
1697 set_tex_image(texObj
, target
, level
, texImage
);
1698 /*texObj->Image[level] = texImage;*/
1700 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1704 else if (texImage
->Data
) {
1705 FREE(texImage
->Data
);
1706 texImage
->Data
= NULL
;
1709 /* setup the teximage struct's fields */
1710 init_texture_image(ctx
, texImage
, postConvWidth
, postConvHeight
,
1711 1, border
, internalFormat
);
1713 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
1714 _mesa_update_image_transfer_state(ctx
);
1716 /* process the texture image */
1718 GLboolean retain
= GL_TRUE
;
1719 GLboolean success
= GL_FALSE
;
1720 if (!ctx
->ImageTransferState
&& ctx
->Driver
.TexImage2D
) {
1721 /* let device driver try to use raw image */
1722 success
= (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, format
,
1723 type
, pixels
, &ctx
->Unpack
,
1724 texObj
, texImage
, &retain
);
1726 if (retain
|| !success
) {
1727 /* make internal copy of the texture image */
1728 make_texture_image(ctx
, 2, texImage
, width
, height
, 1,
1729 format
, type
, pixels
, &ctx
->Unpack
);
1730 if (!success
&& ctx
->Driver
.TexImage2D
) {
1731 /* let device driver try to use unpacked image */
1732 (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, texImage
->Format
,
1733 GL_UNSIGNED_BYTE
, texImage
->Data
,
1734 &_mesa_native_packing
,
1735 texObj
, texImage
, &retain
);
1738 if (!retain
&& texImage
->Data
) {
1739 FREE(texImage
->Data
);
1740 texImage
->Data
= NULL
;
1744 make_null_texture(texImage
);
1745 if (ctx
->Driver
.TexImage2D
) {
1747 (*ctx
->Driver
.TexImage2D
)( ctx
, target
, level
, texImage
->Format
,
1748 GL_UNSIGNED_BYTE
, texImage
->Data
,
1749 &_mesa_native_packing
,
1750 texObj
, texImage
, &retain
);
1754 #define OLD_DD_TEXTURE
1755 #ifdef OLD_DD_TEXTURE
1756 /* XXX this will be removed in the future */
1757 if (ctx
->Driver
.TexImage
) {
1758 (*ctx
->Driver
.TexImage
)( ctx
, target
, texObj
, level
, internalFormat
,
1764 gl_put_texobj_on_dirty_list( ctx
, texObj
);
1765 ctx
->NewState
|= NEW_TEXTURING
;
1767 else if (target
==GL_PROXY_TEXTURE_2D
) {
1768 /* Proxy texture: check for errors and update proxy state */
1769 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1770 format
, type
, 2, postConvWidth
, height
, 1, border
)) {
1771 /* if error, clear all proxy texture image parameters */
1772 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1773 MEMSET( ctx
->Texture
.Proxy2D
->Image
[level
], 0,
1774 sizeof(struct gl_texture_image
) );
1778 /* if no error, update proxy texture image parameters */
1779 init_texture_image(ctx
,
1780 ctx
->Texture
.Proxy2D
->Image
[level
],
1781 width
, height
, 1, border
, internalFormat
);
1785 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1793 * Called by the API or display list executor.
1794 * Note that width and height include the border.
1797 _mesa_TexImage3D( GLenum target
, GLint level
, GLint internalFormat
,
1798 GLsizei width
, GLsizei height
, GLsizei depth
,
1799 GLint border
, GLenum format
, GLenum type
,
1800 const GLvoid
*pixels
)
1802 GET_CURRENT_CONTEXT(ctx
);
1803 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glTexImage3D");
1805 if (target
==GL_TEXTURE_3D_EXT
) {
1806 struct gl_texture_unit
*texUnit
;
1807 struct gl_texture_object
*texObj
;
1808 struct gl_texture_image
*texImage
;
1811 ifmt
= get_specific_compressed_tex_format(ctx
, internalFormat
, 3);
1814 * The error here is that we were sent a generic compressed
1815 * format, but the extension is not supported.
1820 internalFormat
= ifmt
;
1823 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1824 format
, type
, 3, width
, height
, depth
, border
)) {
1825 return; /* error in texture image was detected */
1828 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1829 texObj
= texUnit
->CurrentD
[3];
1830 texImage
= texObj
->Image
[level
];
1833 texImage
= _mesa_alloc_texture_image();
1834 texObj
->Image
[level
] = texImage
;
1836 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
1840 else if (texImage
->Data
) {
1841 FREE(texImage
->Data
);
1842 texImage
->Data
= NULL
;
1845 /* setup the teximage struct's fields */
1846 init_texture_image(ctx
, texImage
, width
, height
, depth
,
1847 border
, internalFormat
);
1849 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
1850 _mesa_update_image_transfer_state(ctx
);
1852 /* process the texture image */
1854 GLboolean retain
= GL_TRUE
;
1855 GLboolean success
= GL_FALSE
;
1856 if (!ctx
->ImageTransferState
&& ctx
->Driver
.TexImage3D
) {
1857 /* let device driver try to use raw image */
1858 success
= (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, format
,
1859 type
, pixels
, &ctx
->Unpack
,
1860 texObj
, texImage
, &retain
);
1862 if (retain
|| !success
) {
1863 /* make internal copy of the texture image */
1864 make_texture_image(ctx
, 3, texImage
, width
, height
, depth
,
1865 format
, type
, pixels
, &ctx
->Unpack
);
1866 if (!success
&& ctx
->Driver
.TexImage3D
) {
1867 /* let device driver try to use unpacked image */
1868 (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, texImage
->Format
,
1869 GL_UNSIGNED_BYTE
, texImage
->Data
,
1870 &_mesa_native_packing
,
1871 texObj
, texImage
, &retain
);
1874 if (!retain
&& texImage
->Data
) {
1875 FREE(texImage
->Data
);
1876 texImage
->Data
= NULL
;
1880 make_null_texture(texImage
);
1881 if (ctx
->Driver
.TexImage3D
) {
1883 (*ctx
->Driver
.TexImage3D
)( ctx
, target
, level
, texImage
->Format
,
1884 GL_UNSIGNED_BYTE
, texImage
->Data
,
1885 &_mesa_native_packing
,
1886 texObj
, texImage
, &retain
);
1891 gl_put_texobj_on_dirty_list( ctx
, texObj
);
1892 ctx
->NewState
|= NEW_TEXTURING
;
1894 else if (target
==GL_PROXY_TEXTURE_3D
) {
1895 /* Proxy texture: check for errors and update proxy state */
1896 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1897 format
, type
, 3, width
, height
, depth
, border
)) {
1898 /* if error, clear all proxy texture image parameters */
1899 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1900 MEMSET( ctx
->Texture
.Proxy3D
->Image
[level
], 0,
1901 sizeof(struct gl_texture_image
) );
1905 /* if no error, update proxy texture image parameters */
1906 init_texture_image(ctx
, ctx
->Texture
.Proxy3D
->Image
[level
],
1907 width
, height
, depth
, border
, internalFormat
);
1911 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1918 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
1919 GLsizei width
, GLsizei height
, GLsizei depth
,
1920 GLint border
, GLenum format
, GLenum type
,
1921 const GLvoid
*pixels
)
1923 _mesa_TexImage3D(target
, level
, (GLint
) internalFormat
, width
, height
,
1924 depth
, border
, format
, type
, pixels
);
1929 * Fetch a texture image from the device driver.
1930 * Store the results in the given texture object at the given mipmap level.
1933 _mesa_get_teximage_from_driver( GLcontext
*ctx
, GLenum target
, GLint level
,
1934 const struct gl_texture_object
*texObj
)
1937 GLenum imgFormat
, imgType
;
1938 GLboolean freeImage
;
1939 struct gl_texture_image
*texImage
;
1940 GLint destComponents
, numPixels
, srcBytesPerTexel
;
1942 if (!ctx
->Driver
.GetTexImage
)
1945 image
= (*ctx
->Driver
.GetTexImage
)( ctx
, target
, level
, texObj
,
1946 &imgFormat
, &imgType
, &freeImage
);
1950 texImage
= texObj
->Image
[level
];
1955 destComponents
= components_in_intformat(texImage
->Format
);
1956 assert(destComponents
> 0);
1957 numPixels
= texImage
->Width
* texImage
->Height
* texImage
->Depth
;
1958 assert(numPixels
> 0);
1959 srcBytesPerTexel
= _mesa_bytes_per_pixel(imgFormat
, imgType
);
1960 assert(srcBytesPerTexel
> 0);
1962 if (!texImage
->Data
) {
1963 /* Allocate memory for the texture image data */
1964 texImage
->Data
= (GLubyte
*) MALLOC(numPixels
* destComponents
+ EXTRA_BYTE
);
1967 if (imgFormat
== texImage
->Format
&& imgType
== GL_UNSIGNED_BYTE
) {
1968 /* We got lucky! The driver's format and type match Mesa's format. */
1969 if (texImage
->Data
) {
1970 MEMCPY(texImage
->Data
, image
, numPixels
* destComponents
);
1974 /* Convert the texture image from the driver's format to Mesa's
1977 const GLint width
= texImage
->Width
;
1978 const GLint height
= texImage
->Height
;
1979 const GLint depth
= texImage
->Depth
;
1980 const GLint destBytesPerRow
= width
* destComponents
* sizeof(GLchan
);
1981 const GLint srcBytesPerRow
= width
* srcBytesPerTexel
;
1982 const GLenum dstType
= GL_UNSIGNED_BYTE
;
1983 const GLenum dstFormat
= texImage
->Format
;
1984 const GLubyte
*srcPtr
= (const GLubyte
*) image
;
1985 GLubyte
*destPtr
= texImage
->Data
;
1987 if (texImage
->Format
== GL_COLOR_INDEX
) {
1988 /* color index texture */
1990 assert(imgFormat
== GL_COLOR_INDEX
);
1991 for (img
= 0; img
< depth
; img
++) {
1992 for (row
= 0; row
< height
; row
++) {
1993 _mesa_unpack_index_span(ctx
, width
, dstType
, destPtr
,
1994 imgType
, srcPtr
, &_mesa_native_packing
, GL_FALSE
);
1995 destPtr
+= destBytesPerRow
;
1996 srcPtr
+= srcBytesPerRow
;
2003 for (img
= 0; img
< depth
; img
++) {
2004 for (row
= 0; row
< height
; row
++) {
2005 _mesa_unpack_ubyte_color_span(ctx
, width
, dstFormat
, destPtr
,
2006 imgFormat
, imgType
, srcPtr
, &_mesa_native_packing
, GL_FALSE
);
2007 destPtr
+= destBytesPerRow
;
2008 srcPtr
+= srcBytesPerRow
;
2020 _mesa_GetTexImage( GLenum target
, GLint level
, GLenum format
,
2021 GLenum type
, GLvoid
*pixels
)
2023 GET_CURRENT_CONTEXT(ctx
);
2024 const struct gl_texture_object
*texObj
;
2025 struct gl_texture_image
*texImage
;
2026 GLboolean discardImage
;
2028 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetTexImage");
2030 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
2031 gl_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
2035 if (_mesa_sizeof_type(type
) <= 0) {
2036 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
2040 if (_mesa_components_in_format(format
) <= 0) {
2041 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
2050 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[1];
2051 texImage
= texObj
->Image
[level
];
2054 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[2];
2055 texImage
= texObj
->Image
[level
];
2057 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
2058 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
2059 texImage
= texObj
->Image
[level
];
2061 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
2062 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
2063 texImage
= texObj
->NegX
[level
];
2065 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
2066 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
2067 texImage
= texObj
->PosY
[level
];
2069 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
2070 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
2071 texImage
= texObj
->NegY
[level
];
2073 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
2074 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
2075 texImage
= texObj
->PosZ
[level
];
2077 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
2078 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
2079 texImage
= texObj
->NegZ
[level
];
2082 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[3];
2083 texImage
= texObj
->Image
[level
];
2086 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)" );
2091 /* invalid mipmap level */
2095 if (!texImage
->Data
) {
2096 /* try to get the texture image from the device driver */
2097 _mesa_get_teximage_from_driver(ctx
, target
, level
, texObj
);
2098 discardImage
= GL_TRUE
;
2101 discardImage
= GL_FALSE
;
2104 if (texImage
->Data
) {
2105 GLint width
= texImage
->Width
;
2106 GLint height
= texImage
->Height
;
2109 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
2110 _mesa_update_image_transfer_state(ctx
);
2112 for (row
= 0; row
< height
; row
++) {
2113 /* compute destination address in client memory */
2114 GLvoid
*dest
= _mesa_image_address( &ctx
->Unpack
, pixels
,
2116 format
, type
, 0, row
, 0);
2119 if (texImage
->Format
== GL_RGBA
) {
2120 const GLubyte
*src
= texImage
->Data
+ row
* width
* 4 * sizeof(GLubyte
);
2121 /* XXX convolution */
2122 _mesa_pack_rgba_span( ctx
, width
, (CONST
GLubyte (*)[4]) src
,
2123 format
, type
, dest
, &ctx
->Pack
,
2124 ctx
->ImageTransferState
);
2127 /* fetch RGBA row from texture image then pack it in client mem */
2128 GLubyte rgba
[MAX_WIDTH
][4];
2131 switch (texImage
->Format
) {
2133 src
= texImage
->Data
+ row
* width
* sizeof(GLubyte
);
2134 for (i
= 0; i
< width
; i
++) {
2135 rgba
[i
][RCOMP
] = 255;
2136 rgba
[i
][GCOMP
] = 255;
2137 rgba
[i
][BCOMP
] = 255;
2138 rgba
[i
][ACOMP
] = src
[i
];
2142 src
= texImage
->Data
+ row
* width
* sizeof(GLubyte
);
2143 for (i
= 0; i
< width
; i
++) {
2144 rgba
[i
][RCOMP
] = src
[i
];
2145 rgba
[i
][GCOMP
] = src
[i
];
2146 rgba
[i
][BCOMP
] = src
[i
];
2147 rgba
[i
][ACOMP
] = 255;
2150 case GL_LUMINANCE_ALPHA
:
2151 src
= texImage
->Data
+ row
* 2 * width
* sizeof(GLubyte
);
2152 for (i
= 0; i
< width
; i
++) {
2153 rgba
[i
][RCOMP
] = src
[i
*2+0];
2154 rgba
[i
][GCOMP
] = src
[i
*2+0];
2155 rgba
[i
][BCOMP
] = src
[i
*2+0];
2156 rgba
[i
][ACOMP
] = src
[i
*2+1];
2160 src
= texImage
->Data
+ row
* width
* sizeof(GLubyte
);
2161 for (i
= 0; i
< width
; i
++) {
2162 rgba
[i
][RCOMP
] = src
[i
];
2163 rgba
[i
][GCOMP
] = src
[i
];
2164 rgba
[i
][BCOMP
] = src
[i
];
2165 rgba
[i
][ACOMP
] = 255;
2169 src
= texImage
->Data
+ row
* 3 * width
* sizeof(GLubyte
);
2170 for (i
= 0; i
< width
; i
++) {
2171 rgba
[i
][RCOMP
] = src
[i
*3+0];
2172 rgba
[i
][GCOMP
] = src
[i
*3+1];
2173 rgba
[i
][BCOMP
] = src
[i
*3+2];
2174 rgba
[i
][ACOMP
] = 255;
2178 /* this special case should have been handled above! */
2179 gl_problem( ctx
, "error 1 in gl_GetTexImage" );
2181 case GL_COLOR_INDEX
:
2182 gl_problem( ctx
, "GL_COLOR_INDEX not implemented in gl_GetTexImage" );
2185 gl_problem( ctx
, "bad format in gl_GetTexImage" );
2187 /* XXX convolution */
2188 _mesa_pack_rgba_span( ctx
, width
, (const GLubyte (*)[4])rgba
,
2189 format
, type
, dest
, &ctx
->Pack
,
2190 ctx
->ImageTransferState
);
2194 /* if we got the teximage from the device driver we'll discard it now */
2196 FREE(texImage
->Data
);
2197 texImage
->Data
= NULL
;
2205 _mesa_TexSubImage1D( GLenum target
, GLint level
,
2206 GLint xoffset
, GLsizei width
,
2207 GLenum format
, GLenum type
,
2208 const GLvoid
*pixels
)
2210 GET_CURRENT_CONTEXT(ctx
);
2211 struct gl_texture_unit
*texUnit
;
2212 struct gl_texture_object
*texObj
;
2213 struct gl_texture_image
*texImage
;
2214 GLboolean success
= GL_FALSE
;
2216 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
2217 width
, 1, 1, format
, type
)) {
2218 return; /* error was detected */
2221 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2222 texObj
= texUnit
->CurrentD
[1];
2223 texImage
= texObj
->Image
[level
];
2226 if (width
== 0 || !pixels
)
2227 return; /* no-op, not an error */
2229 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
2230 _mesa_update_image_transfer_state(ctx
);
2232 if (!ctx
->ImageTransferState
&& ctx
->Driver
.TexSubImage1D
) {
2233 success
= (*ctx
->Driver
.TexSubImage1D
)( ctx
, target
, level
, xoffset
,
2234 width
, format
, type
, pixels
,
2235 &ctx
->Unpack
, texObj
, texImage
);
2238 /* XXX if Driver.TexSubImage1D, unpack image and try again? */
2240 const GLint texComponents
= components_in_intformat(texImage
->Format
);
2241 const GLenum texFormat
= texImage
->Format
;
2242 const GLint xoffsetb
= xoffset
+ texImage
->Border
;
2243 GLboolean retain
= GL_TRUE
;
2244 if (!texImage
->Data
) {
2245 _mesa_get_teximage_from_driver( ctx
, target
, level
, texObj
);
2246 if (!texImage
->Data
) {
2247 make_null_texture(texImage
);
2249 if (!texImage
->Data
)
2250 return; /* we're really out of luck! */
2253 if (texFormat
== GL_COLOR_INDEX
) {
2254 /* color index texture */
2255 GLubyte
*dst
= texImage
->Data
+ xoffsetb
* texComponents
;
2256 const GLvoid
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
, width
,
2257 1, format
, type
, 0, 0, 0);
2258 _mesa_unpack_index_span(ctx
, width
, GL_UNSIGNED_BYTE
, dst
,
2259 type
, src
, &ctx
->Unpack
,
2260 ctx
->ImageTransferState
);
2264 GLubyte
*dst
= texImage
->Data
+ xoffsetb
* texComponents
;
2265 const GLvoid
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
, width
,
2266 1, format
, type
, 0, 0, 0);
2267 /* XXX change for convolution */
2268 _mesa_unpack_ubyte_color_span(ctx
, width
, texFormat
, dst
, format
,
2269 type
, src
, &ctx
->Unpack
,
2270 ctx
->ImageTransferState
);
2273 if (ctx
->Driver
.TexImage1D
) {
2274 (*ctx
->Driver
.TexImage1D
)( ctx
, target
, level
, texImage
->Format
,
2275 GL_UNSIGNED_BYTE
, texImage
->Data
,
2276 &_mesa_native_packing
, texObj
, texImage
,
2280 if (!retain
&& texImage
->Data
) {
2281 FREE(texImage
->Data
);
2282 texImage
->Data
= NULL
;
2286 /*gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[1] );*/
2291 _mesa_TexSubImage2D( GLenum target
, GLint level
,
2292 GLint xoffset
, GLint yoffset
,
2293 GLsizei width
, GLsizei height
,
2294 GLenum format
, GLenum type
,
2295 const GLvoid
*pixels
)
2297 GET_CURRENT_CONTEXT(ctx
);
2298 struct gl_texture_unit
*texUnit
;
2299 struct gl_texture_object
*texObj
;
2300 struct gl_texture_image
*texImage
;
2301 GLboolean success
= GL_FALSE
;
2303 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2304 width
, height
, 1, format
, type
)) {
2305 return; /* error was detected */
2308 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2309 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2310 texImage
= texObj
->Image
[level
];
2313 if (width
== 0 || height
== 0 || !pixels
)
2314 return; /* no-op, not an error */
2316 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
2317 _mesa_update_image_transfer_state(ctx
);
2319 if (!ctx
->ImageTransferState
&& ctx
->Driver
.TexSubImage2D
) {
2320 success
= (*ctx
->Driver
.TexSubImage2D
)( ctx
, target
, level
, xoffset
,
2321 yoffset
, width
, height
, format
, type
,
2322 pixels
, &ctx
->Unpack
, texObj
, texImage
);
2325 /* XXX if Driver.TexSubImage2D, unpack image and try again? */
2327 const GLint texComponents
= components_in_intformat(texImage
->Format
);
2328 const GLenum texFormat
= texImage
->Format
;
2329 const GLint xoffsetb
= xoffset
+ texImage
->Border
;
2330 const GLint yoffsetb
= yoffset
+ texImage
->Border
;
2331 const GLint srcStride
= _mesa_image_row_stride(&ctx
->Unpack
, width
,
2333 const GLint dstStride
= texImage
->Width
* texComponents
*sizeof(GLubyte
);
2334 GLboolean retain
= GL_TRUE
;
2336 if (!texImage
->Data
) {
2337 _mesa_get_teximage_from_driver( ctx
, target
, level
, texObj
);
2338 if (!texImage
->Data
) {
2339 make_null_texture(texImage
);
2341 if (!texImage
->Data
)
2342 return; /* we're really out of luck! */
2345 if (texFormat
== GL_COLOR_INDEX
) {
2346 /* color index texture */
2347 GLubyte
*dst
= texImage
->Data
2348 + (yoffsetb
* texImage
->Width
+ xoffsetb
) * texComponents
;
2349 const GLubyte
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
,
2350 width
, height
, format
, type
, 0, 0, 0);
2352 for (row
= 0; row
< height
; row
++) {
2353 _mesa_unpack_index_span(ctx
, width
, GL_UNSIGNED_BYTE
, dst
, type
,
2354 (const GLvoid
*) src
, &ctx
->Unpack
,
2355 ctx
->ImageTransferState
);
2362 GLubyte
*dst
= texImage
->Data
2363 + (yoffsetb
* texImage
->Width
+ xoffsetb
) * texComponents
;
2364 const GLubyte
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
,
2365 width
, height
, format
, type
, 0, 0, 0);
2367 /* XXX change for convolution */
2368 for (row
= 0; row
< height
; row
++) {
2369 _mesa_unpack_ubyte_color_span(ctx
, width
, texFormat
, dst
, format
,
2370 type
, (const GLvoid
*) src
,
2372 ctx
->ImageTransferState
);
2378 if (ctx
->Driver
.TexImage2D
) {
2379 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, texImage
->Format
,
2380 GL_UNSIGNED_BYTE
, texImage
->Data
,
2381 &_mesa_native_packing
, texObj
, texImage
,
2385 if (!retain
&& texImage
->Data
) {
2386 FREE(texImage
->Data
);
2387 texImage
->Data
= NULL
;
2390 #ifdef OLD_DD_TEXTURE
2391 /* XXX this will be removed in the future */
2392 if (ctx
->Driver
.TexSubImage
) {
2393 (*ctx
->Driver
.TexSubImage
)(ctx
, target
, texObj
, level
,
2394 xoffset
, yoffset
, width
, height
,
2395 texImage
->IntFormat
, texImage
);
2397 else if (ctx
->Driver
.TexImage
) {
2398 (*ctx
->Driver
.TexImage
)(ctx
, GL_TEXTURE_2D
, texObj
,
2399 level
, texImage
->IntFormat
, texImage
);
2408 _mesa_TexSubImage3D( GLenum target
, GLint level
,
2409 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2410 GLsizei width
, GLsizei height
, GLsizei depth
,
2411 GLenum format
, GLenum type
,
2412 const GLvoid
*pixels
)
2414 GET_CURRENT_CONTEXT(ctx
);
2415 struct gl_texture_unit
*texUnit
;
2416 struct gl_texture_object
*texObj
;
2417 struct gl_texture_image
*texImage
;
2418 GLboolean success
= GL_FALSE
;
2420 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2421 width
, height
, depth
, format
, type
)) {
2422 return; /* error was detected */
2425 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2426 texObj
= texUnit
->CurrentD
[3];
2427 texImage
= texObj
->Image
[level
];
2430 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
2431 return; /* no-op, not an error */
2433 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
2434 _mesa_update_image_transfer_state(ctx
);
2436 if (!ctx
->ImageTransferState
&& ctx
->Driver
.TexSubImage3D
) {
2437 success
= (*ctx
->Driver
.TexSubImage3D
)( ctx
, target
, level
, xoffset
,
2438 yoffset
, zoffset
, width
, height
, depth
, format
,
2439 type
, pixels
, &ctx
->Unpack
, texObj
, texImage
);
2442 /* XXX if Driver.TexSubImage3D, unpack image and try again? */
2444 const GLint texComponents
= components_in_intformat(texImage
->Format
);
2445 const GLenum texFormat
= texImage
->Format
;
2446 const GLint xoffsetb
= xoffset
+ texImage
->Border
;
2447 const GLint yoffsetb
= yoffset
+ texImage
->Border
;
2448 const GLint zoffsetb
= zoffset
+ texImage
->Border
;
2449 const GLint texWidth
= texImage
->Width
;
2450 const GLint dstRectArea
= texWidth
* texImage
->Height
;
2451 const GLint srcStride
= _mesa_image_row_stride(&ctx
->Unpack
,
2452 width
, format
, type
);
2453 const GLint dstStride
= texWidth
* texComponents
* sizeof(GLubyte
);
2454 GLboolean retain
= GL_TRUE
;
2456 if (texFormat
== GL_COLOR_INDEX
) {
2457 /* color index texture */
2459 for (img
= 0; img
< depth
; img
++) {
2460 const GLubyte
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
,
2461 width
, height
, format
, type
, img
, 0, 0);
2462 GLubyte
*dst
= texImage
->Data
+ ((zoffsetb
+ img
) * dstRectArea
2463 + yoffsetb
* texWidth
+ xoffsetb
) * texComponents
;
2464 for (row
= 0; row
< height
; row
++) {
2465 _mesa_unpack_index_span(ctx
, width
, GL_UNSIGNED_BYTE
, dst
,
2466 type
, (const GLvoid
*) src
,
2467 &ctx
->Unpack
, ctx
->ImageTransferState
);
2476 /* XXX convolution */
2477 for (img
= 0; img
< depth
; img
++) {
2478 const GLubyte
*src
= _mesa_image_address(&ctx
->Unpack
, pixels
,
2479 width
, height
, format
, type
, img
, 0, 0);
2480 GLubyte
*dst
= texImage
->Data
+ ((zoffsetb
+ img
) * dstRectArea
2481 + yoffsetb
* texWidth
+ xoffsetb
) * texComponents
;
2482 for (row
= 0; row
< height
; row
++) {
2483 _mesa_unpack_ubyte_color_span(ctx
, width
, texFormat
, dst
,
2485 (const GLvoid
*) src
,
2487 ctx
->ImageTransferState
);
2494 if (ctx
->Driver
.TexImage3D
) {
2495 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, texImage
->Format
,
2496 GL_UNSIGNED_BYTE
, texImage
->Data
,
2497 &_mesa_native_packing
, texObj
, texImage
,
2501 if (!retain
&& texImage
->Data
) {
2502 FREE(texImage
->Data
);
2503 texImage
->Data
= NULL
;
2511 * Read an RGBA image from the frame buffer.
2512 * This is used by glCopyTexSubImage[12]D().
2513 * Input: ctx - the context
2514 * x, y - lower left corner
2515 * width, height - size of region to read
2516 * Return: pointer to block of GL_RGBA, GLubyte data.
2519 read_color_image( GLcontext
*ctx
, GLint x
, GLint y
,
2520 GLsizei width
, GLsizei height
)
2523 GLubyte
*image
, *dst
;
2525 image
= (GLubyte
*) MALLOC(width
* height
* 4 * sizeof(GLubyte
));
2529 /* Select buffer to read from */
2530 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->ReadBuffer
,
2531 ctx
->Pixel
.DriverReadBuffer
);
2533 /* XXX TODO we have to apply pixel transfer ops here! */
2536 stride
= width
* 4 * sizeof(GLubyte
);
2537 for (i
= 0; i
< height
; i
++) {
2538 gl_read_rgba_span( ctx
, ctx
->ReadBuffer
, width
, x
, y
+ i
,
2539 (GLubyte (*)[4]) dst
);
2543 /* Read from draw buffer (the default) */
2544 (*ctx
->Driver
.SetReadBuffer
)( ctx
, ctx
->DrawBuffer
,
2545 ctx
->Color
.DriverDrawBuffer
);
2553 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
2554 GLenum internalFormat
,
2556 GLsizei width
, GLint border
)
2558 GET_CURRENT_CONTEXT(ctx
);
2559 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexImage1D");
2561 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
2565 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
2566 _mesa_update_image_transfer_state(ctx
);
2568 if (ctx
->ImageTransferState
|| !ctx
->Driver
.CopyTexImage1D
2569 || !(*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
,
2570 internalFormat
, x
, y
, width
, border
))
2572 struct gl_pixelstore_attrib unpackSave
;
2574 /* get image from framebuffer */
2575 GLubyte
*image
= read_color_image( ctx
, x
, y
, width
, 1 );
2577 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D" );
2581 /* call glTexImage1D to redefine the texture */
2582 unpackSave
= ctx
->Unpack
;
2583 ctx
->Unpack
= _mesa_native_packing
;
2584 (*ctx
->Exec
->TexImage1D
)( target
, level
, internalFormat
, width
,
2585 border
, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2586 ctx
->Unpack
= unpackSave
;
2595 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
2596 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
2599 GET_CURRENT_CONTEXT(ctx
);
2600 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexImage2D");
2602 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
2603 width
, height
, border
))
2606 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
2607 _mesa_update_image_transfer_state(ctx
);
2609 if (ctx
->ImageTransferState
|| !ctx
->Driver
.CopyTexImage2D
2610 || !(*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
,
2611 internalFormat
, x
, y
, width
, height
, border
))
2613 struct gl_pixelstore_attrib unpackSave
;
2615 /* get image from framebuffer */
2616 GLubyte
*image
= read_color_image( ctx
, x
, y
, width
, height
);
2618 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D" );
2622 /* call glTexImage2D to redefine the texture */
2623 unpackSave
= ctx
->Unpack
;
2624 ctx
->Unpack
= _mesa_native_packing
;
2625 (ctx
->Exec
->TexImage2D
)( target
, level
, internalFormat
, width
,
2626 height
, border
, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2627 ctx
->Unpack
= unpackSave
;
2636 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
2637 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
2639 GET_CURRENT_CONTEXT(ctx
);
2640 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexSubImage1D");
2642 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
2643 xoffset
, 0, 0, width
, 1))
2646 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
2647 _mesa_update_image_transfer_state(ctx
);
2649 if (ctx
->ImageTransferState
|| !ctx
->Driver
.CopyTexSubImage1D
2650 || !(*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
,
2651 xoffset
, x
, y
, width
)) {
2652 struct gl_texture_unit
*texUnit
;
2653 struct gl_texture_image
*teximage
;
2654 struct gl_pixelstore_attrib unpackSave
;
2657 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2658 teximage
= texUnit
->CurrentD
[1]->Image
[level
];
2661 /* get image from frame buffer */
2662 image
= read_color_image(ctx
, x
, y
, width
, 1);
2664 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage2D" );
2668 /* now call glTexSubImage1D to do the real work */
2669 unpackSave
= ctx
->Unpack
;
2670 ctx
->Unpack
= _mesa_native_packing
;
2671 _mesa_TexSubImage1D(target
, level
, xoffset
, width
,
2672 GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2673 ctx
->Unpack
= unpackSave
;
2682 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
2683 GLint xoffset
, GLint yoffset
,
2684 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2686 GET_CURRENT_CONTEXT(ctx
);
2687 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexSubImage2D");
2689 if (copytexsubimage_error_check(ctx
, 2, target
, level
,
2690 xoffset
, yoffset
, 0, width
, height
))
2693 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
2694 _mesa_update_image_transfer_state(ctx
);
2696 if (ctx
->ImageTransferState
|| !ctx
->Driver
.CopyTexSubImage2D
2697 || !(*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
2698 xoffset
, yoffset
, x
, y
, width
, height
)) {
2699 struct gl_texture_unit
*texUnit
;
2700 struct gl_texture_image
*teximage
;
2701 struct gl_pixelstore_attrib unpackSave
;
2704 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2705 teximage
= texUnit
->CurrentD
[2]->Image
[level
];
2708 /* get image from frame buffer */
2709 image
= read_color_image(ctx
, x
, y
, width
, height
);
2711 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage2D" );
2715 /* now call glTexSubImage2D to do the real work */
2716 unpackSave
= ctx
->Unpack
;
2717 ctx
->Unpack
= _mesa_native_packing
;
2718 _mesa_TexSubImage2D(target
, level
, xoffset
, yoffset
, width
, height
,
2719 GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2720 ctx
->Unpack
= unpackSave
;
2729 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
2730 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2731 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2733 GET_CURRENT_CONTEXT(ctx
);
2734 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexSubImage3D");
2736 if (copytexsubimage_error_check(ctx
, 3, target
, level
,
2737 xoffset
, yoffset
, zoffset
, width
, height
))
2740 if (ctx
->ImageTransferState
== UPDATE_IMAGE_TRANSFER_STATE
)
2741 _mesa_update_image_transfer_state(ctx
);
2743 if (ctx
->ImageTransferState
|| !ctx
->Driver
.CopyTexSubImage3D
2744 || !(*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
2745 xoffset
, yoffset
, zoffset
, x
, y
, width
, height
)) {
2746 struct gl_texture_unit
*texUnit
;
2747 struct gl_texture_image
*teximage
;
2748 struct gl_pixelstore_attrib unpackSave
;
2751 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2752 teximage
= texUnit
->CurrentD
[3]->Image
[level
];
2755 /* get image from frame buffer */
2756 image
= read_color_image(ctx
, x
, y
, width
, height
);
2758 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage2D" );
2762 /* now call glTexSubImage2D to do the real work */
2763 unpackSave
= ctx
->Unpack
;
2764 ctx
->Unpack
= _mesa_native_packing
;
2765 _mesa_TexSubImage3D(target
, level
, xoffset
, yoffset
, zoffset
,
2766 width
, height
, 1, GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
2767 ctx
->Unpack
= unpackSave
;
2776 _mesa_CompressedTexImage1DARB(GLenum target
, GLint level
,
2777 GLenum internalFormat
, GLsizei width
,
2778 GLint border
, GLsizei imageSize
,
2781 GET_CURRENT_CONTEXT(ctx
);
2782 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCompressedTexImage1DARB");
2784 switch (internalFormat
) {
2785 case GL_COMPRESSED_ALPHA_ARB
:
2786 case GL_COMPRESSED_LUMINANCE_ARB
:
2787 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2788 case GL_COMPRESSED_INTENSITY_ARB
:
2789 case GL_COMPRESSED_RGB_ARB
:
2790 case GL_COMPRESSED_RGBA_ARB
:
2791 gl_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB");
2794 /* silence compiler warning */
2798 if (target
== GL_TEXTURE_1D
) {
2799 struct gl_texture_unit
*texUnit
;
2800 struct gl_texture_object
*texObj
;
2801 struct gl_texture_image
*texImage
;
2802 GLsizei computedImageSize
;
2804 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2805 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
2806 return; /* error in texture image was detected */
2809 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2810 texObj
= texUnit
->CurrentD
[1];
2811 texImage
= texObj
->Image
[level
];
2814 texImage
= _mesa_alloc_texture_image();
2815 texObj
->Image
[level
] = texImage
;
2817 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage1DARB");
2821 else if (texImage
->Data
) {
2822 FREE(texImage
->Data
);
2823 texImage
->Data
= NULL
;
2826 /* setup the teximage struct's fields */
2827 init_texture_image(ctx
, texImage
, width
, 1, 1,
2828 border
, internalFormat
);
2830 /* process the texture image */
2832 GLboolean retain
= GL_TRUE
;
2833 GLboolean success
= GL_FALSE
;
2834 if (ctx
->Driver
.CompressedTexImage1D
) {
2835 success
= (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
,
2836 imageSize
, data
, texObj
, texImage
, &retain
);
2838 if (retain
|| !success
) {
2839 /* make internal copy of the texture image */
2840 computedImageSize
= _mesa_compressed_image_size(ctx
,
2846 if (computedImageSize
!= imageSize
) {
2847 gl_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexImage1DARB(imageSize)");
2850 texImage
->Data
= MALLOC(computedImageSize
);
2851 if (texImage
->Data
) {
2852 MEMCPY(texImage
->Data
, data
, computedImageSize
);
2855 if (!retain
&& texImage
->Data
) {
2856 FREE(texImage
->Data
);
2857 texImage
->Data
= NULL
;
2861 make_null_texture(texImage
);
2862 if (ctx
->Driver
.CompressedTexImage1D
) {
2864 (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
, 0,
2865 texImage
->Data
, texObj
,
2871 gl_put_texobj_on_dirty_list( ctx
, texObj
);
2872 ctx
->NewState
|= NEW_TEXTURING
;
2874 else if (target
== GL_PROXY_TEXTURE_1D
) {
2875 /* Proxy texture: check for errors and update proxy state */
2876 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2877 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
2878 /* if error, clear all proxy texture image parameters */
2879 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
2880 MEMSET( ctx
->Texture
.Proxy1D
->Image
[level
], 0,
2881 sizeof(struct gl_texture_image
) );
2885 /* if no error, update proxy texture image parameters */
2886 init_texture_image(ctx
, ctx
->Texture
.Proxy1D
->Image
[level
],
2887 width
, 1, 1, border
, internalFormat
);
2891 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB(target)" );
2898 _mesa_CompressedTexImage2DARB(GLenum target
, GLint level
,
2899 GLenum internalFormat
, GLsizei width
,
2900 GLsizei height
, GLint border
, GLsizei imageSize
,
2903 GET_CURRENT_CONTEXT(ctx
);
2904 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCompressedTexImage2DARB");
2906 switch (internalFormat
) {
2907 case GL_COMPRESSED_ALPHA_ARB
:
2908 case GL_COMPRESSED_LUMINANCE_ARB
:
2909 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2910 case GL_COMPRESSED_INTENSITY_ARB
:
2911 case GL_COMPRESSED_RGB_ARB
:
2912 case GL_COMPRESSED_RGBA_ARB
:
2913 gl_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB");
2916 /* silence compiler warning */
2920 if (target
==GL_TEXTURE_2D
||
2921 (ctx
->Extensions
.HaveTextureCubeMap
&&
2922 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2923 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
2924 struct gl_texture_unit
*texUnit
;
2925 struct gl_texture_object
*texObj
;
2926 struct gl_texture_image
*texImage
;
2927 GLsizei computedImageSize
;
2929 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2930 GL_NONE
, GL_NONE
, 1, width
, height
, 1, border
)) {
2931 return; /* error in texture image was detected */
2934 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2935 texObj
= texUnit
->CurrentD
[2];
2936 texImage
= texObj
->Image
[level
];
2939 texImage
= _mesa_alloc_texture_image();
2940 texObj
->Image
[level
] = texImage
;
2942 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
2946 else if (texImage
->Data
) {
2947 FREE(texImage
->Data
);
2948 texImage
->Data
= NULL
;
2951 /* setup the teximage struct's fields */
2952 init_texture_image(ctx
, texImage
, width
, height
, 1, border
, internalFormat
);
2954 /* process the texture image */
2956 GLboolean retain
= GL_TRUE
;
2957 GLboolean success
= GL_FALSE
;
2958 if (ctx
->Driver
.CompressedTexImage2D
) {
2959 success
= (*ctx
->Driver
.CompressedTexImage2D
)( ctx
,
2968 if (retain
|| !success
) {
2969 /* make internal copy of the texture image */
2970 computedImageSize
= _mesa_compressed_image_size(ctx
,
2976 if (computedImageSize
!= imageSize
) {
2977 gl_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexImage2DARB(imageSize)");
2980 texImage
->Data
= MALLOC(computedImageSize
);
2981 if (texImage
->Data
) {
2982 MEMCPY(texImage
->Data
, data
, computedImageSize
);
2985 if (!retain
&& texImage
->Data
) {
2986 FREE(texImage
->Data
);
2987 texImage
->Data
= NULL
;
2991 make_null_texture(texImage
);
2992 if (ctx
->Driver
.CompressedTexImage2D
) {
2994 (*ctx
->Driver
.CompressedTexImage2D
)( ctx
, target
, level
, 0,
2995 texImage
->Data
, texObj
,
3001 gl_put_texobj_on_dirty_list( ctx
, texObj
);
3002 ctx
->NewState
|= NEW_TEXTURING
;
3004 else if (target
== GL_PROXY_TEXTURE_2D
) {
3005 /* Proxy texture: check for errors and update proxy state */
3006 if (texture_error_check(ctx
, target
, level
, internalFormat
,
3007 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
3008 /* if error, clear all proxy texture image parameters */
3009 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
3010 MEMSET( ctx
->Texture
.Proxy2D
->Image
[level
], 0,
3011 sizeof(struct gl_texture_image
) );
3015 /* if no error, update proxy texture image parameters */
3016 init_texture_image(ctx
, ctx
->Texture
.Proxy2D
->Image
[level
],
3017 width
, 1, 1, border
, internalFormat
);
3021 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB(target)" );
3028 _mesa_CompressedTexImage3DARB(GLenum target
, GLint level
,
3029 GLenum internalFormat
, GLsizei width
,
3030 GLsizei height
, GLsizei depth
, GLint border
,
3031 GLsizei imageSize
, const GLvoid
*data
)
3033 GET_CURRENT_CONTEXT(ctx
);
3034 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCompressedTexImage3DARB");
3036 switch (internalFormat
) {
3037 case GL_COMPRESSED_ALPHA_ARB
:
3038 case GL_COMPRESSED_LUMINANCE_ARB
:
3039 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
3040 case GL_COMPRESSED_INTENSITY_ARB
:
3041 case GL_COMPRESSED_RGB_ARB
:
3042 case GL_COMPRESSED_RGBA_ARB
:
3043 gl_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB");
3046 /* silence compiler warning */
3050 if (target
== GL_TEXTURE_3D
) {
3051 struct gl_texture_unit
*texUnit
;
3052 struct gl_texture_object
*texObj
;
3053 struct gl_texture_image
*texImage
;
3054 GLsizei computedImageSize
;
3056 if (texture_error_check(ctx
, target
, level
, internalFormat
,
3057 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
)) {
3058 return; /* error in texture image was detected */
3061 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3062 texObj
= texUnit
->CurrentD
[3];
3063 texImage
= texObj
->Image
[level
];
3066 texImage
= _mesa_alloc_texture_image();
3067 texObj
->Image
[level
] = texImage
;
3069 gl_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage3DARB");
3073 else if (texImage
->Data
) {
3074 FREE(texImage
->Data
);
3075 texImage
->Data
= NULL
;
3078 /* setup the teximage struct's fields */
3079 init_texture_image(ctx
, texImage
, width
, height
, depth
,
3080 border
, internalFormat
);
3082 /* process the texture image */
3084 GLboolean retain
= GL_TRUE
;
3085 GLboolean success
= GL_FALSE
;
3086 if (ctx
->Driver
.CompressedTexImage3D
) {
3087 success
= (*ctx
->Driver
.CompressedTexImage3D
)(ctx
, target
, level
,
3092 if (retain
|| !success
) {
3093 /* make internal copy of the texture image */
3094 computedImageSize
= _mesa_compressed_image_size(ctx
,
3100 if (computedImageSize
!= imageSize
) {
3101 gl_error(ctx
, GL_INVALID_VALUE
, "glCompressedTexImage3DARB(imageSize)");
3104 texImage
->Data
= MALLOC(computedImageSize
);
3105 if (texImage
->Data
) {
3106 MEMCPY(texImage
->Data
, data
, computedImageSize
);
3109 if (!retain
&& texImage
->Data
) {
3110 FREE(texImage
->Data
);
3111 texImage
->Data
= NULL
;
3115 make_null_texture(texImage
);
3116 if (ctx
->Driver
.CompressedTexImage3D
) {
3118 (*ctx
->Driver
.CompressedTexImage3D
)( ctx
, target
, level
, 0,
3119 texImage
->Data
, texObj
,
3125 gl_put_texobj_on_dirty_list( ctx
, texObj
);
3126 ctx
->NewState
|= NEW_TEXTURING
;
3128 else if (target
== GL_PROXY_TEXTURE_3D
) {
3129 /* Proxy texture: check for errors and update proxy state */
3130 if (texture_error_check(ctx
, target
, level
, internalFormat
,
3131 GL_NONE
, GL_NONE
, 1, width
, height
, depth
, border
)) {
3132 /* if error, clear all proxy texture image parameters */
3133 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
3134 MEMSET( ctx
->Texture
.Proxy3D
->Image
[level
], 0,
3135 sizeof(struct gl_texture_image
) );
3139 /* if no error, update proxy texture image parameters */
3140 init_texture_image(ctx
, ctx
->Texture
.Proxy3D
->Image
[level
],
3141 width
, 1, 1, border
, internalFormat
);
3145 gl_error( ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB(target)" );
3152 _mesa_CompressedTexSubImage1DARB(GLenum target
, GLint level
, GLint xoffset
,
3153 GLsizei width
, GLenum format
,
3154 GLsizei imageSize
, const GLvoid
*data
)
3156 GET_CURRENT_CONTEXT(ctx
);
3157 struct gl_texture_unit
*texUnit
;
3158 struct gl_texture_object
*texObj
;
3159 struct gl_texture_image
*texImage
;
3160 GLboolean success
= GL_FALSE
;
3162 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
3163 width
, 1, 1, format
, GL_NONE
)) {
3164 return; /* error was detected */
3167 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3168 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
3169 texImage
= texObj
->Image
[level
];
3172 if (width
== 0 || !data
)
3173 return; /* no-op, not an error */
3175 if (ctx
->Driver
.CompressedTexSubImage1D
) {
3176 success
= (*ctx
->Driver
.CompressedTexSubImage1D
)(ctx
, target
, level
,
3177 xoffset
, width
, format
, imageSize
, data
, texObj
, texImage
);
3180 /* XXX what else can we do? */
3181 gl_problem(ctx
, "glCompressedTexSubImage1DARB failed!");
3188 _mesa_CompressedTexSubImage2DARB(GLenum target
, GLint level
, GLint xoffset
,
3189 GLint yoffset
, GLsizei width
, GLsizei height
,
3190 GLenum format
, GLsizei imageSize
,
3193 GET_CURRENT_CONTEXT(ctx
);
3194 struct gl_texture_unit
*texUnit
;
3195 struct gl_texture_object
*texObj
;
3196 struct gl_texture_image
*texImage
;
3197 GLboolean success
= GL_FALSE
;
3199 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
3200 width
, height
, 1, format
, GL_NONE
)) {
3201 return; /* error was detected */
3204 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3205 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
3206 texImage
= texObj
->Image
[level
];
3209 if (width
== 0 || height
== 0 || !data
)
3210 return; /* no-op, not an error */
3212 if (ctx
->Driver
.CompressedTexSubImage2D
) {
3213 success
= (*ctx
->Driver
.CompressedTexSubImage2D
)(ctx
, target
, level
,
3214 xoffset
, yoffset
, width
, height
, format
,
3215 imageSize
, data
, texObj
, texImage
);
3218 /* XXX what else can we do? */
3219 gl_problem(ctx
, "glCompressedTexSubImage2DARB failed!");
3226 _mesa_CompressedTexSubImage3DARB(GLenum target
, GLint level
, GLint xoffset
,
3227 GLint yoffset
, GLint zoffset
, GLsizei width
,
3228 GLsizei height
, GLsizei depth
, GLenum format
,
3229 GLsizei imageSize
, const GLvoid
*data
)
3231 GET_CURRENT_CONTEXT(ctx
);
3232 struct gl_texture_unit
*texUnit
;
3233 struct gl_texture_object
*texObj
;
3234 struct gl_texture_image
*texImage
;
3235 GLboolean success
= GL_FALSE
;
3237 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
3238 width
, height
, depth
, format
, GL_NONE
)) {
3239 return; /* error was detected */
3242 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
3243 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
3244 texImage
= texObj
->Image
[level
];
3247 if (width
== 0 || height
== 0 || depth
== 0 || !data
)
3248 return; /* no-op, not an error */
3250 if (ctx
->Driver
.CompressedTexSubImage3D
) {
3251 success
= (*ctx
->Driver
.CompressedTexSubImage3D
)(ctx
, target
, level
,
3252 xoffset
, yoffset
, zoffset
, width
, height
, depth
,
3253 format
, imageSize
, data
, texObj
, texImage
);
3256 /* XXX what else can we do? */
3257 gl_problem(ctx
, "glCompressedTexSubImage3DARB failed!");
3264 _mesa_GetCompressedTexImageARB(GLenum target
, GLint level
, GLvoid
*img
)
3266 GET_CURRENT_CONTEXT(ctx
);
3267 const struct gl_texture_object
*texObj
;
3268 struct gl_texture_image
*texImage
;
3270 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetCompressedTexImageARB");
3272 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
3273 gl_error( ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)" );
3279 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[1];
3280 texImage
= texObj
->Image
[level
];
3283 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[2];
3284 texImage
= texObj
->Image
[level
];
3286 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
3287 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3288 texImage
= texObj
->Image
[level
];
3290 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
3291 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3292 texImage
= texObj
->NegX
[level
];
3294 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
3295 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3296 texImage
= texObj
->PosY
[level
];
3298 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
3299 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3300 texImage
= texObj
->NegY
[level
];
3302 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
3303 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3304 texImage
= texObj
->PosZ
[level
];
3306 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
3307 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentCubeMap
;
3308 texImage
= texObj
->NegZ
[level
];
3311 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[3];
3312 texImage
= texObj
->Image
[level
];
3315 gl_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB(target)");
3320 /* invalid mipmap level */
3321 gl_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
3325 if (!texImage
->IsCompressed
) {
3326 gl_error(ctx
, GL_INVALID_OPERATION
, "glGetCompressedTexImageARB");
3333 if (ctx
->Driver
.GetCompressedTexImage
) {
3334 (*ctx
->Driver
.GetCompressedTexImage
)(ctx
, target
, level
, img
, texObj
,
3338 gl_problem(ctx
, "Driver doesn't implement GetCompressedTexImage");