diff options
Diffstat (limited to 'src/mesa/main/teximage.c')
-rw-r--r-- | src/mesa/main/teximage.c | 234 |
1 files changed, 187 insertions, 47 deletions
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 342bab3aac9..2ad0df9d6ba 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -1,4 +1,4 @@ -/* $Id: teximage.c,v 1.108 2002/04/23 16:44:46 brianp Exp $ */ +/* $Id: teximage.c,v 1.109 2002/06/15 03:03:09 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -359,6 +359,10 @@ _mesa_set_tex_image(struct gl_texture_object *tObj, case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: tObj->NegZ[level] = texImage; return; + case GL_TEXTURE_RECTANGLE_NV: + ASSERT(level == 0); + tObj->Image[level] = texImage; + return; default: _mesa_problem(NULL, "bad target in _mesa_set_tex_image()"); return; @@ -435,6 +439,12 @@ _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit, case GL_PROXY_TEXTURE_CUBE_MAP_ARB: return ctx->Extensions.ARB_texture_cube_map ? ctx->Texture.ProxyCubeMap : NULL; + case GL_TEXTURE_RECTANGLE_NV: + return ctx->Extensions.NV_texture_rectangle + ? texUnit->CurrentRect : NULL; + case GL_PROXY_TEXTURE_RECTANGLE_NV: + return ctx->Extensions.NV_texture_rectangle + ? ctx->Texture.ProxyRect : NULL; default: _mesa_problem(NULL, "bad target in _mesa_select_tex_object()"); return NULL; @@ -500,6 +510,22 @@ _mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, return ctx->Texture.ProxyCubeMap->Image[level]; else return NULL; + case GL_TEXTURE_RECTANGLE_NV: + if (ctx->Extensions.NV_texture_rectangle) { + ASSERT(level == 0); + return texUnit->CurrentRect->Image[level]; + } + else { + return NULL; + } + case GL_PROXY_TEXTURE_RECTANGLE_NV: + if (ctx->Extensions.NV_texture_rectangle) { + ASSERT(level == 0); + return ctx->Texture.ProxyRect->Image[level]; + } + else { + return NULL; + } default: _mesa_problem(ctx, "bad target in _mesa_select_tex_image()"); return NULL; @@ -598,7 +624,7 @@ clear_teximage_fields(struct gl_texture_image *img) * Initialize basic fields of the gl_texture_image struct. */ void -_mesa_init_teximage_fields(GLcontext *ctx, +_mesa_init_teximage_fields(GLcontext *ctx, GLenum target, struct gl_texture_image *img, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum internalFormat) @@ -625,6 +651,18 @@ _mesa_init_teximage_fields(GLcontext *ctx, img->Depth2 = 1 << img->DepthLog2; img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2); img->IsCompressed = is_compressed_format(ctx, internalFormat); + /* Compute Width/Height/DepthScale for mipmap lod computation */ + if (target == GL_TEXTURE_RECTANGLE_NV) { + /* scale = 1.0 since texture coords directly map to texels */ + img->WidthScale = 1.0; + img->HeightScale = 1.0; + img->DepthScale = 1.0; + } + else { + img->WidthScale = (GLfloat) img->Width; + img->HeightScale = (GLfloat) img->Height; + img->DepthScale = (GLfloat) img->Depth; + } } @@ -648,31 +686,73 @@ texture_error_check( GLcontext *ctx, GLenum target, GLint maxLevels = 0, maxTextureSize; if (dimensions == 1) { - isProxy = (GLboolean) (target == GL_PROXY_TEXTURE_1D); - if (target != GL_TEXTURE_1D && !isProxy) { + if (target == GL_PROXY_TEXTURE_1D) { + isProxy = GL_TRUE; + } + else if (target == GL_TEXTURE_1D) { + isProxy = GL_FALSE; + } + else { _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" ); return GL_TRUE; } maxLevels = ctx->Const.MaxTextureLevels; } else if (dimensions == 2) { - isProxy = (GLboolean) (target == GL_PROXY_TEXTURE_2D || - target == GL_PROXY_TEXTURE_CUBE_MAP_ARB); - if (target != GL_TEXTURE_2D && !isProxy && - !(ctx->Extensions.ARB_texture_cube_map && - target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && - target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) { - _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" ); - return GL_TRUE; - } - if (target == GL_PROXY_TEXTURE_2D || target == GL_TEXTURE_2D) + if (target == GL_PROXY_TEXTURE_2D) { + isProxy = GL_TRUE; maxLevels = ctx->Const.MaxTextureLevels; - else + } + else if (target == GL_TEXTURE_2D) { + isProxy = GL_FALSE; + maxLevels = ctx->Const.MaxTextureLevels; + } + else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) { + if (!ctx->Extensions.ARB_texture_cube_map) { + _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); + return GL_TRUE; + } + isProxy = GL_TRUE; maxLevels = ctx->Const.MaxCubeTextureLevels; + } + else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && + target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { + if (!ctx->Extensions.ARB_texture_cube_map) { + _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); + return GL_TRUE; + } + isProxy = GL_FALSE; + maxLevels = ctx->Const.MaxCubeTextureLevels; + } + else if (target == GL_PROXY_TEXTURE_RECTANGLE_NV) { + if (!ctx->Extensions.NV_texture_rectangle) { + _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); + return GL_TRUE; + } + isProxy = GL_TRUE; + maxLevels = 1; + } + else if (target == GL_TEXTURE_RECTANGLE_NV) { + if (!ctx->Extensions.NV_texture_rectangle) { + _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); + return GL_TRUE; + } + isProxy = GL_FALSE; + maxLevels = 1; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); + return GL_TRUE; + } } else if (dimensions == 3) { - isProxy = (GLboolean) (target == GL_PROXY_TEXTURE_3D); - if (target != GL_TEXTURE_3D && !isProxy) { + if (target == GL_PROXY_TEXTURE_3D) { + isProxy = GL_TRUE; + } + else if (target == GL_TEXTURE_3D) { + isProxy = GL_FALSE; + } + else { _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" ); return GL_TRUE; } @@ -695,9 +775,24 @@ texture_error_check( GLcontext *ctx, GLenum target, } return GL_TRUE; } + if ((target == GL_TEXTURE_RECTANGLE_NV || + target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0) { + return GL_TRUE; + } /* Width */ - if (width < 2 * border || width > 2 + maxTextureSize + if (target == GL_TEXTURE_RECTANGLE_NV || + target == GL_PROXY_TEXTURE_RECTANGLE_NV) { + if (width < 1 || width > ctx->Const.MaxTextureRectSize) { + if (!isProxy) { + char message[100]; + sprintf(message, "glTexImage%dD(width=%d)", dimensions, width); + _mesa_error(ctx, GL_INVALID_VALUE, message); + } + return GL_TRUE; + } + } + else if (width < 2 * border || width > 2 + maxTextureSize || logbase2( width - 2 * border ) < 0) { if (!isProxy) { char message[100]; @@ -708,7 +803,18 @@ texture_error_check( GLcontext *ctx, GLenum target, } /* Height */ - if (dimensions >= 2) { + if (target == GL_TEXTURE_RECTANGLE_NV || + target == GL_PROXY_TEXTURE_RECTANGLE_NV) { + if (height < 1 || height > ctx->Const.MaxTextureRectSize) { + if (!isProxy) { + char message[100]; + sprintf(message, "glTexImage%dD(height=%d)", dimensions, height); + _mesa_error(ctx, GL_INVALID_VALUE, message); + } + return GL_TRUE; + } + } + else if (dimensions >= 2) { if (height < 2 * border || height > 2 + maxTextureSize || logbase2( height - 2 * border ) < 0) { if (!isProxy) { @@ -745,7 +851,18 @@ texture_error_check( GLcontext *ctx, GLenum target, } /* Level */ - if (level < 0 || level >= maxLevels) { + if (target == GL_TEXTURE_RECTANGLE_NV || + target == GL_PROXY_TEXTURE_RECTANGLE_NV) { + if (level != 0) { + if (!isProxy) { + char message[100]; + sprintf(message, "glTexImage2D(level=%d)", level); + _mesa_error(ctx, GL_INVALID_VALUE, message); + } + return GL_TRUE; + } + } + else if (level < 0 || level >= maxLevels) { if (!isProxy) { char message[100]; sprintf(message, "glTexImage%dD(level=%d)", dimensions, level); @@ -966,10 +1083,15 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions, maxLevels = ctx->Const.MaxTextureLevels; } else if (dimensions == 2) { - if (ctx->Extensions.ARB_texture_cube_map) { - if ((target < GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || - target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) && - target != GL_TEXTURE_2D) { + if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && + target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { + if (!ctx->Extensions.ARB_texture_cube_map) { + _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); + return GL_TRUE; + } + } + else if (target == GL_TEXTURE_RECTANGLE_NV) { + if (!ctx->Extensions.NV_texture_rectangle) { _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); return GL_TRUE; } @@ -978,8 +1100,10 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions, _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); return GL_TRUE; } - if (target == GL_PROXY_TEXTURE_2D && target == GL_TEXTURE_2D) + if (target == GL_TEXTURE_2D) maxLevels = ctx->Const.MaxTextureLevels; + else if (target == GL_TEXTURE_RECTANGLE_NV) + maxLevels = 1; else maxLevels = ctx->Const.MaxCubeTextureLevels; } @@ -1211,6 +1335,9 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, else if (target == GL_TEXTURE_3D) { maxLevels = ctx->Const.Max3DTextureLevels; } + else if (target == GL_TEXTURE_RECTANGLE_NV) { + maxLevels = 1; + } else { maxLevels = ctx->Const.MaxCubeTextureLevels; } @@ -1354,7 +1481,8 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, texImage->Data = NULL; } clear_teximage_fields(texImage); /* not really needed, but helpful */ - _mesa_init_teximage_fields(ctx, texImage, postConvWidth, 1, 1, + _mesa_init_teximage_fields(ctx, target, texImage, + postConvWidth, 1, 1, border, internalFormat); if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) @@ -1410,7 +1538,8 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, struct gl_texture_image *texImage; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - _mesa_init_teximage_fields(ctx, texImage, postConvWidth, 1, 1, + _mesa_init_teximage_fields(ctx, target, texImage, + postConvWidth, 1, 1, border, internalFormat); ASSERT(ctx->Driver.TestProxyTexImage); error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, @@ -1449,7 +1578,9 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, if (target == GL_TEXTURE_2D || (ctx->Extensions.ARB_texture_cube_map && target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && - target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) { + target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) || + (ctx->Extensions.NV_texture_rectangle && + target == GL_TEXTURE_RECTANGLE_NV)) { /* non-proxy target */ struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; @@ -1479,8 +1610,9 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, texImage->Data = NULL; } clear_teximage_fields(texImage); /* not really needed, but helpful */ - _mesa_init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight, - 1, border, internalFormat); + _mesa_init_teximage_fields(ctx, target, texImage, + postConvWidth, postConvHeight, 1, + border, internalFormat); if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) _mesa_update_state(ctx); @@ -1527,7 +1659,9 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, } else if (target == GL_PROXY_TEXTURE_2D || (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB && - ctx->Extensions.ARB_texture_cube_map)) { + ctx->Extensions.ARB_texture_cube_map) || + (target == GL_PROXY_TEXTURE_RECTANGLE_NV && + ctx->Extensions.NV_texture_rectangle)) { /* Proxy texture: check for errors and update proxy state */ GLenum error = texture_error_check(ctx, target, level, internalFormat, format, type, 2, @@ -1537,8 +1671,9 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, struct gl_texture_image *texImage; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - _mesa_init_teximage_fields(ctx, texImage, postConvWidth, - postConvHeight, 1, border, internalFormat); + _mesa_init_teximage_fields(ctx, target, texImage, + postConvWidth, postConvHeight, 1, + border, internalFormat); ASSERT(ctx->Driver.TestProxyTexImage); error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, internalFormat, format, type, @@ -1600,8 +1735,9 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, texImage->Data = NULL; } clear_teximage_fields(texImage); /* not really needed, but helpful */ - _mesa_init_teximage_fields(ctx, texImage, width, height, depth, border, - internalFormat); + _mesa_init_teximage_fields(ctx, target, texImage, + width, height, depth, + border, internalFormat); if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) _mesa_update_state(ctx); @@ -1657,7 +1793,7 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, struct gl_texture_image *texImage; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - _mesa_init_teximage_fields(ctx, texImage, width, height, 1, + _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, border, internalFormat); ASSERT(ctx->Driver.TestProxyTexImage); error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, @@ -1871,7 +2007,7 @@ _mesa_CopyTexImage1D( GLenum target, GLint level, } clear_teximage_fields(texImage); /* not really needed, but helpful */ - _mesa_init_teximage_fields(ctx, texImage, postConvWidth, 1, 1, + _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1, border, internalFormat); @@ -1935,7 +2071,8 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, } clear_teximage_fields(texImage); /* not really needed, but helpful */ - _mesa_init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight, 1, + _mesa_init_teximage_fields(ctx, target, texImage, + postConvWidth, postConvHeight, 1, border, internalFormat); ASSERT(ctx->Driver.CopyTexImage2D); @@ -2119,7 +2256,7 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level, texImage->Data = NULL; } - _mesa_init_teximage_fields(ctx, texImage, width, 1, 1, + _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, border, internalFormat); if (ctx->Extensions.ARB_texture_compression) { @@ -2144,7 +2281,7 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level, struct gl_texture_image *texImage; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - _mesa_init_teximage_fields(ctx, texImage, width, 1, 1, + _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, border, internalFormat); ASSERT(ctx->Driver.TestProxyTexImage); error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, @@ -2191,7 +2328,9 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, if (target == GL_TEXTURE_2D || (ctx->Extensions.ARB_texture_cube_map && target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && - target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) { + target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) || + (ctx->Extensions.NV_texture_rectangle && + target == GL_TEXTURE_RECTANGLE_NV)) { struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; struct gl_texture_image *texImage; @@ -2218,8 +2357,8 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, texImage->Data = NULL; } - _mesa_init_teximage_fields(ctx, texImage, width, height, 1, border, - internalFormat); + _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, + border, internalFormat); if (ctx->Extensions.ARB_texture_compression) { ASSERT(ctx->Driver.CompressedTexImage2D); @@ -2243,7 +2382,7 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, struct gl_texture_image *texImage; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - _mesa_init_teximage_fields(ctx, texImage, width, height, 1, + _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, border, internalFormat); ASSERT(ctx->Driver.TestProxyTexImage); error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, @@ -2316,8 +2455,8 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, texImage->Data = NULL; } - _mesa_init_teximage_fields(ctx, texImage, width, height, depth, border, - internalFormat); + _mesa_init_teximage_fields(ctx, target, texImage, width, height, depth, + border, internalFormat); if (ctx->Extensions.ARB_texture_compression) { ASSERT(ctx->Driver.CompressedTexImage3D); @@ -2342,7 +2481,8 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, struct gl_texture_image *texImage; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - _mesa_init_teximage_fields(ctx, texImage, width, height, depth, + _mesa_init_teximage_fields(ctx, target, texImage, + width, height, depth, border, internalFormat); ASSERT(ctx->Driver.TestProxyTexImage); error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, |