summaryrefslogtreecommitdiffstats
path: root/src/mesa/main/teximage.c
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2003-04-04 17:17:50 +0000
committerBrian Paul <[email protected]>2003-04-04 17:17:50 +0000
commit738318bb75dea8dac4465f53850987f6062a732d (patch)
tree870a4e1bb830bd65e3cb829c1eb1ee4d97cbeecb /src/mesa/main/teximage.c
parentb0e90cc839c6b7fcd3bd76759862eb3bc423e50a (diff)
Rework gl[Copy]Tex[Sub]Image() error checking so that all level, width, height
and depth checks are done via ctx->Driver.TestProxyTexImage(). This allows more flexiblity, like supporting larger, non-cubic 3D textures.
Diffstat (limited to 'src/mesa/main/teximage.c')
-rw-r--r--src/mesa/main/teximage.c558
1 files changed, 270 insertions, 288 deletions
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 11247b50028..1c10aaea016 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -785,7 +785,7 @@ make_null_texture(GLint width, GLint height, GLint depth, GLenum format)
-/*
+/**
* Reset the fields of a gl_texture_image struct to zero.
* This is called when a proxy texture test fails, we set all the
* image members (except DriverData) to zero.
@@ -871,12 +871,103 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
}
+/**
+ * This is the fallback for Driver.TestProxyTexImage(). Test the texture
+ * level, width, height and depth against the ctx->Const limits for textures.
+ *
+ * A hardware driver might override this function if, for example, the
+ * max 3D texture size is 512x512x64 (i.e. not a cube).
+ *
+ * \param target one of GL_PROXY_TEXTURE_1D, GL_PROXY_TEXTURE_2D,
+ * GL_PROXY_TEXTURE_3D, GL_PROXY_TEXTURE_RECTANGLE_NV,
+ * GL_PROXY_TEXTURE_CUBE_MAP_ARB.
+ * \param level as passed to glTexImage
+ * \param internalFormat as passed to glTexImage
+ * \param format as passed to glTexImage
+ * \param type as passed to glTexImage
+ * \param width as passed to glTexImage
+ * \param height as passed to glTexImage
+ * \param depth as passed to glTexImage
+ * \param border as passed to glTexImage
+ * \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable.
+ */
+GLboolean
+_mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat, GLenum format, GLenum type,
+ GLint width, GLint height, GLint depth, GLint border)
+{
+ GLint maxSize;
-/*
+ (void) internalFormat;
+ (void) format;
+ (void) type;
+
+ switch (target) {
+ case GL_PROXY_TEXTURE_1D:
+ maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
+ if (width < 2 * border || width > 2 + maxSize ||
+ _mesa_bitcount(width - 2 * border) != 1 ||
+ level >= ctx->Const.MaxTextureLevels) {
+ /* bad width or level */
+ return GL_FALSE;
+ }
+ return GL_TRUE;
+ case GL_PROXY_TEXTURE_2D:
+ maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
+ if (width < 2 * border || width > 2 + maxSize ||
+ _mesa_bitcount(width - 2 * border) != 1 ||
+ height < 2 * border || height > 2 + maxSize ||
+ _mesa_bitcount(height - 2 * border) != 1 ||
+ level >= ctx->Const.MaxTextureLevels) {
+ /* bad width or height or level */
+ return GL_FALSE;
+ }
+ return GL_TRUE;
+ case GL_PROXY_TEXTURE_3D:
+ maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
+ if (width < 2 * border || width > 2 + maxSize ||
+ _mesa_bitcount(width - 2 * border) != 1 ||
+ height < 2 * border || height > 2 + maxSize ||
+ _mesa_bitcount(height - 2 * border) != 1 ||
+ depth < 2 * border || depth > 2 + maxSize ||
+ _mesa_bitcount(depth - 2 * border) != 1 ||
+ level >= ctx->Const.Max3DTextureLevels) {
+ /* bad width or height or depth or level */
+ return GL_FALSE;
+ }
+ return GL_TRUE;
+ case GL_PROXY_TEXTURE_RECTANGLE_NV:
+ if (width < 1 || width > ctx->Const.MaxTextureRectSize ||
+ height < 1 || height > ctx->Const.MaxTextureRectSize ||
+ level != 0) {
+ /* bad width or height or level */
+ return GL_FALSE;
+ }
+ return GL_TRUE;
+ case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
+ maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1);
+ if (width < 2 * border || width > 2 + maxSize ||
+ _mesa_bitcount(width - 2 * border) != 1 ||
+ height < 2 * border || height > 2 + maxSize ||
+ _mesa_bitcount(height - 2 * border) != 1 ||
+ level >= ctx->Const.MaxCubeTextureLevels) {
+ /* bad width or height */
+ return GL_FALSE;
+ }
+ return GL_TRUE;
+ default:
+ _mesa_problem(ctx, "Invalid target in _mesa_test_proxy_teximage");
+ return GL_FALSE;
+ }
+}
+
+
+/**
* Test glTexImage[123]D() parameters for errors.
- * Input:
- * dimensions - must be 1 or 2 or 3
- * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
+ * This function calls the ctx->Driver.TestProxyTexImage() function to
+ * check the level and size.
+ * \param dimensions must be 1 or 2 or 3
+ * \return GL_TRUE if an error was detected or GL_FALSE if no errors
*/
static GLboolean
texture_error_check( GLcontext *ctx, GLenum target,
@@ -886,63 +977,74 @@ texture_error_check( GLcontext *ctx, GLenum target,
GLint width, GLint height,
GLint depth, GLint border )
{
- GLboolean isProxy;
- GLint maxLevels = 0, maxTextureSize;
+ const GLboolean isProxy = is_proxy_target(target);
+ GLboolean sizeOK;
- if (dimensions == 1) {
- if (target == GL_PROXY_TEXTURE_1D) {
- isProxy = GL_TRUE;
+ /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
+ if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
+ if (!isProxy) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage%dD(level=%d)", dimensions, level);
}
- else if (target == GL_TEXTURE_1D) {
- isProxy = GL_FALSE;
+ return GL_TRUE;
+ }
+
+ /* Check border */
+ if (border < 0 || border > 1 ||
+ ((target == GL_TEXTURE_RECTANGLE_NV ||
+ target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
+ if (!isProxy) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexImage%dD(border=%d)", dimensions, border);
+ }
+ return GL_TRUE;
+ }
+
+ /* Check target and call ctx->Driver.TestProxyTexImage() to check the
+ * level, width, height and depth.
+ */
+ if (dimensions == 1) {
+ if (target == GL_PROXY_TEXTURE_1D || target == GL_TEXTURE_1D) {
+ sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_1D,
+ level, internalFormat,
+ format, type,
+ width, 1, 1, border);
}
else {
_mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
return GL_TRUE;
}
- maxLevels = ctx->Const.MaxTextureLevels;
}
else if (dimensions == 2) {
- if (target == GL_PROXY_TEXTURE_2D) {
- isProxy = GL_TRUE;
- maxLevels = ctx->Const.MaxTextureLevels;
- }
- else if (target == GL_TEXTURE_2D) {
- isProxy = GL_FALSE;
- maxLevels = ctx->Const.MaxTextureLevels;
- }
- else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
+ if (target == GL_PROXY_TEXTURE_2D || target == GL_TEXTURE_2D) {
+ sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_2D,
+ level, internalFormat,
+ format, type,
+ width, height, 1, border);
+ }
+ else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB ||
+ (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_TRUE;
- maxLevels = ctx->Const.MaxCubeTextureLevels;
+ sizeOK = (width == height) &&
+ ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_CUBE_MAP_ARB,
+ level, internalFormat, format, type,
+ width, height, 1, border);
}
- 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) {
+ else if (target == GL_PROXY_TEXTURE_RECTANGLE_NV ||
+ 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;
+ sizeOK = ctx->Driver.TestProxyTexImage(ctx,
+ GL_PROXY_TEXTURE_RECTANGLE_NV,
+ level, internalFormat,
+ format, type,
+ width, height, 1, border);
}
else {
_mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)");
@@ -950,132 +1052,32 @@ texture_error_check( GLcontext *ctx, GLenum target,
}
}
else if (dimensions == 3) {
- if (target == GL_PROXY_TEXTURE_3D) {
- isProxy = GL_TRUE;
- }
- else if (target == GL_TEXTURE_3D) {
- isProxy = GL_FALSE;
+ if (target == GL_PROXY_TEXTURE_3D || target == GL_TEXTURE_3D) {
+ sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_3D,
+ level, internalFormat,
+ format, type,
+ width, height, depth, border);
}
else {
_mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" );
return GL_TRUE;
}
- maxLevels = ctx->Const.Max3DTextureLevels;
}
else {
_mesa_problem( ctx, "bad dims in texture_error_check" );
return GL_TRUE;
}
- ASSERT(maxLevels > 0);
- maxTextureSize = 1 << (maxLevels - 1);
-
- /* Border */
- if (border != 0 && border != 1) {
- if (!isProxy) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glTexImage%dD(border=%d)", dimensions, border);
- }
- return GL_TRUE;
- }
- if ((target == GL_TEXTURE_RECTANGLE_NV ||
- target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0) {
- return GL_TRUE;
- }
-
- /* Width */
- if (target == GL_TEXTURE_RECTANGLE_NV ||
- target == GL_PROXY_TEXTURE_RECTANGLE_NV) {
- if (width < 1 || width > ctx->Const.MaxTextureRectSize) {
- if (!isProxy) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glTexImage%dD(width=%d)", dimensions, width);
- }
- return GL_TRUE;
- }
- }
- else if (width < 2 * border || width > 2 + maxTextureSize
- || logbase2( width - 2 * border ) < 0) {
- if (!isProxy) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glTexImage%dD(width=%d)", dimensions, width);
- }
- return GL_TRUE;
- }
-
- /* Height */
- if (target == GL_TEXTURE_RECTANGLE_NV ||
- target == GL_PROXY_TEXTURE_RECTANGLE_NV) {
- if (height < 1 || height > ctx->Const.MaxTextureRectSize) {
- if (!isProxy) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glTexImage%dD(height=%d)", dimensions, height);
- }
- return GL_TRUE;
- }
- }
- else if (dimensions >= 2) {
- if (height < 2 * border || height > 2 + maxTextureSize
- || logbase2( height - 2 * border ) < 0) {
- if (!isProxy) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glTexImage%dD(height=%d)", dimensions, height);
- }
- return GL_TRUE;
- }
- }
-
- /* For cube map, width must equal height */
- if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
- target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
- if (width != height) {
- if (!isProxy) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glTexImage2D(width != height)");
- }
- return GL_TRUE;
- }
- }
-
- /* Depth */
- if (dimensions >= 3) {
- if (depth < 2 * border || depth > 2 + maxTextureSize
- || logbase2( depth - 2 * border ) < 0) {
- if (!isProxy) {
- _mesa_error( ctx, GL_INVALID_VALUE,
- "glTexImage3D(depth=%d)", depth );
- }
- return GL_TRUE;
- }
- }
-
- /* Level */
- if (target == GL_TEXTURE_RECTANGLE_NV ||
- target == GL_PROXY_TEXTURE_RECTANGLE_NV) {
- if (level != 0) {
- if (!isProxy) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glTexImage2D(level=%d)", level);
- }
- return GL_TRUE;
- }
- }
- else if (level < 0 || level >= maxLevels) {
+ if (!sizeOK) {
if (!isProxy) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glTexImage%dD(level=%d)", dimensions, level);
+ "glTexImage%dD(level=%d, width=%d, height=%d, depth=%d)",
+ dimensions, level, width, height, depth);
}
return GL_TRUE;
}
- /* For cube map, width must equal height */
- if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
- target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
- if (width != height) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glTexImage2D(width != height)");
- return GL_TRUE;
- }
- }
-
+ /* Check internalFormat */
if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
if (!isProxy) {
_mesa_error(ctx, GL_INVALID_VALUE,
@@ -1085,6 +1087,7 @@ texture_error_check( GLcontext *ctx, GLenum target,
return GL_TRUE;
}
+ /* Check incoming image format and type */
if (!_mesa_is_legal_format_and_type(format, type)) {
/* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
* is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4.
@@ -1176,52 +1179,47 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions,
{
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
struct gl_texture_image *destTex;
- GLint maxLevels = 0;
+ /* Check target */
if (dimensions == 1) {
- if (target == GL_TEXTURE_1D) {
- maxLevels = ctx->Const.MaxTextureLevels;
- }
- else {
+ if (target != GL_TEXTURE_1D) {
_mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" );
return GL_TRUE;
}
}
else if (dimensions == 2) {
- if (ctx->Extensions.ARB_texture_cube_map &&
- target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
+ if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
target <=GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
- maxLevels = ctx->Const.MaxCubeTextureLevels;
+ if (!ctx->Extensions.ARB_texture_cube_map) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
+ return GL_TRUE;
+ }
}
else if (ctx->Extensions.NV_texture_rectangle &&
target == GL_TEXTURE_RECTANGLE_NV) {
- maxLevels = 1;
- }
- else if (target == GL_TEXTURE_2D) {
- maxLevels = ctx->Const.MaxTextureLevels;
+ if (!ctx->Extensions.NV_texture_rectangle) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
+ return GL_TRUE;
+ }
}
- else {
+ else if (target != GL_TEXTURE_2D) {
_mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
return GL_TRUE;
}
}
else if (dimensions == 3) {
- if (target == GL_TEXTURE_3D) {
- maxLevels = ctx->Const.Max3DTextureLevels;
- }
- else {
+ if (target != GL_TEXTURE_3D) {
_mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" );
return GL_TRUE;
}
}
else {
- _mesa_problem( ctx, "bad dims in texture_error_check" );
+ _mesa_problem( ctx, "invalid dims in texture_error_check" );
return GL_TRUE;
}
- ASSERT(maxLevels > 0);
-
- if (level < 0 || level >= maxLevels) {
+ /* Basic level check */
+ if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
_mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level);
return GL_TRUE;
}
@@ -1237,32 +1235,38 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions,
return GL_TRUE;
}
if (depth < 0 && dimensions > 2) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(depth=%d)", dimensions, depth);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTexSubImage%dD(depth=%d)", dimensions, depth);
return GL_TRUE;
}
destTex = _mesa_select_tex_image(ctx, texUnit, target, level);
if (!destTex) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage2D");
+ /* undefined image level */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%dD", dimensions);
return GL_TRUE;
}
if (xoffset < -((GLint)destTex->Border)) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage1/2/3D(xoffset)");
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset)",
+ dimensions);
return GL_TRUE;
}
if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage1/2/3D(xoffset+width)");
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset+width)",
+ dimensions);
return GL_TRUE;
}
if (dimensions > 1) {
if (yoffset < -((GLint)destTex->Border)) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage2/3D(yoffset)");
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset)",
+ dimensions);
return GL_TRUE;
}
if (yoffset + height > (GLint) (destTex->Height + destTex->Border)) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage2/3D(yoffset+height)");
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset+height)",
+ dimensions);
return GL_TRUE;
}
}
@@ -1336,82 +1340,93 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
GLenum target, GLint level, GLint internalFormat,
GLint width, GLint height, GLint border )
{
- GLint maxLevels = 0, maxTextureSize;
+ GLenum format, type;
+ GLboolean sizeOK;
+ /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
+ if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexImage%dD(level=%d)", dimensions, level);
+ return GL_TRUE;
+ }
+
+ /* Check border */
+ if (border < 0 || border > 1 ||
+ ((target == GL_TEXTURE_RECTANGLE_NV ||
+ target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
+ return GL_TRUE;
+ }
+
+ /* The format and type aren't really significant here, but we need to pass
+ * something to TestProxyTexImage().
+ */
+ format = _mesa_base_tex_format(ctx, internalFormat);
+ type = GL_FLOAT;
+
+ /* Check target and call ctx->Driver.TestProxyTexImage() to check the
+ * level, width, height and depth.
+ */
if (dimensions == 1) {
- if (target != GL_TEXTURE_1D) {
+ if (target == GL_TEXTURE_1D) {
+ sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_1D,
+ level, internalFormat,
+ format, type,
+ width, 1, 1, border);
+ }
+ else {
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1D(target)" );
return GL_TRUE;
}
- maxLevels = ctx->Const.MaxTextureLevels;
}
else if (dimensions == 2) {
- if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
- target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
+ if (target == GL_TEXTURE_2D) {
+ sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_2D,
+ level, internalFormat,
+ format, type,
+ width, height, 1, border);
+ }
+ 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, "glCopyTexImage2D(target)" );
return GL_TRUE;
}
+ sizeOK = (width == height) &&
+ ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_CUBE_MAP_ARB,
+ level, internalFormat, format, type,
+ width, height, 1, border);
}
else if (target == GL_TEXTURE_RECTANGLE_NV) {
if (!ctx->Extensions.NV_texture_rectangle) {
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
return GL_TRUE;
}
+ sizeOK = ctx->Driver.TestProxyTexImage(ctx,
+ GL_PROXY_TEXTURE_RECTANGLE_NV,
+ level, internalFormat,
+ format, type,
+ width, height, 1, border);
}
- else if (target != GL_TEXTURE_2D) {
+ else {
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
return GL_TRUE;
}
- if (target == GL_TEXTURE_2D)
- maxLevels = ctx->Const.MaxTextureLevels;
- else if (target == GL_TEXTURE_RECTANGLE_NV)
- maxLevels = 1;
- else
- maxLevels = ctx->Const.MaxCubeTextureLevels;
- }
-
- ASSERT(maxLevels > 0);
- maxTextureSize = 1 << (maxLevels - 1);
-
- /* Border */
- if (border != 0 && border != 1) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glCopyTexImage%dD(border)", dimensions);
- return GL_TRUE;
}
-
- /* Width */
- if (width < 2 * border || width > 2 + maxTextureSize
- || logbase2( width - 2 * border ) < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glCopyTexImage%dD(width=%d)", dimensions, width);
+ else {
+ _mesa_problem(ctx, "invalid dimensions in copytexture_error_check");
return GL_TRUE;
}
- /* Height */
- if (dimensions >= 2) {
- if (height < 2 * border || height > 2 + maxTextureSize
- || logbase2( height - 2 * border ) < 0) {
+ if (!sizeOK) {
+ if (dimensions == 1) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glCopyTexImage%dD(height=%d)", dimensions, height);
- return GL_TRUE;
+ "glCopyTexImage1D(width=%d)", width);
}
- }
-
- /* For cube map, width must equal height */
- if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
- target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
- if (width != height) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexImage2D(width != height)");
- return GL_TRUE;
+ else {
+ ASSERT(dimensions == 2);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCopyTexImage2D(width=%d, height=%d)", width, height);
}
- }
-
- /* Level */
- if (level < 0 || level >= maxLevels) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glCopyTexImage%dD(level=%d)", dimensions, level);
return GL_TRUE;
}
@@ -1447,14 +1462,13 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions,
{
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
struct gl_texture_image *teximage;
- GLint maxLevels = 0;
+ /* Check target */
if (dimensions == 1) {
if (target != GL_TEXTURE_1D) {
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" );
return GL_TRUE;
}
- maxLevels = ctx->Const.MaxTextureLevels;
}
else if (dimensions == 2) {
if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
@@ -1474,29 +1488,22 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions,
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
return GL_TRUE;
}
- if (target == GL_TEXTURE_2D)
- maxLevels = ctx->Const.MaxTextureLevels;
- else if (target == GL_TEXTURE_RECTANGLE_NV)
- maxLevels = 1;
- else
- maxLevels = ctx->Const.MaxCubeTextureLevels;
}
else if (dimensions == 3) {
if (target != GL_TEXTURE_3D) {
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3D(target)" );
return GL_TRUE;
}
- maxLevels = ctx->Const.Max3DTextureLevels;
}
- ASSERT(maxLevels > 0);
-
- if (level < 0 || level >= maxLevels) {
+ /* Check level */
+ if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glCopyTexSubImage%dD(level=%d)", dimensions, level);
return GL_TRUE;
}
+ /* Check size */
if (width < 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glCopyTexSubImage%dD(width=%d)", dimensions, width);
@@ -1792,30 +1799,22 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
}
else if (target == GL_PROXY_TEXTURE_1D) {
/* Proxy texture: check for errors and update proxy state */
- GLboolean error = texture_error_check(ctx, target, level, internalFormat,
- format, type, 1, postConvWidth, 1, 1, border);
- if (!error) {
- ASSERT(ctx->Driver.TestProxyTexImage);
- error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
- internalFormat, format, type,
- postConvWidth, 1, 1, border);
- }
- if (error) {
- /* if error, clear all proxy texture image parameters */
- struct gl_texture_image *texImage;
- texImage = _mesa_get_proxy_tex_image(ctx, target, level);
+ struct gl_texture_image *texImage;
+ texImage = _mesa_get_proxy_tex_image(ctx, target, level);
+ if (texture_error_check(ctx, target, level, internalFormat,
+ format, type, 1, postConvWidth, 1, 1, border)) {
+ /* when error, clear all proxy texture image parameters */
if (texImage)
clear_teximage_fields(texImage);
}
else {
/* no error, set the tex image parameters */
- struct gl_texture_unit *texUnit;
- struct gl_texture_image *texImage;
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ ASSERT(texImage);
_mesa_init_teximage_fields(ctx, target, texImage,
postConvWidth, 1, 1,
border, internalFormat);
+ texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
+ internalFormat, format, type);
}
}
else {
@@ -1901,30 +1900,22 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
(target == GL_PROXY_TEXTURE_RECTANGLE_NV &&
ctx->Extensions.NV_texture_rectangle)) {
/* Proxy texture: check for errors and update proxy state */
- GLboolean error = texture_error_check(ctx, target, level, internalFormat,
- format, type, 2, postConvWidth, postConvHeight, 1, border);
- if (!error) {
- ASSERT(ctx->Driver.TestProxyTexImage);
- error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
- internalFormat, format, type,
- postConvWidth, postConvHeight, 1, border);
- }
- if (error) {
- /* if error, clear all proxy texture image parameters */
- struct gl_texture_image *texImage;
- texImage = _mesa_get_proxy_tex_image(ctx, target, level);
+ struct gl_texture_image *texImage;
+ texImage = _mesa_get_proxy_tex_image(ctx, target, level);
+ if (texture_error_check(ctx, target, level, internalFormat,
+ format, type, 2, postConvWidth, postConvHeight,
+ 1, border)) {
+ /* when error, clear all proxy texture image parameters */
if (texImage)
clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]);
}
else {
/* no error, set the tex image parameters */
- struct gl_texture_unit *texUnit;
- 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, target, texImage,
postConvWidth, postConvHeight, 1,
border, internalFormat);
+ texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
+ internalFormat, format, type);
}
}
else {
@@ -1996,29 +1987,20 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
}
else if (target == GL_PROXY_TEXTURE_3D) {
/* Proxy texture: check for errors and update proxy state */
- GLboolean error = texture_error_check(ctx, target, level, internalFormat,
- format, type, 3, width, height, depth, border);
- if (!error) {
- ASSERT(ctx->Driver.TestProxyTexImage);
- error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
- internalFormat, format, type,
- width, height, depth, border);
- }
- if (error) {
- /* if error, clear all proxy texture image parameters */
- struct gl_texture_image *texImage;
- texImage = _mesa_get_proxy_tex_image(ctx, target, level);
+ struct gl_texture_image *texImage;
+ texImage = _mesa_get_proxy_tex_image(ctx, target, level);
+ if (texture_error_check(ctx, target, level, internalFormat,
+ format, type, 3, width, height, depth, border)) {
+ /* when error, clear all proxy texture image parameters */
if (texImage)
clear_teximage_fields(texImage);
}
else {
/* no error, set the tex image parameters */
- struct gl_texture_unit *texUnit;
- 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, target, texImage, width, height, 1,
border, internalFormat);
+ texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
+ internalFormat, format, type);
}
}
else {