X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fteximage.c;h=a5e0db736ed7c82729225dde4de223244731d1a4;hb=19e4222f937c9bb95d3a899dd788afb930eecaa4;hp=1bc52d220ab2eaa67e6dfb12b4c4caee736a0cad;hpb=6ef27b88e6f767cd476676b33cb7c4ea6922234e;p=mesa.git diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 1bc52d220ab..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"), @@ -32,7 +32,9 @@ #include "glheader.h" #include "bufferobj.h" #include "context.h" +#if FEATURE_convolve #include "convolve.h" +#endif #include "fbobject.h" #include "framebuffer.h" #include "image.h" @@ -239,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 */ @@ -387,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: @@ -490,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; } @@ -524,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: @@ -595,8 +598,12 @@ is_compressed_format(GLcontext *ctx, GLenum internalFormat) } -static GLuint -texture_face(GLenum target) +/** + * For cube map faces, return a face index in [0,5]. + * For other targets return 0; + */ +GLuint +_mesa_tex_target_to_face(GLenum target) { if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) @@ -625,6 +632,7 @@ _mesa_set_tex_image(struct gl_texture_object *tObj, { ASSERT(tObj); ASSERT(texImage); + /* XXX simplify this with _mesa_tex_target_to_face() */ switch (target) { case GL_TEXTURE_1D: case GL_TEXTURE_2D: @@ -828,6 +836,7 @@ _mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_object *texObj, if (level < 0 || level >= MAX_TEXTURE_LEVELS) return NULL; + /* XXX simplify this with _mesa_tex_target_to_face() */ switch (target) { case GL_TEXTURE_1D: case GL_PROXY_TEXTURE_1D: @@ -1208,25 +1217,36 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target, img->Width = width; img->Height = height; img->Depth = depth; + img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */ - img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ - img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */ img->WidthLog2 = logbase2(img->Width2); - if (height == 1) /* 1-D texture */ + + if (height == 1) { /* 1-D texture */ + img->Height2 = 1; img->HeightLog2 = 0; - else + } + else { + img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ img->HeightLog2 = logbase2(img->Height2); - if (depth == 1) /* 2-D texture */ + } + + if (depth == 1) { /* 2-D texture */ + img->Depth2 = 1; img->DepthLog2 = 0; - else + } + else { + img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */ img->DepthLog2 = logbase2(img->Depth2); + } + img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2); + 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; @@ -1297,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; @@ -1307,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; @@ -1320,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; @@ -1344,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; @@ -1357,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; @@ -1371,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; @@ -1569,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)) || @@ -2033,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); @@ -2067,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)" ); @@ -2114,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, @@ -2136,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)", @@ -2143,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); @@ -2167,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, @@ -2289,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; } @@ -2306,9 +2328,6 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, return; } - if (!pixels) - return; - _mesa_lock_texture(ctx, texObj); { texImage = _mesa_select_tex_image(ctx, texObj, target, level); @@ -2322,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; @@ -2415,16 +2434,18 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (is_color_format(internalFormat)) { +#if FEATURE_convolve + if (_mesa_is_color_format(internalFormat)) { _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); } +#endif if (target == GL_TEXTURE_1D) { /* non-proxy target */ struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; - const GLuint face = texture_face(target); + const GLuint face = _mesa_tex_target_to_face(target); if (texture_error_check(ctx, target, level, internalFormat, format, type, 1, postConvWidth, 1, 1, border)) { @@ -2510,10 +2531,12 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (is_color_format(internalFormat)) { +#if FEATURE_convolve + if (_mesa_is_color_format(internalFormat)) { _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); } +#endif if (target == GL_TEXTURE_2D || (ctx->Extensions.ARB_texture_cube_map && @@ -2527,7 +2550,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; - const GLuint face = texture_face(target); + const GLuint face = _mesa_tex_target_to_face(target); if (texture_error_check(ctx, target, level, internalFormat, format, type, 2, postConvWidth, postConvHeight, @@ -2629,7 +2652,7 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; - const GLuint face = texture_face(target); + const GLuint face = _mesa_tex_target_to_face(target); if (texture_error_check(ctx, target, level, (GLint) internalFormat, format, type, 3, width, height, depth, border)) { @@ -2691,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); } @@ -2732,10 +2755,12 @@ _mesa_TexSubImage1D( GLenum target, GLint level, if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) _mesa_update_state(ctx); +#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 if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0, postConvWidth, 1, 1, format, type)) { @@ -2790,11 +2815,13 @@ _mesa_TexSubImage2D( GLenum target, GLint level, if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) _mesa_update_state(ctx); +#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); } +#endif if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0, postConvWidth, postConvHeight, 1, format, type)) { @@ -2897,16 +2924,18 @@ _mesa_CopyTexImage1D( GLenum target, GLint level, struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLsizei postConvWidth = width; - const GLuint face = texture_face(target); + const GLuint face = _mesa_tex_target_to_face(target); GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) _mesa_update_state(ctx); - if (is_color_format(internalFormat)) { +#if FEATURE_convolve + if (_mesa_is_color_format(internalFormat)) { _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); } +#endif if (copytexture_error_check(ctx, 1, target, level, internalFormat, postConvWidth, 1, border)) @@ -2960,17 +2989,19 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLsizei postConvWidth = width, postConvHeight = height; - const GLuint face = texture_face(target); + const GLuint face = _mesa_tex_target_to_face(target); GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) _mesa_update_state(ctx); - if (is_color_format(internalFormat)) { +#if FEATURE_convolve + 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)) @@ -3024,17 +3055,16 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level, struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLsizei postConvWidth = width; + GLint yoffset = 0; + GLsizei height = 1; + GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) _mesa_update_state(ctx); - /* XXX should test internal format */ - _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); - - 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]; @@ -3044,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)) @@ -3053,8 +3089,13 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level, /* If we have a border, xoffset=-1 is legal. Bias by border width */ xoffset += texImage->Border; - ASSERT(ctx->Driver.CopyTexSubImage1D); - (*ctx->Driver.CopyTexSubImage1D)(ctx, target, level, xoffset, x, y, width); + if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, + &width, &height)) { + ASSERT(ctx->Driver.CopyTexSubImage1D); + ctx->Driver.CopyTexSubImage1D(ctx, target, level, + xoffset, x, y, width); + } + ctx->NewState |= _NEW_TEXTURE; } out: @@ -3078,11 +3119,7 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level, if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) _mesa_update_state(ctx); - /* XXX should test internal format */ - _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); - - 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]; @@ -3092,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; @@ -3099,10 +3143,14 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level, /* If we have a border, xoffset=-1 is legal. Bias by border width */ xoffset += texImage->Border; yoffset += texImage->Border; - - ASSERT(ctx->Driver.CopyTexSubImage2D); - (*ctx->Driver.CopyTexSubImage2D)(ctx, target, level, + + if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, + &width, &height)) { + ASSERT(ctx->Driver.CopyTexSubImage2D); + ctx->Driver.CopyTexSubImage2D(ctx, target, level, xoffset, yoffset, x, y, width, height); + } + ctx->NewState |= _NEW_TEXTURE; } out: @@ -3126,11 +3174,7 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) _mesa_update_state(ctx); - /* XXX should test internal format */ - _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); - - 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]; @@ -3140,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)) @@ -3150,10 +3201,14 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, yoffset += texImage->Border; zoffset += texImage->Border; - ASSERT(ctx->Driver.CopyTexSubImage3D); - (*ctx->Driver.CopyTexSubImage3D)(ctx, target, level, + if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, + &width, &height)) { + ASSERT(ctx->Driver.CopyTexSubImage3D); + ctx->Driver.CopyTexSubImage3D(ctx, target, level, xoffset, yoffset, zoffset, x, y, width, height); + } + ctx->NewState |= _NEW_TEXTURE; } out: @@ -3229,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;