1 /* $Id: teximage.c,v 1.116 2002/09/23 16:37:14 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2002 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.
39 #include "texformat.h"
50 * Mesa's native texture datatype is GLchan. Native formats are
51 * GL_ALPHA, GL_LUMINANCE, GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, GL_RGBA,
53 * Device drivers are free to implement any internal format they want.
58 static void PrintTexture(GLcontext
*ctx
, const struct gl_texture_image
*img
)
60 #if CHAN_TYPE == GL_FLOAT
61 _mesa_problem(NULL
, "PrintTexture doesn't support float channels");
64 const GLchan
*data
= (const GLchan
*) img
->Data
;
67 _mesa_printf(ctx
, "No texture data\n");
71 switch (img
->Format
) {
78 case GL_LUMINANCE_ALPHA
:
88 _mesa_problem(NULL
, "error in PrintTexture\n");
92 for (i
= 0; i
< img
->Height
; i
++) {
93 for (j
= 0; j
< img
->Width
; j
++) {
95 _mesa_printf(ctx
, "%02x ", data
[0]);
97 _mesa_printf(ctx
, "%02x%02x ", data
[0], data
[1]);
99 _mesa_printf(ctx
, "%02x%02x%02x ", data
[0], data
[1], data
[2]);
101 _mesa_printf(ctx
, "%02x%02x%02x%02x ", data
[0], data
[1], data
[2], data
[3]);
102 data
+= (img
->RowStride
- img
->Width
) * c
;
104 _mesa_printf(ctx
, "\n");
113 * Compute log base 2 of n.
114 * If n isn't an exact power of two return -1.
115 * If n < 0 return -1.
142 * Given an internal texture format enum or 1, 2, 3, 4 return the
143 * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE,
144 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.
145 * Return -1 if invalid enum.
148 _mesa_base_tex_format( GLcontext
*ctx
, GLint format
)
151 * Ask the driver for the base format, if it doesn't
152 * know, it will return -1;
154 if (ctx
->Driver
.BaseCompressedTexFormat
) {
155 GLint ifmt
= (*ctx
->Driver
.BaseCompressedTexFormat
)(ctx
, format
);
175 case GL_LUMINANCE_ALPHA
:
176 case GL_LUMINANCE4_ALPHA4
:
177 case GL_LUMINANCE6_ALPHA2
:
178 case GL_LUMINANCE8_ALPHA8
:
179 case GL_LUMINANCE12_ALPHA4
:
180 case GL_LUMINANCE12_ALPHA12
:
181 case GL_LUMINANCE16_ALPHA16
:
182 return GL_LUMINANCE_ALPHA
;
210 case GL_COLOR_INDEX1_EXT
:
211 case GL_COLOR_INDEX2_EXT
:
212 case GL_COLOR_INDEX4_EXT
:
213 case GL_COLOR_INDEX8_EXT
:
214 case GL_COLOR_INDEX12_EXT
:
215 case GL_COLOR_INDEX16_EXT
:
216 return GL_COLOR_INDEX
;
217 case GL_DEPTH_COMPONENT
:
218 case GL_DEPTH_COMPONENT16_SGIX
:
219 case GL_DEPTH_COMPONENT24_SGIX
:
220 case GL_DEPTH_COMPONENT32_SGIX
:
221 if (ctx
->Extensions
.SGIX_depth_texture
)
222 return GL_DEPTH_COMPONENT
;
226 if (ctx
->Extensions
.MESA_ycbcr_texture
)
227 return GL_YCBCR_MESA
;
231 return -1; /* error */
237 * Test if the given image format is a color/rgba format. That is,
238 * not color index, depth, stencil, etc.
241 is_color_format(GLenum format
)
256 case GL_LUMINANCE_ALPHA
:
257 case GL_LUMINANCE4_ALPHA4
:
258 case GL_LUMINANCE6_ALPHA2
:
259 case GL_LUMINANCE8_ALPHA8
:
260 case GL_LUMINANCE12_ALPHA4
:
261 case GL_LUMINANCE12_ALPHA12
:
262 case GL_LUMINANCE16_ALPHA16
:
287 case GL_YCBCR_MESA
: /* not considered to be RGB */
295 is_index_format(GLenum format
)
299 case GL_COLOR_INDEX1_EXT
:
300 case GL_COLOR_INDEX2_EXT
:
301 case GL_COLOR_INDEX4_EXT
:
302 case GL_COLOR_INDEX8_EXT
:
303 case GL_COLOR_INDEX12_EXT
:
304 case GL_COLOR_INDEX16_EXT
:
313 * Return GL_TRUE if internalFormat is a compressed format, return GL_FALSE
317 is_compressed_format(GLcontext
*ctx
, GLenum internalFormat
)
319 if (ctx
->Driver
.BaseCompressedTexFormat
) {
320 GLint b
= (*ctx
->Driver
.BaseCompressedTexFormat
)(ctx
, internalFormat
);
332 * Store a gl_texture_image pointer in a gl_texture_object structure
333 * according to the target and level parameters.
334 * This was basically prompted by the introduction of cube maps.
337 _mesa_set_tex_image(struct gl_texture_object
*tObj
,
338 GLenum target
, GLint level
,
339 struct gl_texture_image
*texImage
)
347 tObj
->Image
[level
] = texImage
;
349 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
350 tObj
->Image
[level
] = texImage
;
352 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
353 tObj
->NegX
[level
] = texImage
;
355 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
356 tObj
->PosY
[level
] = texImage
;
358 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
359 tObj
->NegY
[level
] = texImage
;
361 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
362 tObj
->PosZ
[level
] = texImage
;
364 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
365 tObj
->NegZ
[level
] = texImage
;
367 case GL_TEXTURE_RECTANGLE_NV
:
369 tObj
->Image
[level
] = texImage
;
372 _mesa_problem(NULL
, "bad target in _mesa_set_tex_image()");
380 * Return new gl_texture_image struct with all fields initialized to zero.
382 struct gl_texture_image
*
383 _mesa_alloc_texture_image( void )
385 return CALLOC_STRUCT(gl_texture_image
);
391 _mesa_free_texture_image( struct gl_texture_image
*teximage
)
393 if (teximage
->Data
) {
394 MESA_PBUFFER_FREE( teximage
->Data
);
395 teximage
->Data
= NULL
;
402 * Return GL_TRUE if the target is a proxy target.
405 is_proxy_target(GLenum target
)
407 return (target
== GL_PROXY_TEXTURE_1D
||
408 target
== GL_PROXY_TEXTURE_2D
||
409 target
== GL_PROXY_TEXTURE_3D
||
410 target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
);
415 * Given a texture unit and a texture target, return the corresponding
418 struct gl_texture_object
*
419 _mesa_select_tex_object(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
424 return texUnit
->Current1D
;
425 case GL_PROXY_TEXTURE_1D
:
426 return ctx
->Texture
.Proxy1D
;
428 return texUnit
->Current2D
;
429 case GL_PROXY_TEXTURE_2D
:
430 return ctx
->Texture
.Proxy2D
;
432 return texUnit
->Current3D
;
433 case GL_PROXY_TEXTURE_3D
:
434 return ctx
->Texture
.Proxy3D
;
435 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
436 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
437 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
438 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
439 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
440 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
441 case GL_TEXTURE_CUBE_MAP_ARB
:
442 return ctx
->Extensions
.ARB_texture_cube_map
443 ? texUnit
->CurrentCubeMap
: NULL
;
444 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
445 return ctx
->Extensions
.ARB_texture_cube_map
446 ? ctx
->Texture
.ProxyCubeMap
: NULL
;
447 case GL_TEXTURE_RECTANGLE_NV
:
448 return ctx
->Extensions
.NV_texture_rectangle
449 ? texUnit
->CurrentRect
: NULL
;
450 case GL_PROXY_TEXTURE_RECTANGLE_NV
:
451 return ctx
->Extensions
.NV_texture_rectangle
452 ? ctx
->Texture
.ProxyRect
: NULL
;
454 _mesa_problem(NULL
, "bad target in _mesa_select_tex_object()");
461 * Return the texture image struct which corresponds to target and level
462 * for the given texture unit.
464 struct gl_texture_image
*
465 _mesa_select_tex_image(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
466 GLenum target
, GLint level
)
469 ASSERT(level
< MAX_TEXTURE_LEVELS
);
472 return texUnit
->Current1D
->Image
[level
];
473 case GL_PROXY_TEXTURE_1D
:
474 return ctx
->Texture
.Proxy1D
->Image
[level
];
476 return texUnit
->Current2D
->Image
[level
];
477 case GL_PROXY_TEXTURE_2D
:
478 return ctx
->Texture
.Proxy2D
->Image
[level
];
480 return texUnit
->Current3D
->Image
[level
];
481 case GL_PROXY_TEXTURE_3D
:
482 return ctx
->Texture
.Proxy3D
->Image
[level
];
483 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
484 if (ctx
->Extensions
.ARB_texture_cube_map
)
485 return texUnit
->CurrentCubeMap
->Image
[level
];
488 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
489 if (ctx
->Extensions
.ARB_texture_cube_map
)
490 return texUnit
->CurrentCubeMap
->NegX
[level
];
493 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
494 if (ctx
->Extensions
.ARB_texture_cube_map
)
495 return texUnit
->CurrentCubeMap
->PosY
[level
];
498 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
499 if (ctx
->Extensions
.ARB_texture_cube_map
)
500 return texUnit
->CurrentCubeMap
->NegY
[level
];
503 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
504 if (ctx
->Extensions
.ARB_texture_cube_map
)
505 return texUnit
->CurrentCubeMap
->PosZ
[level
];
508 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
509 if (ctx
->Extensions
.ARB_texture_cube_map
)
510 return texUnit
->CurrentCubeMap
->NegZ
[level
];
513 case GL_PROXY_TEXTURE_CUBE_MAP_ARB
:
514 if (ctx
->Extensions
.ARB_texture_cube_map
)
515 return ctx
->Texture
.ProxyCubeMap
->Image
[level
];
518 case GL_TEXTURE_RECTANGLE_NV
:
519 if (ctx
->Extensions
.NV_texture_rectangle
) {
521 return texUnit
->CurrentRect
->Image
[level
];
526 case GL_PROXY_TEXTURE_RECTANGLE_NV
:
527 if (ctx
->Extensions
.NV_texture_rectangle
) {
529 return ctx
->Texture
.ProxyRect
->Image
[level
];
535 _mesa_problem(ctx
, "bad target in _mesa_select_tex_image()");
542 #if 000 /* not used anymore */
544 * glTexImage[123]D can accept a NULL image pointer. In this case we
545 * create a texture image with unspecified image contents per the OpenGL
549 make_null_texture(GLint width
, GLint height
, GLint depth
, GLenum format
)
551 const GLint components
= _mesa_components_in_format(format
);
552 const GLint numPixels
= width
* height
* depth
;
553 GLubyte
*data
= (GLubyte
*) MALLOC(numPixels
* components
* sizeof(GLubyte
));
557 * Let's see if anyone finds this. If glTexImage2D() is called with
558 * a NULL image pointer then load the texture image with something
559 * interesting instead of leaving it indeterminate.
562 static const char message
[8][32] = {
566 " X X XXXX XXX XXXXX ",
569 " X X XXXXX XXX X X ",
573 GLubyte
*imgPtr
= data
;
575 for (h
= 0; h
< depth
; h
++) {
576 for (i
= 0; i
< height
; i
++) {
577 GLint srcRow
= 7 - (i
% 8);
578 for (j
= 0; j
< width
; j
++) {
579 GLint srcCol
= j
% 32;
580 GLubyte texel
= (message
[srcRow
][srcCol
]=='X') ? 255 : 70;
581 for (k
= 0; k
< components
; k
++) {
597 * Reset the fields of a gl_texture_image struct to zero.
598 * This is called when a proxy texture test fails, we set all the
599 * image members (except DriverData) to zero.
600 * It's also used in glTexImage[123]D as a safeguard to be sure all
601 * required fields get initialized properly by the Driver.TexImage[123]D
605 clear_teximage_fields(struct gl_texture_image
*img
)
622 img
->TexFormat
= &_mesa_null_texformat
;
623 img
->FetchTexel
= NULL
;
624 img
->IsCompressed
= 0;
625 img
->CompressedSize
= 0;
630 * Initialize basic fields of the gl_texture_image struct.
633 _mesa_init_teximage_fields(GLcontext
*ctx
, GLenum target
,
634 struct gl_texture_image
*img
,
635 GLsizei width
, GLsizei height
, GLsizei depth
,
636 GLint border
, GLenum internalFormat
)
639 img
->Format
= _mesa_base_tex_format( ctx
, internalFormat
);
640 ASSERT(img
->Format
> 0);
641 img
->IntFormat
= internalFormat
;
642 img
->Border
= border
;
644 img
->Height
= height
;
646 img
->RowStride
= width
;
647 img
->WidthLog2
= logbase2(width
- 2 * border
);
648 if (height
== 1) /* 1-D texture */
651 img
->HeightLog2
= logbase2(height
- 2 * border
);
652 if (depth
== 1) /* 2-D texture */
655 img
->DepthLog2
= logbase2(depth
- 2 * border
);
656 img
->Width2
= 1 << img
->WidthLog2
;
657 img
->Height2
= 1 << img
->HeightLog2
;
658 img
->Depth2
= 1 << img
->DepthLog2
;
659 img
->MaxLog2
= MAX2(img
->WidthLog2
, img
->HeightLog2
);
660 img
->IsCompressed
= is_compressed_format(ctx
, internalFormat
);
661 /* Compute Width/Height/DepthScale for mipmap lod computation */
662 if (target
== GL_TEXTURE_RECTANGLE_NV
) {
663 /* scale = 1.0 since texture coords directly map to texels */
664 img
->WidthScale
= 1.0;
665 img
->HeightScale
= 1.0;
666 img
->DepthScale
= 1.0;
669 img
->WidthScale
= (GLfloat
) img
->Width
;
670 img
->HeightScale
= (GLfloat
) img
->Height
;
671 img
->DepthScale
= (GLfloat
) img
->Depth
;
678 * Test glTexImage[123]D() parameters for errors.
680 * dimensions - must be 1 or 2 or 3
681 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
684 texture_error_check( GLcontext
*ctx
, GLenum target
,
685 GLint level
, GLint internalFormat
,
686 GLenum format
, GLenum type
,
688 GLint width
, GLint height
,
689 GLint depth
, GLint border
)
693 GLint maxLevels
= 0, maxTextureSize
;
695 if (dimensions
== 1) {
696 if (target
== GL_PROXY_TEXTURE_1D
) {
699 else if (target
== GL_TEXTURE_1D
) {
703 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
706 maxLevels
= ctx
->Const
.MaxTextureLevels
;
708 else if (dimensions
== 2) {
709 if (target
== GL_PROXY_TEXTURE_2D
) {
711 maxLevels
= ctx
->Const
.MaxTextureLevels
;
713 else if (target
== GL_TEXTURE_2D
) {
715 maxLevels
= ctx
->Const
.MaxTextureLevels
;
717 else if (target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
) {
718 if (!ctx
->Extensions
.ARB_texture_cube_map
) {
719 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
723 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
725 else if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
726 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
727 if (!ctx
->Extensions
.ARB_texture_cube_map
) {
728 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
732 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
734 else if (target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) {
735 if (!ctx
->Extensions
.NV_texture_rectangle
) {
736 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
742 else if (target
== GL_TEXTURE_RECTANGLE_NV
) {
743 if (!ctx
->Extensions
.NV_texture_rectangle
) {
744 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
751 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)");
755 else if (dimensions
== 3) {
756 if (target
== GL_PROXY_TEXTURE_3D
) {
759 else if (target
== GL_TEXTURE_3D
) {
763 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
766 maxLevels
= ctx
->Const
.Max3DTextureLevels
;
769 _mesa_problem( ctx
, "bad dims in texture_error_check" );
773 ASSERT(maxLevels
> 0);
774 maxTextureSize
= 1 << (maxLevels
- 1);
777 if (border
!= 0 && border
!= 1) {
779 _mesa_error(ctx
, GL_INVALID_VALUE
,
780 "glTexImage%dD(border=%d)", dimensions
, border
);
784 if ((target
== GL_TEXTURE_RECTANGLE_NV
||
785 target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) && border
!= 0) {
790 if (target
== GL_TEXTURE_RECTANGLE_NV
||
791 target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) {
792 if (width
< 1 || width
> ctx
->Const
.MaxTextureRectSize
) {
794 _mesa_error(ctx
, GL_INVALID_VALUE
,
795 "glTexImage%dD(width=%d)", dimensions
, width
);
800 else if (width
< 2 * border
|| width
> 2 + maxTextureSize
801 || logbase2( width
- 2 * border
) < 0) {
803 _mesa_error(ctx
, GL_INVALID_VALUE
,
804 "glTexImage%dD(width=%d)", dimensions
, width
);
810 if (target
== GL_TEXTURE_RECTANGLE_NV
||
811 target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) {
812 if (height
< 1 || height
> ctx
->Const
.MaxTextureRectSize
) {
814 _mesa_error(ctx
, GL_INVALID_VALUE
,
815 "glTexImage%dD(height=%d)", dimensions
, height
);
820 else if (dimensions
>= 2) {
821 if (height
< 2 * border
|| height
> 2 + maxTextureSize
822 || logbase2( height
- 2 * border
) < 0) {
824 _mesa_error(ctx
, GL_INVALID_VALUE
,
825 "glTexImage%dD(height=%d)", dimensions
, height
);
831 /* For cube map, width must equal height */
832 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
833 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
834 if (width
!= height
) {
836 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
843 if (dimensions
>= 3) {
844 if (depth
< 2 * border
|| depth
> 2 + maxTextureSize
845 || logbase2( depth
- 2 * border
) < 0) {
847 _mesa_error( ctx
, GL_INVALID_VALUE
,
848 "glTexImage3D(depth=%d)", depth
);
855 if (target
== GL_TEXTURE_RECTANGLE_NV
||
856 target
== GL_PROXY_TEXTURE_RECTANGLE_NV
) {
859 _mesa_error(ctx
, GL_INVALID_VALUE
,
860 "glTexImage2D(level=%d)", level
);
865 else if (level
< 0 || level
>= maxLevels
) {
867 _mesa_error(ctx
, GL_INVALID_VALUE
,
868 "glTexImage%dD(level=%d)", dimensions
, level
);
873 /* For cube map, width must equal height */
874 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
875 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
876 if (width
!= height
) {
877 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexImage2D(width != height)");
882 iformat
= _mesa_base_tex_format( ctx
, internalFormat
);
885 _mesa_error(ctx
, GL_INVALID_VALUE
,
886 "glTexImage%dD(internalFormat=0x%x)",
887 dimensions
, internalFormat
);
894 if (!is_compressed_format( ctx
, internalFormat
) &&
895 !_mesa_is_legal_format_and_type( format
, type
)) {
896 /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
897 * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
900 _mesa_error(ctx
, GL_INVALID_OPERATION
,
901 "glTexImage%dD(format or type)", dimensions
);
906 if (format
== GL_YCBCR_MESA
|| iformat
== GL_YCBCR_MESA
) {
907 ASSERT(ctx
->Extensions
.MESA_ycbcr_texture
);
908 if (format
!= GL_YCBCR_MESA
||
909 iformat
!= GL_YCBCR_MESA
||
910 (type
!= GL_UNSIGNED_SHORT_8_8_MESA
&&
911 type
!= GL_UNSIGNED_SHORT_8_8_REV_MESA
)) {
914 "glTexImage%d(format/type/internalFormat YCBCR mismatch",
916 _mesa_error(ctx
, GL_INVALID_ENUM
, message
);
917 return GL_TRUE
; /* error */
921 /* if we get here, the parameters are OK */
928 * Test glTexSubImage[123]D() parameters for errors.
930 * dimensions - must be 1 or 2 or 3
931 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
934 subtexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
935 GLenum target
, GLint level
,
936 GLint xoffset
, GLint yoffset
, GLint zoffset
,
937 GLint width
, GLint height
, GLint depth
,
938 GLenum format
, GLenum type
)
940 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
941 struct gl_texture_image
*destTex
;
943 GLboolean compressed
;
945 if (dimensions
== 1) {
946 if (target
!= GL_TEXTURE_1D
) {
947 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(target)" );
950 maxLevels
= ctx
->Const
.MaxTextureLevels
;
952 else if (dimensions
== 2) {
953 if (ctx
->Extensions
.ARB_texture_cube_map
) {
954 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
955 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
956 target
!= GL_TEXTURE_2D
) {
957 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
961 else if (target
!= GL_TEXTURE_2D
) {
962 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
965 if (target
== GL_PROXY_TEXTURE_2D
&& target
== GL_TEXTURE_2D
)
966 maxLevels
= ctx
->Const
.MaxTextureLevels
;
968 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
970 else if (dimensions
== 3) {
971 if (target
!= GL_TEXTURE_3D
) {
972 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3D(target)" );
975 maxLevels
= ctx
->Const
.Max3DTextureLevels
;
978 _mesa_problem( ctx
, "bad dims in texture_error_check" );
982 ASSERT(maxLevels
> 0);
984 if (level
< 0 || level
>= maxLevels
) {
985 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(level=%d)", level
);
990 _mesa_error(ctx
, GL_INVALID_VALUE
,
991 "glTexSubImage%dD(width=%d)", dimensions
, width
);
994 if (height
< 0 && dimensions
> 1) {
995 _mesa_error(ctx
, GL_INVALID_VALUE
,
996 "glTexSubImage%dD(height=%d)", dimensions
, height
);
999 if (depth
< 0 && dimensions
> 2) {
1000 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage%dD(depth=%d)", dimensions
, depth
);
1004 destTex
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1007 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glTexSubImage2D");
1011 if (xoffset
< -((GLint
)destTex
->Border
)) {
1012 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset)");
1015 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
1016 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage1/2/3D(xoffset+width)");
1019 if (dimensions
> 1) {
1020 if (yoffset
< -((GLint
)destTex
->Border
)) {
1021 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset)");
1024 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
1025 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage2/3D(yoffset+height)");
1029 if (dimensions
> 2) {
1030 if (zoffset
< -((GLint
)destTex
->Border
)) {
1031 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset)");
1034 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+ destTex
->Border
)) {
1035 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTexSubImage3D(zoffset+depth)");
1040 compressed
= is_compressed_format(ctx
, destTex
->IntFormat
);
1042 if (!compressed
&& !_mesa_is_legal_format_and_type(format
, type
)) {
1043 _mesa_error(ctx
, GL_INVALID_ENUM
,
1044 "glTexSubImage%dD(format or type)", dimensions
);
1049 if (xoffset
!= -((GLint
)destTex
->Border
)) {
1050 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1051 "glTexSubImage1/2/3D(xoffset != -border");
1054 if (dimensions
> 1 && yoffset
!= -((GLint
)destTex
->Border
)) {
1055 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1056 "glTexSubImage2/3D(yoffset != -border");
1059 if (dimensions
> 2 && zoffset
!= -((GLint
)destTex
->Border
)) {
1060 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1061 "glTexSubImage3D(zoffset != -border");
1071 * Test glCopyTexImage[12]D() parameters for errors.
1072 * Input: dimensions - must be 1 or 2 or 3
1073 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
1076 copytexture_error_check( GLcontext
*ctx
, GLuint dimensions
,
1077 GLenum target
, GLint level
, GLint internalFormat
,
1078 GLint width
, GLint height
, GLint border
)
1081 GLint maxLevels
= 0, maxTextureSize
;
1083 if (dimensions
== 1) {
1084 if (target
!= GL_TEXTURE_1D
) {
1085 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
1088 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1090 else if (dimensions
== 2) {
1091 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1092 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
1093 if (!ctx
->Extensions
.ARB_texture_cube_map
) {
1094 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1098 else if (target
== GL_TEXTURE_RECTANGLE_NV
) {
1099 if (!ctx
->Extensions
.NV_texture_rectangle
) {
1100 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1104 else if (target
!= GL_TEXTURE_2D
) {
1105 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
1108 if (target
== GL_TEXTURE_2D
)
1109 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1110 else if (target
== GL_TEXTURE_RECTANGLE_NV
)
1113 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
1116 ASSERT(maxLevels
> 0);
1117 maxTextureSize
= 1 << (maxLevels
- 1);
1120 if (border
!= 0 && border
!= 1) {
1121 _mesa_error(ctx
, GL_INVALID_VALUE
,
1122 "glCopyTexImage%dD(border)", dimensions
);
1127 if (width
< 2 * border
|| width
> 2 + maxTextureSize
1128 || logbase2( width
- 2 * border
) < 0) {
1129 _mesa_error(ctx
, GL_INVALID_VALUE
,
1130 "glCopyTexImage%dD(width=%d)", dimensions
, width
);
1135 if (dimensions
>= 2) {
1136 if (height
< 2 * border
|| height
> 2 + maxTextureSize
1137 || logbase2( height
- 2 * border
) < 0) {
1138 _mesa_error(ctx
, GL_INVALID_VALUE
,
1139 "glCopyTexImage%dD(height=%d)", dimensions
, height
);
1144 /* For cube map, width must equal height */
1145 if (target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1146 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) {
1147 if (width
!= height
) {
1148 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(width != height)");
1154 if (level
< 0 || level
>= maxLevels
) {
1155 _mesa_error(ctx
, GL_INVALID_VALUE
,
1156 "glCopyTexImage%dD(level=%d)", dimensions
, level
);
1160 iformat
= _mesa_base_tex_format(ctx
, internalFormat
);
1162 _mesa_error(ctx
, GL_INVALID_VALUE
,
1163 "glCopyTexImage%dD(internalFormat)", dimensions
);
1167 /* if we get here, the parameters are OK */
1173 copytexsubimage_error_check( GLcontext
*ctx
, GLuint dimensions
,
1174 GLenum target
, GLint level
,
1175 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1176 GLsizei width
, GLsizei height
)
1178 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1179 struct gl_texture_image
*teximage
;
1180 GLint maxLevels
= 0;
1181 GLboolean compressed
;
1183 if (dimensions
== 1) {
1184 if (target
!= GL_TEXTURE_1D
) {
1185 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
1188 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1190 else if (dimensions
== 2) {
1191 if (ctx
->Extensions
.ARB_texture_cube_map
) {
1192 if ((target
< GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
||
1193 target
> GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) &&
1194 target
!= GL_TEXTURE_2D
) {
1195 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1199 else if (target
!= GL_TEXTURE_2D
) {
1200 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
1203 if (target
== GL_PROXY_TEXTURE_2D
&& target
== GL_TEXTURE_2D
)
1204 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1206 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
1208 else if (dimensions
== 3) {
1209 if (target
!= GL_TEXTURE_3D
) {
1210 _mesa_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3D(target)" );
1213 maxLevels
= ctx
->Const
.Max3DTextureLevels
;
1216 ASSERT(maxLevels
> 0);
1218 if (level
< 0 || level
>= maxLevels
) {
1219 _mesa_error(ctx
, GL_INVALID_VALUE
,
1220 "glCopyTexSubImage%dD(level=%d)", dimensions
, level
);
1225 _mesa_error(ctx
, GL_INVALID_VALUE
,
1226 "glCopyTexSubImage%dD(width=%d)", dimensions
, width
);
1229 if (dimensions
> 1 && height
< 0) {
1230 _mesa_error(ctx
, GL_INVALID_VALUE
,
1231 "glCopyTexSubImage%dD(height=%d)", dimensions
, height
);
1235 teximage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1237 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1238 "glCopyTexSubImage%dD(undefined texture level: %d)",
1243 if (xoffset
< -((GLint
)teximage
->Border
)) {
1244 _mesa_error(ctx
, GL_INVALID_VALUE
,
1245 "glCopyTexSubImage%dD(xoffset=%d)", dimensions
, xoffset
);
1248 if (xoffset
+ width
> (GLint
) (teximage
->Width
+ teximage
->Border
)) {
1249 _mesa_error(ctx
, GL_INVALID_VALUE
,
1250 "glCopyTexSubImage%dD(xoffset+width)", dimensions
);
1253 if (dimensions
> 1) {
1254 if (yoffset
< -((GLint
)teximage
->Border
)) {
1255 _mesa_error(ctx
, GL_INVALID_VALUE
,
1256 "glCopyTexSubImage%dD(yoffset=%d)", dimensions
, yoffset
);
1259 /* NOTE: we're adding the border here, not subtracting! */
1260 if (yoffset
+ height
> (GLint
) (teximage
->Height
+ teximage
->Border
)) {
1261 _mesa_error(ctx
, GL_INVALID_VALUE
,
1262 "glCopyTexSubImage%dD(yoffset+height)", dimensions
);
1267 if (dimensions
> 2) {
1268 if (zoffset
< -((GLint
)teximage
->Border
)) {
1269 _mesa_error(ctx
, GL_INVALID_VALUE
,
1270 "glCopyTexSubImage%dD(zoffset)", dimensions
);
1273 if (zoffset
> (GLint
) (teximage
->Depth
+ teximage
->Border
)) {
1274 _mesa_error(ctx
, GL_INVALID_VALUE
,
1275 "glCopyTexSubImage%dD(zoffset+depth)", dimensions
);
1280 compressed
= is_compressed_format(ctx
, teximage
->IntFormat
);
1282 if (xoffset
!= -((GLint
)teximage
->Border
)) {
1283 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1284 "glCopyTexSubImage1/2/3D(xoffset != -border");
1287 if (dimensions
> 1 && yoffset
!= -((GLint
)teximage
->Border
)) {
1288 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1289 "glCopyTexSubImage2/3D(yoffset != -border");
1292 if (dimensions
> 2 && zoffset
!= -((GLint
)teximage
->Border
)) {
1293 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1294 "glCopyTexSubImage3D(zoffset != -border");
1299 /* if we get here, the parameters are OK */
1306 _mesa_GetTexImage( GLenum target
, GLint level
, GLenum format
,
1307 GLenum type
, GLvoid
*pixels
)
1309 const struct gl_texture_unit
*texUnit
;
1310 const struct gl_texture_object
*texObj
;
1311 const struct gl_texture_image
*texImage
;
1312 GLint maxLevels
= 0;
1313 GET_CURRENT_CONTEXT(ctx
);
1314 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1316 texUnit
= &(ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
]);
1317 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1318 if (!texObj
|| is_proxy_target(target
)) {
1319 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)");
1323 if (target
== GL_TEXTURE_1D
|| target
== GL_TEXTURE_2D
) {
1324 maxLevels
= ctx
->Const
.MaxTextureLevels
;
1326 else if (target
== GL_TEXTURE_3D
) {
1327 maxLevels
= ctx
->Const
.Max3DTextureLevels
;
1329 else if (target
== GL_TEXTURE_RECTANGLE_NV
) {
1333 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
1336 ASSERT(maxLevels
> 0);
1338 if (level
< 0 || level
>= maxLevels
) {
1339 _mesa_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
1343 if (_mesa_sizeof_packed_type(type
) <= 0) {
1344 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
1348 if (_mesa_components_in_format(format
) <= 0 ||
1349 format
== GL_STENCIL_INDEX
) {
1350 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
1354 if (!ctx
->Extensions
.EXT_paletted_texture
&& is_index_format(format
)) {
1355 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1358 if (!ctx
->Extensions
.SGIX_depth_texture
&& format
== GL_DEPTH_COMPONENT
) {
1359 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1362 if (!ctx
->Extensions
.MESA_ycbcr_texture
&& format
== GL_YCBCR_MESA
) {
1363 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)");
1366 /* XXX what if format/type doesn't match texture format/type? */
1371 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1373 /* invalid mipmap level, not an error */
1377 if (!texImage
->Data
) {
1378 /* no image data, not an error */
1383 const GLint width
= texImage
->Width
;
1384 const GLint height
= texImage
->Height
;
1385 const GLint depth
= texImage
->Depth
;
1387 for (img
= 0; img
< depth
; img
++) {
1388 for (row
= 0; row
< height
; row
++) {
1389 /* compute destination address in client memory */
1390 GLvoid
*dest
= _mesa_image_address( &ctx
->Pack
, pixels
,
1391 width
, height
, format
, type
,
1395 if (format
== GL_COLOR_INDEX
) {
1396 GLuint indexRow
[MAX_WIDTH
];
1398 for (col
= 0; col
< width
; col
++) {
1399 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1400 (GLvoid
*) &indexRow
[col
]);
1402 _mesa_pack_index_span(ctx
, width
, type
, dest
,
1403 indexRow
, &ctx
->Pack
,
1404 0 /* no image transfer */);
1406 else if (format
== GL_DEPTH_COMPONENT
) {
1407 GLfloat depthRow
[MAX_WIDTH
];
1409 for (col
= 0; col
< width
; col
++) {
1410 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1411 (GLvoid
*) &depthRow
[col
]);
1413 _mesa_pack_depth_span(ctx
, width
, dest
, type
,
1414 depthRow
, &ctx
->Pack
);
1416 else if (format
== GL_YCBCR_MESA
) {
1417 /* No pixel transfer */
1418 const GLint rowstride
= texImage
->RowStride
;
1420 (const GLushort
*) texImage
->Data
+ row
* rowstride
,
1421 width
* sizeof(GLushort
));
1422 /* check for byte swapping */
1423 if ((texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_YCBCR
1424 && type
== GL_UNSIGNED_SHORT_8_8_REV_MESA
) ||
1425 (texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_YCBCR_REV
1426 && type
== GL_UNSIGNED_SHORT_8_8_MESA
)) {
1427 if (!ctx
->Pack
.SwapBytes
)
1428 _mesa_swap2((GLushort
*) dest
, width
);
1430 else if (ctx
->Pack
.SwapBytes
) {
1431 _mesa_swap2((GLushort
*) dest
, width
);
1435 /* general case: convert row to RGBA format */
1436 GLchan rgba
[MAX_WIDTH
][4];
1438 for (col
= 0; col
< width
; col
++) {
1439 (*texImage
->FetchTexel
)(texImage
, col
, row
, img
,
1440 (GLvoid
*) rgba
[col
]);
1442 _mesa_pack_rgba_span(ctx
, width
, (const GLchan (*)[4])rgba
,
1443 format
, type
, dest
, &ctx
->Pack
,
1444 0 /* no image transfer */);
1454 * Called from the API. Note that width includes the border.
1457 _mesa_TexImage1D( GLenum target
, GLint level
, GLint internalFormat
,
1458 GLsizei width
, GLint border
, GLenum format
,
1459 GLenum type
, const GLvoid
*pixels
)
1461 GLsizei postConvWidth
= width
;
1462 GET_CURRENT_CONTEXT(ctx
);
1463 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1465 if (is_color_format(internalFormat
)) {
1466 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1469 if (target
== GL_TEXTURE_1D
) {
1470 struct gl_texture_unit
*texUnit
;
1471 struct gl_texture_object
*texObj
;
1472 struct gl_texture_image
*texImage
;
1474 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1475 format
, type
, 1, postConvWidth
, 1, 1, border
)) {
1476 return; /* error was recorded */
1479 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1480 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1481 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1484 texImage
= _mesa_alloc_texture_image();
1485 texObj
->Image
[level
] = texImage
;
1487 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
1491 else if (texImage
->Data
) {
1492 /* free the old texture data */
1493 MESA_PBUFFER_FREE(texImage
->Data
);
1494 texImage
->Data
= NULL
;
1496 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1497 _mesa_init_teximage_fields(ctx
, target
, texImage
,
1498 postConvWidth
, 1, 1,
1499 border
, internalFormat
);
1501 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1502 _mesa_update_state(ctx
);
1504 ASSERT(ctx
->Driver
.TexImage1D
);
1506 #if 0 /* don't make default teximage anymore */
1508 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1509 width
, border
, format
, type
, pixels
,
1510 &ctx
->Unpack
, texObj
, texImage
);
1513 GLubyte
*dummy
= make_null_texture(width
, 1, 1, format
);
1515 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1517 format
, GL_UNSIGNED_BYTE
, dummy
,
1518 &_mesa_native_packing
, texObj
, texImage
);
1523 /* <pixels> may be null! */
1524 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
1525 width
, border
, format
, type
, pixels
,
1526 &ctx
->Unpack
, texObj
, texImage
);
1529 ASSERT(texImage
->TexFormat
);
1530 if (!texImage
->FetchTexel
) {
1531 /* If driver didn't explicitly set this, use the default */
1532 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel1D
;
1534 ASSERT(texImage
->FetchTexel
);
1536 if (texImage
->IsCompressed
) {
1537 ASSERT(texImage
->CompressedSize
> 0);
1541 texObj
->Complete
= GL_FALSE
;
1542 ctx
->NewState
|= _NEW_TEXTURE
;
1544 else if (target
== GL_PROXY_TEXTURE_1D
) {
1545 /* Proxy texture: check for errors and update proxy state */
1546 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1548 postConvWidth
, 1, 1, border
);
1550 struct gl_texture_unit
*texUnit
;
1551 struct gl_texture_image
*texImage
;
1552 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1553 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1554 _mesa_init_teximage_fields(ctx
, target
, texImage
,
1555 postConvWidth
, 1, 1,
1556 border
, internalFormat
);
1557 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1558 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1559 internalFormat
, format
, type
,
1560 postConvWidth
, 1, 1, border
);
1563 /* if error, clear all proxy texture image parameters */
1564 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
1565 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
1570 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1577 _mesa_TexImage2D( GLenum target
, GLint level
, GLint internalFormat
,
1578 GLsizei width
, GLsizei height
, GLint border
,
1579 GLenum format
, GLenum type
,
1580 const GLvoid
*pixels
)
1582 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1583 GET_CURRENT_CONTEXT(ctx
);
1584 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1586 if (is_color_format(internalFormat
)) {
1587 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1591 if (target
== GL_TEXTURE_2D
||
1592 (ctx
->Extensions
.ARB_texture_cube_map
&&
1593 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
1594 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) ||
1595 (ctx
->Extensions
.NV_texture_rectangle
&&
1596 target
== GL_TEXTURE_RECTANGLE_NV
)) {
1597 /* non-proxy target */
1598 struct gl_texture_unit
*texUnit
;
1599 struct gl_texture_object
*texObj
;
1600 struct gl_texture_image
*texImage
;
1602 if (texture_error_check(ctx
, target
, level
, internalFormat
,
1603 format
, type
, 2, postConvWidth
, postConvHeight
,
1605 return; /* error was recorded */
1608 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1609 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1610 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1613 texImage
= _mesa_alloc_texture_image();
1614 _mesa_set_tex_image(texObj
, target
, level
, texImage
);
1616 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
1620 else if (texImage
->Data
) {
1621 /* free the old texture data */
1622 MESA_PBUFFER_FREE(texImage
->Data
);
1623 texImage
->Data
= NULL
;
1625 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1626 _mesa_init_teximage_fields(ctx
, target
, texImage
,
1627 postConvWidth
, postConvHeight
, 1,
1628 border
, internalFormat
);
1630 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1631 _mesa_update_state(ctx
);
1633 ASSERT(ctx
->Driver
.TexImage2D
);
1635 #if 0 /* don't make default teximage anymore */
1637 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1638 width
, height
, border
, format
, type
, pixels
,
1639 &ctx
->Unpack
, texObj
, texImage
);
1642 GLubyte
*dummy
= make_null_texture(width
, height
, 1, format
);
1644 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1645 width
, height
, border
,
1646 format
, GL_UNSIGNED_BYTE
, dummy
,
1647 &_mesa_native_packing
, texObj
, texImage
);
1652 /* <pixels> may be null! */
1653 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
1654 width
, height
, border
, format
, type
, pixels
,
1655 &ctx
->Unpack
, texObj
, texImage
);
1658 ASSERT(texImage
->TexFormat
);
1659 if (!texImage
->FetchTexel
) {
1660 /* If driver didn't explicitly set this, use the default */
1661 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel2D
;
1663 ASSERT(texImage
->FetchTexel
);
1665 if (texImage
->IsCompressed
) {
1666 ASSERT(texImage
->CompressedSize
> 0);
1670 texObj
->Complete
= GL_FALSE
;
1671 ctx
->NewState
|= _NEW_TEXTURE
;
1673 else if (target
== GL_PROXY_TEXTURE_2D
||
1674 (target
== GL_PROXY_TEXTURE_CUBE_MAP_ARB
&&
1675 ctx
->Extensions
.ARB_texture_cube_map
) ||
1676 (target
== GL_PROXY_TEXTURE_RECTANGLE_NV
&&
1677 ctx
->Extensions
.NV_texture_rectangle
)) {
1678 /* Proxy texture: check for errors and update proxy state */
1679 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1681 postConvWidth
, postConvHeight
, 1, border
);
1683 struct gl_texture_unit
*texUnit
;
1684 struct gl_texture_image
*texImage
;
1685 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1686 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1687 _mesa_init_teximage_fields(ctx
, target
, texImage
,
1688 postConvWidth
, postConvHeight
, 1,
1689 border
, internalFormat
);
1690 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1691 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1692 internalFormat
, format
, type
,
1693 postConvWidth
, postConvHeight
, 1, border
);
1696 /* if error, clear all proxy texture image parameters */
1697 const GLint maxLevels
= (target
== GL_PROXY_TEXTURE_2D
) ?
1698 ctx
->Const
.MaxTextureLevels
: ctx
->Const
.MaxCubeTextureLevels
;
1699 if (level
>= 0 && level
< maxLevels
) {
1700 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
1705 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1712 * Called by the API or display list executor.
1713 * Note that width and height include the border.
1716 _mesa_TexImage3D( GLenum target
, GLint level
, GLint internalFormat
,
1717 GLsizei width
, GLsizei height
, GLsizei depth
,
1718 GLint border
, GLenum format
, GLenum type
,
1719 const GLvoid
*pixels
)
1721 GET_CURRENT_CONTEXT(ctx
);
1722 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1724 if (target
== GL_TEXTURE_3D
) {
1725 struct gl_texture_unit
*texUnit
;
1726 struct gl_texture_object
*texObj
;
1727 struct gl_texture_image
*texImage
;
1729 if (texture_error_check(ctx
, target
, level
, (GLint
) internalFormat
,
1730 format
, type
, 3, width
, height
, depth
, border
)) {
1731 return; /* error was recorded */
1734 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1735 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1736 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1739 texImage
= _mesa_alloc_texture_image();
1740 texObj
->Image
[level
] = texImage
;
1742 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
1746 else if (texImage
->Data
) {
1747 MESA_PBUFFER_FREE(texImage
->Data
);
1748 texImage
->Data
= NULL
;
1750 clear_teximage_fields(texImage
); /* not really needed, but helpful */
1751 _mesa_init_teximage_fields(ctx
, target
, texImage
,
1752 width
, height
, depth
,
1753 border
, internalFormat
);
1755 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1756 _mesa_update_state(ctx
);
1758 ASSERT(ctx
->Driver
.TexImage3D
);
1760 #if 0 /* don't make default teximage anymore */
1762 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, (GLint
) internalFormat
,
1763 width
, height
, depth
, border
,
1764 format
, type
, pixels
,
1765 &ctx
->Unpack
, texObj
, texImage
);
1768 GLubyte
*dummy
= make_null_texture(width
, height
, depth
, format
);
1770 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
,
1771 (GLint
) internalFormat
,
1772 width
, height
, depth
, border
,
1773 format
, GL_UNSIGNED_BYTE
, dummy
,
1774 &_mesa_native_packing
, texObj
, texImage
);
1779 /* <pixels> may be null! */
1780 (*ctx
->Driver
.TexImage3D
)(ctx
, target
, level
, internalFormat
,
1781 width
, height
, depth
, border
, format
, type
,
1782 pixels
, &ctx
->Unpack
, texObj
, texImage
);
1785 ASSERT(texImage
->TexFormat
);
1786 if (!texImage
->FetchTexel
) {
1787 /* If driver didn't explicitly set this, use the default */
1788 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel3D
;
1790 ASSERT(texImage
->FetchTexel
);
1792 if (texImage
->IsCompressed
) {
1793 ASSERT(texImage
->CompressedSize
> 0);
1797 texObj
->Complete
= GL_FALSE
;
1798 ctx
->NewState
|= _NEW_TEXTURE
;
1800 else if (target
== GL_PROXY_TEXTURE_3D
) {
1801 /* Proxy texture: check for errors and update proxy state */
1802 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
1803 format
, type
, 3, width
, height
, depth
, border
);
1805 struct gl_texture_unit
*texUnit
;
1806 struct gl_texture_image
*texImage
;
1807 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1808 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1809 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
, 1,
1810 border
, internalFormat
);
1811 ASSERT(ctx
->Driver
.TestProxyTexImage
);
1812 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
1813 internalFormat
, format
, type
,
1814 width
, height
, depth
, border
);
1817 /* if error, clear all proxy texture image parameters */
1818 if (level
>= 0 && level
< ctx
->Const
.Max3DTextureLevels
) {
1819 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
1824 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
1831 _mesa_TexImage3DEXT( GLenum target
, GLint level
, GLenum internalFormat
,
1832 GLsizei width
, GLsizei height
, GLsizei depth
,
1833 GLint border
, GLenum format
, GLenum type
,
1834 const GLvoid
*pixels
)
1836 _mesa_TexImage3D(target
, level
, internalFormat
, width
, height
,
1837 depth
, border
, format
, type
, pixels
);
1843 _mesa_TexSubImage1D( GLenum target
, GLint level
,
1844 GLint xoffset
, GLsizei width
,
1845 GLenum format
, GLenum type
,
1846 const GLvoid
*pixels
)
1848 GLsizei postConvWidth
= width
;
1849 struct gl_texture_unit
*texUnit
;
1850 struct gl_texture_object
*texObj
;
1851 struct gl_texture_image
*texImage
;
1852 GET_CURRENT_CONTEXT(ctx
);
1853 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1855 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1856 _mesa_update_state(ctx
);
1858 /* XXX should test internal format */
1859 if (is_color_format(format
)) {
1860 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
1863 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
1864 postConvWidth
, 1, 1, format
, type
)) {
1865 return; /* error was detected */
1868 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1869 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1870 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1873 if (width
== 0 || !pixels
)
1874 return; /* no-op, not an error */
1876 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1877 xoffset
+= texImage
->Border
;
1879 ASSERT(ctx
->Driver
.TexSubImage1D
);
1880 (*ctx
->Driver
.TexSubImage1D
)(ctx
, target
, level
, xoffset
, width
,
1881 format
, type
, pixels
, &ctx
->Unpack
,
1883 ctx
->NewState
|= _NEW_TEXTURE
;
1888 _mesa_TexSubImage2D( GLenum target
, GLint level
,
1889 GLint xoffset
, GLint yoffset
,
1890 GLsizei width
, GLsizei height
,
1891 GLenum format
, GLenum type
,
1892 const GLvoid
*pixels
)
1894 GLsizei postConvWidth
= width
, postConvHeight
= height
;
1895 struct gl_texture_unit
*texUnit
;
1896 struct gl_texture_object
*texObj
;
1897 struct gl_texture_image
*texImage
;
1898 GET_CURRENT_CONTEXT(ctx
);
1899 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1901 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1902 _mesa_update_state(ctx
);
1904 /* XXX should test internal format */
1905 if (is_color_format(format
)) {
1906 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
1910 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
1911 postConvWidth
, postConvHeight
, 1, format
, type
)) {
1912 return; /* error was detected */
1915 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1916 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1917 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1920 if (width
== 0 || height
== 0 || !pixels
)
1921 return; /* no-op, not an error */
1923 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1924 xoffset
+= texImage
->Border
;
1925 yoffset
+= texImage
->Border
;
1927 ASSERT(ctx
->Driver
.TexSubImage2D
);
1928 (*ctx
->Driver
.TexSubImage2D
)(ctx
, target
, level
, xoffset
, yoffset
,
1929 width
, height
, format
, type
, pixels
,
1930 &ctx
->Unpack
, texObj
, texImage
);
1931 ctx
->NewState
|= _NEW_TEXTURE
;
1937 _mesa_TexSubImage3D( GLenum target
, GLint level
,
1938 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1939 GLsizei width
, GLsizei height
, GLsizei depth
,
1940 GLenum format
, GLenum type
,
1941 const GLvoid
*pixels
)
1943 struct gl_texture_unit
*texUnit
;
1944 struct gl_texture_object
*texObj
;
1945 struct gl_texture_image
*texImage
;
1946 GET_CURRENT_CONTEXT(ctx
);
1947 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1949 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1950 _mesa_update_state(ctx
);
1952 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
1953 width
, height
, depth
, format
, type
)) {
1954 return; /* error was detected */
1957 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1958 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
1959 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
1962 if (width
== 0 || height
== 0 || height
== 0 || !pixels
)
1963 return; /* no-op, not an error */
1965 /* If we have a border, xoffset=-1 is legal. Bias by border width */
1966 xoffset
+= texImage
->Border
;
1967 yoffset
+= texImage
->Border
;
1968 zoffset
+= texImage
->Border
;
1970 ASSERT(ctx
->Driver
.TexSubImage3D
);
1971 (*ctx
->Driver
.TexSubImage3D
)(ctx
, target
, level
,
1972 xoffset
, yoffset
, zoffset
,
1973 width
, height
, depth
,
1974 format
, type
, pixels
,
1975 &ctx
->Unpack
, texObj
, texImage
);
1976 ctx
->NewState
|= _NEW_TEXTURE
;
1982 _mesa_CopyTexImage1D( GLenum target
, GLint level
,
1983 GLenum internalFormat
,
1985 GLsizei width
, GLint border
)
1987 struct gl_texture_unit
*texUnit
;
1988 struct gl_texture_object
*texObj
;
1989 struct gl_texture_image
*texImage
;
1990 GLsizei postConvWidth
= width
;
1991 GET_CURRENT_CONTEXT(ctx
);
1992 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1994 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
1995 _mesa_update_state(ctx
);
1997 if (is_color_format(internalFormat
)) {
1998 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
2001 if (copytexture_error_check(ctx
, 1, target
, level
, internalFormat
,
2002 postConvWidth
, 1, border
))
2005 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2006 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2007 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2009 texImage
= _mesa_alloc_texture_image();
2010 _mesa_set_tex_image(texObj
, target
, level
, texImage
);
2012 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D");
2016 else if (texImage
->Data
) {
2017 /* free the old texture data */
2018 MESA_PBUFFER_FREE(texImage
->Data
);
2019 texImage
->Data
= NULL
;
2022 clear_teximage_fields(texImage
); /* not really needed, but helpful */
2023 _mesa_init_teximage_fields(ctx
, target
, texImage
, postConvWidth
, 1, 1,
2024 border
, internalFormat
);
2027 ASSERT(ctx
->Driver
.CopyTexImage1D
);
2028 (*ctx
->Driver
.CopyTexImage1D
)(ctx
, target
, level
, internalFormat
,
2029 x
, y
, width
, border
);
2031 ASSERT(texImage
->TexFormat
);
2032 if (!texImage
->FetchTexel
) {
2033 /* If driver didn't explicitly set this, use the default */
2034 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel1D
;
2036 ASSERT(texImage
->FetchTexel
);
2039 texObj
->Complete
= GL_FALSE
;
2040 ctx
->NewState
|= _NEW_TEXTURE
;
2046 _mesa_CopyTexImage2D( GLenum target
, GLint level
, GLenum internalFormat
,
2047 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
2050 struct gl_texture_unit
*texUnit
;
2051 struct gl_texture_object
*texObj
;
2052 struct gl_texture_image
*texImage
;
2053 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2054 GET_CURRENT_CONTEXT(ctx
);
2055 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2057 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2058 _mesa_update_state(ctx
);
2060 if (is_color_format(internalFormat
)) {
2061 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
,
2065 if (copytexture_error_check(ctx
, 2, target
, level
, internalFormat
,
2066 postConvWidth
, postConvHeight
, border
))
2069 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2070 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2071 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2073 texImage
= _mesa_alloc_texture_image();
2074 _mesa_set_tex_image(texObj
, target
, level
, texImage
);
2076 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D");
2080 else if (texImage
->Data
) {
2081 /* free the old texture data */
2082 MESA_PBUFFER_FREE(texImage
->Data
);
2083 texImage
->Data
= NULL
;
2086 clear_teximage_fields(texImage
); /* not really needed, but helpful */
2087 _mesa_init_teximage_fields(ctx
, target
, texImage
,
2088 postConvWidth
, postConvHeight
, 1,
2089 border
, internalFormat
);
2091 ASSERT(ctx
->Driver
.CopyTexImage2D
);
2092 (*ctx
->Driver
.CopyTexImage2D
)(ctx
, target
, level
, internalFormat
,
2093 x
, y
, width
, height
, border
);
2095 ASSERT(texImage
->TexFormat
);
2096 if (!texImage
->FetchTexel
) {
2097 /* If driver didn't explicitly set this, use the default */
2098 texImage
->FetchTexel
= texImage
->TexFormat
->FetchTexel2D
;
2100 ASSERT(texImage
->FetchTexel
);
2103 texObj
->Complete
= GL_FALSE
;
2104 ctx
->NewState
|= _NEW_TEXTURE
;
2110 _mesa_CopyTexSubImage1D( GLenum target
, GLint level
,
2111 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
2113 struct gl_texture_unit
*texUnit
;
2114 struct gl_texture_object
*texObj
;
2115 struct gl_texture_image
*texImage
;
2116 GLsizei postConvWidth
= width
;
2117 GET_CURRENT_CONTEXT(ctx
);
2118 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2120 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2121 _mesa_update_state(ctx
);
2123 /* XXX should test internal format */
2124 _mesa_adjust_image_for_convolution(ctx
, 1, &postConvWidth
, NULL
);
2126 if (copytexsubimage_error_check(ctx
, 1, target
, level
,
2127 xoffset
, 0, 0, postConvWidth
, 1))
2130 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2131 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2132 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2134 /* If we have a border, xoffset=-1 is legal. Bias by border width */
2135 xoffset
+= texImage
->Border
;
2137 ASSERT(ctx
->Driver
.CopyTexSubImage1D
);
2138 (*ctx
->Driver
.CopyTexSubImage1D
)(ctx
, target
, level
, xoffset
, x
, y
, width
);
2139 ctx
->NewState
|= _NEW_TEXTURE
;
2145 _mesa_CopyTexSubImage2D( GLenum target
, GLint level
,
2146 GLint xoffset
, GLint yoffset
,
2147 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2149 struct gl_texture_unit
*texUnit
;
2150 struct gl_texture_object
*texObj
;
2151 struct gl_texture_image
*texImage
;
2152 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2153 GET_CURRENT_CONTEXT(ctx
);
2154 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2156 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2157 _mesa_update_state(ctx
);
2159 /* XXX should test internal format */
2160 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
2162 if (copytexsubimage_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2163 postConvWidth
, postConvHeight
))
2166 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2167 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2168 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2170 /* If we have a border, xoffset=-1 is legal. Bias by border width */
2171 xoffset
+= texImage
->Border
;
2172 yoffset
+= texImage
->Border
;
2174 ASSERT(ctx
->Driver
.CopyTexSubImage2D
);
2175 (*ctx
->Driver
.CopyTexSubImage2D
)(ctx
, target
, level
,
2176 xoffset
, yoffset
, x
, y
, width
, height
);
2177 ctx
->NewState
|= _NEW_TEXTURE
;
2183 _mesa_CopyTexSubImage3D( GLenum target
, GLint level
,
2184 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2185 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2187 struct gl_texture_unit
*texUnit
;
2188 struct gl_texture_object
*texObj
;
2189 struct gl_texture_image
*texImage
;
2190 GLsizei postConvWidth
= width
, postConvHeight
= height
;
2191 GET_CURRENT_CONTEXT(ctx
);
2192 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2194 if (ctx
->NewState
& _IMAGE_NEW_TRANSFER_STATE
)
2195 _mesa_update_state(ctx
);
2197 /* XXX should test internal format */
2198 _mesa_adjust_image_for_convolution(ctx
, 2, &postConvWidth
, &postConvHeight
);
2200 if (copytexsubimage_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
,
2201 zoffset
, postConvWidth
, postConvHeight
))
2204 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2205 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2206 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2208 /* If we have a border, xoffset=-1 is legal. Bias by border width */
2209 xoffset
+= texImage
->Border
;
2210 yoffset
+= texImage
->Border
;
2211 zoffset
+= texImage
->Border
;
2213 ASSERT(ctx
->Driver
.CopyTexSubImage3D
);
2214 (*ctx
->Driver
.CopyTexSubImage3D
)(ctx
, target
, level
,
2215 xoffset
, yoffset
, zoffset
,
2216 x
, y
, width
, height
);
2217 ctx
->NewState
|= _NEW_TEXTURE
;
2223 _mesa_CompressedTexImage1DARB(GLenum target
, GLint level
,
2224 GLenum internalFormat
, GLsizei width
,
2225 GLint border
, GLsizei imageSize
,
2228 GET_CURRENT_CONTEXT(ctx
);
2229 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2231 switch (internalFormat
) {
2232 case GL_COMPRESSED_ALPHA_ARB
:
2233 case GL_COMPRESSED_LUMINANCE_ARB
:
2234 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2235 case GL_COMPRESSED_INTENSITY_ARB
:
2236 case GL_COMPRESSED_RGB_ARB
:
2237 case GL_COMPRESSED_RGBA_ARB
:
2238 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB");
2241 /* silence compiler warning */
2245 if (target
== GL_TEXTURE_1D
) {
2246 struct gl_texture_unit
*texUnit
;
2247 struct gl_texture_object
*texObj
;
2248 struct gl_texture_image
*texImage
;
2250 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2251 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
)) {
2252 return; /* error in texture image was detected */
2255 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2256 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2257 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2260 texImage
= _mesa_alloc_texture_image();
2261 texObj
->Image
[level
] = texImage
;
2263 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage1DARB");
2267 else if (texImage
->Data
) {
2268 MESA_PBUFFER_FREE(texImage
->Data
);
2269 texImage
->Data
= NULL
;
2272 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, 1, 1,
2273 border
, internalFormat
);
2275 if (ctx
->Extensions
.ARB_texture_compression
) {
2276 ASSERT(ctx
->Driver
.CompressedTexImage1D
);
2277 (*ctx
->Driver
.CompressedTexImage1D
)(ctx
, target
, level
,
2278 internalFormat
, width
, border
,
2281 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2285 texObj
->Complete
= GL_FALSE
;
2286 ctx
->NewState
|= _NEW_TEXTURE
;
2288 else if (target
== GL_PROXY_TEXTURE_1D
) {
2289 /* Proxy texture: check for errors and update proxy state */
2290 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2291 GL_NONE
, GL_NONE
, 1, width
, 1, 1, border
);
2293 struct gl_texture_unit
*texUnit
;
2294 struct gl_texture_image
*texImage
;
2295 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2296 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2297 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, 1, 1,
2298 border
, internalFormat
);
2299 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2300 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2301 internalFormat
, GL_NONE
, GL_NONE
,
2302 width
, 1, 1, border
);
2305 /* if error, clear all proxy texture image parameters */
2306 if (level
>= 0 && level
< ctx
->Const
.MaxTextureLevels
) {
2307 clear_teximage_fields(ctx
->Texture
.Proxy1D
->Image
[level
]);
2312 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage1DARB(target)");
2319 _mesa_CompressedTexImage2DARB(GLenum target
, GLint level
,
2320 GLenum internalFormat
, GLsizei width
,
2321 GLsizei height
, GLint border
, GLsizei imageSize
,
2324 GET_CURRENT_CONTEXT(ctx
);
2325 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2327 switch (internalFormat
) {
2328 case GL_COMPRESSED_ALPHA_ARB
:
2329 case GL_COMPRESSED_LUMINANCE_ARB
:
2330 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2331 case GL_COMPRESSED_INTENSITY_ARB
:
2332 case GL_COMPRESSED_RGB_ARB
:
2333 case GL_COMPRESSED_RGBA_ARB
:
2334 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB");
2337 /* silence compiler warning */
2341 if (target
== GL_TEXTURE_2D
||
2342 (ctx
->Extensions
.ARB_texture_cube_map
&&
2343 target
>= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
&&
2344 target
<= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
) ||
2345 (ctx
->Extensions
.NV_texture_rectangle
&&
2346 target
== GL_TEXTURE_RECTANGLE_NV
)) {
2347 struct gl_texture_unit
*texUnit
;
2348 struct gl_texture_object
*texObj
;
2349 struct gl_texture_image
*texImage
;
2351 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2352 GL_NONE
, GL_NONE
, 2, width
, height
, 1, border
)) {
2353 return; /* error in texture image was detected */
2356 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2357 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2358 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2361 texImage
= _mesa_alloc_texture_image();
2362 texObj
->Image
[level
] = texImage
;
2364 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
2368 else if (texImage
->Data
) {
2369 MESA_PBUFFER_FREE(texImage
->Data
);
2370 texImage
->Data
= NULL
;
2373 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
, 1,
2374 border
, internalFormat
);
2376 if (ctx
->Extensions
.ARB_texture_compression
) {
2377 ASSERT(ctx
->Driver
.CompressedTexImage2D
);
2378 (*ctx
->Driver
.CompressedTexImage2D
)(ctx
, target
, level
,
2379 internalFormat
, width
, height
,
2380 border
, imageSize
, data
,
2382 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2386 texObj
->Complete
= GL_FALSE
;
2387 ctx
->NewState
|= _NEW_TEXTURE
;
2389 else if (target
== GL_PROXY_TEXTURE_2D
) {
2390 /* Proxy texture: check for errors and update proxy state */
2391 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2392 GL_NONE
, GL_NONE
, 2, width
, height
, 1, border
);
2394 struct gl_texture_unit
*texUnit
;
2395 struct gl_texture_image
*texImage
;
2396 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2397 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2398 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
, 1,
2399 border
, internalFormat
);
2400 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2401 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2402 internalFormat
, GL_NONE
, GL_NONE
,
2403 width
, height
, 1, border
);
2406 /* if error, clear all proxy texture image parameters */
2407 const GLint maxLevels
= (target
== GL_PROXY_TEXTURE_2D
) ?
2408 ctx
->Const
.MaxTextureLevels
: ctx
->Const
.MaxCubeTextureLevels
;
2409 if (level
>= 0 && level
< maxLevels
) {
2410 clear_teximage_fields(ctx
->Texture
.Proxy2D
->Image
[level
]);
2415 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage2DARB(target)");
2422 _mesa_CompressedTexImage3DARB(GLenum target
, GLint level
,
2423 GLenum internalFormat
, GLsizei width
,
2424 GLsizei height
, GLsizei depth
, GLint border
,
2425 GLsizei imageSize
, const GLvoid
*data
)
2427 GET_CURRENT_CONTEXT(ctx
);
2428 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2430 switch (internalFormat
) {
2431 case GL_COMPRESSED_ALPHA_ARB
:
2432 case GL_COMPRESSED_LUMINANCE_ARB
:
2433 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB
:
2434 case GL_COMPRESSED_INTENSITY_ARB
:
2435 case GL_COMPRESSED_RGB_ARB
:
2436 case GL_COMPRESSED_RGBA_ARB
:
2437 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB");
2440 /* silence compiler warning */
2444 if (target
== GL_TEXTURE_3D
) {
2445 struct gl_texture_unit
*texUnit
;
2446 struct gl_texture_object
*texObj
;
2447 struct gl_texture_image
*texImage
;
2449 if (texture_error_check(ctx
, target
, level
, internalFormat
,
2450 GL_NONE
, GL_NONE
, 3, width
, height
, depth
, border
)) {
2451 return; /* error in texture image was detected */
2454 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2455 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2456 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2459 texImage
= _mesa_alloc_texture_image();
2460 texObj
->Image
[level
] = texImage
;
2462 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage3DARB");
2466 else if (texImage
->Data
) {
2467 MESA_PBUFFER_FREE(texImage
->Data
);
2468 texImage
->Data
= NULL
;
2471 _mesa_init_teximage_fields(ctx
, target
, texImage
, width
, height
, depth
,
2472 border
, internalFormat
);
2474 if (ctx
->Extensions
.ARB_texture_compression
) {
2475 ASSERT(ctx
->Driver
.CompressedTexImage3D
);
2476 (*ctx
->Driver
.CompressedTexImage3D
)(ctx
, target
, level
,
2478 width
, height
, depth
,
2479 border
, imageSize
, data
,
2481 ASSERT(texImage
->CompressedSize
> 0); /* sanity */
2485 texObj
->Complete
= GL_FALSE
;
2486 ctx
->NewState
|= _NEW_TEXTURE
;
2488 else if (target
== GL_PROXY_TEXTURE_3D
) {
2489 /* Proxy texture: check for errors and update proxy state */
2490 GLenum error
= texture_error_check(ctx
, target
, level
, internalFormat
,
2491 GL_NONE
, GL_NONE
, 3, width
, height
, depth
, border
);
2493 struct gl_texture_unit
*texUnit
;
2494 struct gl_texture_image
*texImage
;
2495 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2496 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2497 _mesa_init_teximage_fields(ctx
, target
, texImage
,
2498 width
, height
, depth
,
2499 border
, internalFormat
);
2500 ASSERT(ctx
->Driver
.TestProxyTexImage
);
2501 error
= !(*ctx
->Driver
.TestProxyTexImage
)(ctx
, target
, level
,
2502 internalFormat
, GL_NONE
, GL_NONE
,
2503 width
, height
, depth
, border
);
2506 /* if error, clear all proxy texture image parameters */
2507 if (level
>= 0 && level
< ctx
->Const
.Max3DTextureLevels
) {
2508 clear_teximage_fields(ctx
->Texture
.Proxy3D
->Image
[level
]);
2513 _mesa_error(ctx
, GL_INVALID_ENUM
, "glCompressedTexImage3DARB(target)");
2520 _mesa_CompressedTexSubImage1DARB(GLenum target
, GLint level
, GLint xoffset
,
2521 GLsizei width
, GLenum format
,
2522 GLsizei imageSize
, const GLvoid
*data
)
2524 struct gl_texture_unit
*texUnit
;
2525 struct gl_texture_object
*texObj
;
2526 struct gl_texture_image
*texImage
;
2527 GET_CURRENT_CONTEXT(ctx
);
2528 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2530 if (subtexture_error_check(ctx
, 1, target
, level
, xoffset
, 0, 0,
2531 width
, 1, 1, format
, GL_NONE
)) {
2532 return; /* error was detected */
2535 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2536 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2537 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2540 if (width
== 0 || !data
)
2541 return; /* no-op, not an error */
2543 if (ctx
->Driver
.CompressedTexSubImage1D
) {
2544 (*ctx
->Driver
.CompressedTexSubImage1D
)(ctx
, target
, level
,
2546 format
, imageSize
, data
,
2549 ctx
->NewState
|= _NEW_TEXTURE
;
2554 _mesa_CompressedTexSubImage2DARB(GLenum target
, GLint level
, GLint xoffset
,
2555 GLint yoffset
, GLsizei width
, GLsizei height
,
2556 GLenum format
, GLsizei imageSize
,
2559 struct gl_texture_unit
*texUnit
;
2560 struct gl_texture_object
*texObj
;
2561 struct gl_texture_image
*texImage
;
2562 GET_CURRENT_CONTEXT(ctx
);
2563 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2565 if (subtexture_error_check(ctx
, 2, target
, level
, xoffset
, yoffset
, 0,
2566 width
, height
, 1, format
, GL_NONE
)) {
2567 return; /* error was detected */
2570 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2571 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2572 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2575 if (width
== 0 || height
== 0 || !data
)
2576 return; /* no-op, not an error */
2578 if (ctx
->Driver
.CompressedTexSubImage2D
) {
2579 (*ctx
->Driver
.CompressedTexSubImage2D
)(ctx
, target
, level
,
2580 xoffset
, yoffset
, width
, height
,
2581 format
, imageSize
, data
,
2584 ctx
->NewState
|= _NEW_TEXTURE
;
2589 _mesa_CompressedTexSubImage3DARB(GLenum target
, GLint level
, GLint xoffset
,
2590 GLint yoffset
, GLint zoffset
, GLsizei width
,
2591 GLsizei height
, GLsizei depth
, GLenum format
,
2592 GLsizei imageSize
, const GLvoid
*data
)
2594 struct gl_texture_unit
*texUnit
;
2595 struct gl_texture_object
*texObj
;
2596 struct gl_texture_image
*texImage
;
2597 GET_CURRENT_CONTEXT(ctx
);
2598 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2600 if (subtexture_error_check(ctx
, 3, target
, level
, xoffset
, yoffset
, zoffset
,
2601 width
, height
, depth
, format
, GL_NONE
)) {
2602 return; /* error was detected */
2605 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2606 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2607 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2610 if (width
== 0 || height
== 0 || depth
== 0 || !data
)
2611 return; /* no-op, not an error */
2613 if (ctx
->Driver
.CompressedTexSubImage3D
) {
2614 (*ctx
->Driver
.CompressedTexSubImage3D
)(ctx
, target
, level
,
2615 xoffset
, yoffset
, zoffset
,
2616 width
, height
, depth
,
2617 format
, imageSize
, data
,
2620 ctx
->NewState
|= _NEW_TEXTURE
;
2625 _mesa_GetCompressedTexImageARB(GLenum target
, GLint level
, GLvoid
*img
)
2627 const struct gl_texture_unit
*texUnit
;
2628 const struct gl_texture_object
*texObj
;
2629 struct gl_texture_image
*texImage
;
2631 GET_CURRENT_CONTEXT(ctx
);
2632 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
2634 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2635 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
2637 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB");
2641 if (target
== GL_TEXTURE_1D
|| target
== GL_TEXTURE_2D
) {
2642 maxLevels
= ctx
->Const
.MaxTextureLevels
;
2644 else if (target
== GL_TEXTURE_3D
) {
2645 maxLevels
= ctx
->Const
.Max3DTextureLevels
;
2648 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
2651 ASSERT(maxLevels
> 0);
2653 if (level
< 0 || level
>= maxLevels
) {
2654 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
2658 if (is_proxy_target(target
)) {
2659 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetCompressedTexImageARB(target)");
2663 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
2665 /* probably invalid mipmap level */
2666 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetCompressedTexImageARB(level)");
2670 if (!texImage
->IsCompressed
) {
2671 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetCompressedTexImageARB");
2678 if (ctx
->Extensions
.ARB_texture_compression
) {
2679 ASSERT(ctx
->Driver
.GetCompressedTexImage
);
2680 (*ctx
->Driver
.GetCompressedTexImage
)(ctx
, target
, level
, img
, texObj
,