diff options
Diffstat (limited to 'src/mesa/main/teximage.c')
-rw-r--r-- | src/mesa/main/teximage.c | 190 |
1 files changed, 98 insertions, 92 deletions
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 36557f19fd4..a5e0db736ed 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -1,8 +1,8 @@ /* - * Mesa 3-D graphics library + * mesa 3-D graphics library * Version: 7.1 * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -241,13 +241,12 @@ _mesa_base_tex_format( GLcontext *ctx, GLint internalFormat ) } } - if (ctx->Extensions.SGIX_depth_texture || - ctx->Extensions.ARB_depth_texture) { + if (ctx->Extensions.ARB_depth_texture) { switch (internalFormat) { case GL_DEPTH_COMPONENT: - case GL_DEPTH_COMPONENT16_SGIX: - case GL_DEPTH_COMPONENT24_SGIX: - case GL_DEPTH_COMPONENT32_SGIX: + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: return GL_DEPTH_COMPONENT; default: ; /* fallthrough */ @@ -389,9 +388,10 @@ _mesa_base_tex_format( GLcontext *ctx, GLint internalFormat ) * index, depth, stencil, etc). * \param format the image format value (may by an internal texture format) * \return GL_TRUE if its a color/RGBA format, GL_FALSE otherwise. + * XXX maybe move this func to image.c */ -static GLboolean -is_color_format(GLenum format) +GLboolean +_mesa_is_color_format(GLenum format) { switch (format) { case GL_RED: @@ -492,6 +492,7 @@ is_color_format(GLenum format) #endif /* FEATURE_EXT_texture_sRGB */ return GL_TRUE; case GL_YCBCR_MESA: /* not considered to be RGB */ + /* fall-through */ default: return GL_FALSE; } @@ -526,9 +527,9 @@ static GLboolean is_depth_format(GLenum format) { switch (format) { - case GL_DEPTH_COMPONENT16_ARB: - case GL_DEPTH_COMPONENT24_ARB: - case GL_DEPTH_COMPONENT32_ARB: + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: case GL_DEPTH_COMPONENT: return GL_TRUE; default: @@ -1243,9 +1244,9 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target, img->IsCompressed = GL_FALSE; img->CompressedSize = 0; - if ((width == 1 || _mesa_bitcount(img->Width2) == 1) && - (height == 1 || _mesa_bitcount(img->Height2) == 1) && - (depth == 1 || _mesa_bitcount(img->Depth2) == 1)) + if ((width == 1 || _mesa_is_pow_two(img->Width2)) && + (height == 1 || _mesa_is_pow_two(img->Height2)) && + (depth == 1 || _mesa_is_pow_two(img->Depth2))) img->_IsPowerOfTwo = GL_TRUE; else img->_IsPowerOfTwo = GL_FALSE; @@ -1316,7 +1317,7 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level, maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); if (width < 2 * border || width > 2 + maxSize || (!ctx->Extensions.ARB_texture_non_power_of_two && - width >0 && _mesa_bitcount(width - 2 * border) != 1) || + width >0 && !_mesa_is_pow_two(width - 2 * border)) || level >= ctx->Const.MaxTextureLevels) { /* bad width or level */ return GL_FALSE; @@ -1326,10 +1327,10 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level, maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); if (width < 2 * border || width > 2 + maxSize || (!ctx->Extensions.ARB_texture_non_power_of_two && - width > 0 && _mesa_bitcount(width - 2 * border) != 1) || + width > 0 && !_mesa_is_pow_two(width - 2 * border)) || height < 2 * border || height > 2 + maxSize || (!ctx->Extensions.ARB_texture_non_power_of_two && - height > 0 && _mesa_bitcount(height - 2 * border) != 1) || + height > 0 && !_mesa_is_pow_two(height - 2 * border)) || level >= ctx->Const.MaxTextureLevels) { /* bad width or height or level */ return GL_FALSE; @@ -1339,13 +1340,13 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level, maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1); if (width < 2 * border || width > 2 + maxSize || (!ctx->Extensions.ARB_texture_non_power_of_two && - width > 0 && _mesa_bitcount(width - 2 * border) != 1) || + width > 0 && !_mesa_is_pow_two(width - 2 * border)) || height < 2 * border || height > 2 + maxSize || (!ctx->Extensions.ARB_texture_non_power_of_two && - height > 0 && _mesa_bitcount(height - 2 * border) != 1) || + height > 0 && !_mesa_is_pow_two(height - 2 * border)) || depth < 2 * border || depth > 2 + maxSize || (!ctx->Extensions.ARB_texture_non_power_of_two && - depth > 0 && _mesa_bitcount(depth - 2 * border) != 1) || + depth > 0 && !_mesa_is_pow_two(depth - 2 * border)) || level >= ctx->Const.Max3DTextureLevels) { /* bad width or height or depth or level */ return GL_FALSE; @@ -1363,10 +1364,10 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level, maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1); if (width < 2 * border || width > 2 + maxSize || (!ctx->Extensions.ARB_texture_non_power_of_two && - width > 0 && _mesa_bitcount(width - 2 * border) != 1) || + width > 0 && !_mesa_is_pow_two(width - 2 * border)) || height < 2 * border || height > 2 + maxSize || (!ctx->Extensions.ARB_texture_non_power_of_two && - height > 0 && _mesa_bitcount(height - 2 * border) != 1) || + height > 0 && !_mesa_is_pow_two(height - 2 * border)) || level >= ctx->Const.MaxCubeTextureLevels) { /* bad width or height */ return GL_FALSE; @@ -1376,7 +1377,7 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level, maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); if (width < 2 * border || width > 2 + maxSize || (!ctx->Extensions.ARB_texture_non_power_of_two && - width > 0 && _mesa_bitcount(width - 2 * border) != 1) || + width > 0 && !_mesa_is_pow_two(width - 2 * border)) || level >= ctx->Const.MaxTextureLevels) { /* bad width or level */ return GL_FALSE; @@ -1390,10 +1391,10 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level, maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); if (width < 2 * border || width > 2 + maxSize || (!ctx->Extensions.ARB_texture_non_power_of_two && - width > 0 && _mesa_bitcount(width - 2 * border) != 1) || + width > 0 && !_mesa_is_pow_two(width - 2 * border)) || height < 2 * border || height > 2 + maxSize || (!ctx->Extensions.ARB_texture_non_power_of_two && - height > 0 && _mesa_bitcount(height - 2 * border) != 1) || + height > 0 && !_mesa_is_pow_two(height - 2 * border)) || level >= ctx->Const.MaxTextureLevels) { /* bad width or height or level */ return GL_FALSE; @@ -1588,9 +1589,9 @@ texture_error_check( GLcontext *ctx, GLenum target, } /* make sure internal format and format basically agree */ - colorFormat = is_color_format(format); + colorFormat = _mesa_is_color_format(format); indexFormat = is_index_format(format); - if ((is_color_format(internalFormat) && !colorFormat && !indexFormat) || + if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) || (is_index_format(internalFormat) && !indexFormat) || (is_depth_format(internalFormat) != is_depth_format(format)) || (is_ycbcr_format(internalFormat) != is_ycbcr_format(format)) || @@ -2017,7 +2018,7 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions, } if (is_compressed_format(ctx, internalFormat)) { - if (target != GL_TEXTURE_2D) { + if (!target_can_be_compressed(ctx, target)) { _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%d(target)", dimensions); return GL_TRUE; @@ -2052,30 +2053,20 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions, /** * Test glCopyTexSubImage[12]D() parameters for errors. + * Note that this is the first part of error checking. + * See also copytexsubimage_error_check2() below for the second part. * * \param ctx GL context. * \param dimensions texture image dimensions (must be 1, 2 or 3). * \param target texture target given by the user. * \param level image level given by the user. - * \param xoffset sub-image x offset given by the user. - * \param yoffset sub-image y offset given by the user. - * \param zoffset sub-image z offset given by the user. - * \param width image width given by the user. - * \param height image height given by the user. * * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. - * - * Verifies each of the parameters against the constants specified in - * __GLcontextRec::Const and the supported extensions, and according to the - * OpenGL specification. */ static GLboolean -copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions, - GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height) +copytexsubimage_error_check1( GLcontext *ctx, GLuint dimensions, + GLenum target, GLint level) { - /* Check target */ /* Check that the source buffer is complete */ if (ctx->ReadBuffer->Name) { _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); @@ -2086,6 +2077,7 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions, } } + /* Check target */ if (dimensions == 1) { if (target != GL_TEXTURE_1D) { _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" ); @@ -2133,21 +2125,18 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions, return GL_TRUE; } - /* Check size */ - if (width < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glCopyTexSubImage%dD(width=%d)", dimensions, width); - return GL_TRUE; - } - if (dimensions > 1 && height < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glCopyTexSubImage%dD(height=%d)", dimensions, height); - return GL_TRUE; - } - return GL_FALSE; } + +/** + * Second part of error checking for glCopyTexSubImage[12]D(). + * \param xoffset sub-image x offset given by the user. + * \param yoffset sub-image y offset given by the user. + * \param zoffset sub-image z offset given by the user. + * \param width image width given by the user. + * \param height image height given by the user. + */ static GLboolean copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions, GLenum target, GLint level, @@ -2155,6 +2144,7 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions, GLsizei width, GLsizei height, const struct gl_texture_image *teximage ) { + /* check that dest tex image exists */ if (!teximage) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage%dD(undefined texture level: %d)", @@ -2162,6 +2152,19 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions, return GL_TRUE; } + /* Check size */ + if (width < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyTexSubImage%dD(width=%d)", dimensions, width); + return GL_TRUE; + } + if (dimensions > 1 && height < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyTexSubImage%dD(height=%d)", dimensions, height); + return GL_TRUE; + } + + /* check x/y offsets */ if (xoffset < -((GLint)teximage->Border)) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset); @@ -2186,6 +2189,7 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions, } } + /* check z offset */ if (dimensions > 2) { if (zoffset < -((GLint)teximage->Border)) { _mesa_error(ctx, GL_INVALID_VALUE, @@ -2200,7 +2204,7 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions, } if (teximage->IsCompressed) { - if (target != GL_TEXTURE_2D) { + if (!target_can_be_compressed(ctx, target)) { _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexSubImage%d(target)", dimensions); return GL_TRUE; @@ -2308,8 +2312,7 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, return; } - if (!ctx->Extensions.SGIX_depth_texture && - !ctx->Extensions.ARB_depth_texture && is_depth_format(format)) { + if (!ctx->Extensions.ARB_depth_texture && is_depth_format(format)) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)"); return; } @@ -2338,8 +2341,8 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, * texture's format. Note that a color index texture can be converted * to RGBA so that combo is allowed. */ - if (is_color_format(format) - && !is_color_format(texImage->TexFormat->BaseFormat) + if (_mesa_is_color_format(format) + && !_mesa_is_color_format(texImage->TexFormat->BaseFormat) && !is_index_format(texImage->TexFormat->BaseFormat)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); goto out; @@ -2432,7 +2435,7 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); #if FEATURE_convolve - if (is_color_format(internalFormat)) { + if (_mesa_is_color_format(internalFormat)) { _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); } #endif @@ -2529,7 +2532,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); #if FEATURE_convolve - if (is_color_format(internalFormat)) { + if (_mesa_is_color_format(internalFormat)) { _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); } @@ -2711,8 +2714,8 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, } else { /* no error, set the tex image parameters */ - _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, - border, internalFormat); + _mesa_init_teximage_fields(ctx, target, texImage, width, height, + depth, border, internalFormat); texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, internalFormat, format, type); } @@ -2754,7 +2757,7 @@ _mesa_TexSubImage1D( GLenum target, GLint level, #if FEATURE_convolve /* XXX should test internal format */ - if (is_color_format(format)) { + if (_mesa_is_color_format(format)) { _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); } #endif @@ -2814,7 +2817,7 @@ _mesa_TexSubImage2D( GLenum target, GLint level, #if FEATURE_convolve /* XXX should test internal format */ - if (is_color_format(format)) { + if (_mesa_is_color_format(format)) { _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); } @@ -2929,7 +2932,7 @@ _mesa_CopyTexImage1D( GLenum target, GLint level, _mesa_update_state(ctx); #if FEATURE_convolve - if (is_color_format(internalFormat)) { + if (_mesa_is_color_format(internalFormat)) { _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); } #endif @@ -2994,11 +2997,12 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, _mesa_update_state(ctx); #if FEATURE_convolve - if (is_color_format(internalFormat)) { + if (_mesa_is_color_format(internalFormat)) { _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); } #endif + if (copytexture_error_check(ctx, 2, target, level, internalFormat, postConvWidth, postConvHeight, border)) return; @@ -3060,13 +3064,7 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level, if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) _mesa_update_state(ctx); -#if FEATURE_convolve - /* XXX should test internal format */ - _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); -#endif - - if (copytexsubimage_error_check(ctx, 1, target, level, - xoffset, 0, 0, postConvWidth, 1)) + if (copytexsubimage_error_check1(ctx, 1, target, level)) return; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; @@ -3076,6 +3074,12 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level, { texImage = _mesa_select_tex_image(ctx, texObj, target, level); +#if FEATURE_convolve + if (texImage && _mesa_is_color_format(texImage->InternalFormat)) { + _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); + } +#endif + if (copytexsubimage_error_check2(ctx, 1, target, level, xoffset, 0, 0, postConvWidth, 1, texImage)) @@ -3115,13 +3119,7 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level, if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) _mesa_update_state(ctx); -#if FEATURE_convolve - /* XXX should test internal format */ - _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); -#endif - - if (copytexsubimage_error_check(ctx, 2, target, level, xoffset, yoffset, 0, - postConvWidth, postConvHeight)) + if (copytexsubimage_error_check1(ctx, 2, target, level)) return; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; @@ -3131,6 +3129,13 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level, { texImage = _mesa_select_tex_image(ctx, texObj, target, level); +#if FEATURE_convolve + if (texImage && _mesa_is_color_format(texImage->InternalFormat)) { + _mesa_adjust_image_for_convolution(ctx, 2, + &postConvWidth, &postConvHeight); + } +#endif + if (copytexsubimage_error_check2(ctx, 2, target, level, xoffset, yoffset, 0, postConvWidth, postConvHeight, texImage)) goto out; @@ -3169,13 +3174,7 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) _mesa_update_state(ctx); -#if FEATURE_convolve - /* XXX should test internal format */ - _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); -#endif - - if (copytexsubimage_error_check(ctx, 3, target, level, xoffset, yoffset, - zoffset, postConvWidth, postConvHeight)) + if (copytexsubimage_error_check1(ctx, 3, target, level)) return; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; @@ -3185,6 +3184,13 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, { texImage = _mesa_select_tex_image(ctx, texObj, target, level); +#if FEATURE_convolve + if (texImage && _mesa_is_color_format(texImage->InternalFormat)) { + _mesa_adjust_image_for_convolution(ctx, 2, + &postConvWidth, &postConvHeight); + } +#endif + if (copytexsubimage_error_check2(ctx, 3, target, level, xoffset, yoffset, zoffset, postConvWidth, postConvHeight, texImage)) @@ -3278,16 +3284,16 @@ compressed_texture_error_check(GLcontext *ctx, GLint dimensions, * XXX We should probably use the proxy texture error check function here. */ if (width < 1 || width > maxTextureSize || - (!ctx->Extensions.ARB_texture_non_power_of_two && _mesa_bitcount(width) != 1)) + (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(width))) return GL_INVALID_VALUE; if ((height < 1 || height > maxTextureSize || - (!ctx->Extensions.ARB_texture_non_power_of_two && _mesa_bitcount(height) != 1)) + (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(height))) && dimensions > 1) return GL_INVALID_VALUE; if ((depth < 1 || depth > maxTextureSize || - (!ctx->Extensions.ARB_texture_non_power_of_two && _mesa_bitcount(depth) != 1)) + (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(depth))) && dimensions > 2) return GL_INVALID_VALUE; |