mesa: refactor glGetTexImage error checking code

This commit is contained in:
Brian Paul
2009-07-30 09:50:36 -06:00
parent 783a93a2c3
commit 25be043940

View File

@@ -1,6 +1,6 @@
/*
* mesa 3-D graphics library
* Version: 7.5
* Version: 7.6
*
* Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
* Copyright (C) 2009 VMware, Inc. All Rights Reserved.
@@ -2191,6 +2191,127 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions,
}
/**
* Do error checking for a glGetTexImage() call.
* \return GL_TRUE if any error, GL_FALSE if no errors.
*/
static GLboolean
getteximage_error_check(GLcontext *ctx, GLenum target, GLint level,
GLenum format, GLenum type, GLvoid *pixels )
{
const struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
const GLuint maxLevels = _mesa_max_texture_levels(ctx, target);
ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
if (level < 0 || level >= maxLevels) {
_mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
return GL_TRUE;
}
if (_mesa_sizeof_packed_type(type) <= 0) {
_mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
return GL_TRUE;
}
if (_mesa_components_in_format(format) <= 0 ||
format == GL_STENCIL_INDEX) {
_mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
return GL_TRUE;
}
if (!ctx->Extensions.EXT_paletted_texture && is_index_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return GL_TRUE;
}
if (!ctx->Extensions.ARB_depth_texture && is_depth_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return GL_TRUE;
}
if (!ctx->Extensions.MESA_ycbcr_texture && is_ycbcr_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return GL_TRUE;
}
if (!ctx->Extensions.EXT_packed_depth_stencil
&& is_depthstencil_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return GL_TRUE;
}
if (!ctx->Extensions.ATI_envmap_bumpmap
&& is_dudv_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return GL_TRUE;
}
texUnit = &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
if (!texImage) {
/* out of memory */
return GL_TRUE;
}
/* Make sure the requested image format is compatible with the
* texture's format. Note that a color index texture can be converted
* to RGBA so that combo is allowed.
*/
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)");
return GL_TRUE;
}
else if (is_index_format(format)
&& !is_index_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
return GL_TRUE;
}
else if (is_depth_format(format)
&& !is_depth_format(texImage->TexFormat->BaseFormat)
&& !is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
return GL_TRUE;
}
else if (is_ycbcr_format(format)
&& !is_ycbcr_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
return GL_TRUE;
}
else if (is_depthstencil_format(format)
&& !is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
return GL_TRUE;
}
else if (is_dudv_format(format)
&& !is_dudv_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
return GL_TRUE;
}
if (ctx->Pack.BufferObj->Name) {
/* packing texture image into a PBO */
const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width,
texImage->Height, texImage->Depth,
format, type, pixels)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetTexImage(invalid PBO access)");
return GL_TRUE;
}
}
return GL_FALSE;
}
/**
* Get texture image. Called by glGetTexImage.
*
@@ -2206,8 +2327,6 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
{
const struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLint maxLevels = 0;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
@@ -2218,116 +2337,19 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
return;
}
maxLevels = _mesa_max_texture_levels(ctx, target);
ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
if (level < 0 || level >= maxLevels) {
_mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
return;
}
if (_mesa_sizeof_packed_type(type) <= 0) {
_mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
return;
}
if (_mesa_components_in_format(format) <= 0 ||
format == GL_STENCIL_INDEX) {
_mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
return;
}
if (!ctx->Extensions.EXT_paletted_texture && is_index_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return;
}
if (!ctx->Extensions.ARB_depth_texture && is_depth_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return;
}
if (!ctx->Extensions.MESA_ycbcr_texture && is_ycbcr_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return;
}
if (!ctx->Extensions.EXT_packed_depth_stencil
&& is_depthstencil_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
return;
}
if (!ctx->Extensions.ATI_envmap_bumpmap
&& is_dudv_format(format)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
if (getteximage_error_check(ctx, target, level, format, type, pixels)) {
return;
}
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
if (!texImage) {
/* invalid mipmap level, not an error */
goto out;
}
/* Make sure the requested image format is compatible with the
* texture's format. Note that a color index texture can be converted
* to RGBA so that combo is allowed.
*/
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;
}
else if (is_index_format(format)
&& !is_index_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
goto out;
}
else if (is_depth_format(format)
&& !is_depth_format(texImage->TexFormat->BaseFormat)
&& !is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
goto out;
}
else if (is_ycbcr_format(format)
&& !is_ycbcr_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
goto out;
}
else if (is_depthstencil_format(format)
&& !is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
goto out;
}
else if (is_dudv_format(format)
&& !is_dudv_format(texImage->TexFormat->BaseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
goto out;
}
if (ctx->Pack.BufferObj->Name) {
/* packing texture image into a PBO */
const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width,
texImage->Height, texImage->Depth,
format, type, pixels)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetTexImage(invalid PBO access)");
goto out;
}
}
struct gl_texture_image *texImage =
_mesa_select_tex_image(ctx, texObj, target, level);
/* typically, this will call _mesa_get_teximage() */
ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels,
texObj, texImage);
texObj, texImage);
}
out:
_mesa_unlock_texture(ctx, texObj);
}