summaryrefslogtreecommitdiffstats
path: root/src/mesa/main/teximage.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main/teximage.c')
-rw-r--r--src/mesa/main/teximage.c234
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,