mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 04:58:05 +02:00
mesa: consolidate subtexture xoffset/yoffset/width/height error checking code
This is the code that checks if a subtexture region is aligned to the compressed format's block size.
This commit is contained in:
parent
2558af7e93
commit
bd3caa50a5
1 changed files with 73 additions and 88 deletions
|
|
@ -1342,6 +1342,60 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do error checking of xoffset, yoffset, width, height for glTexSubImage,
|
||||||
|
* glCopyTexSubImage and glCompressedTexSubImage.
|
||||||
|
* Basically, check that the subregion is aligned to the compressed format's
|
||||||
|
* block size. See comments in function for more info.
|
||||||
|
* \return GL_TRUE if error found, GL_FALSE otherwise.
|
||||||
|
*/
|
||||||
|
static GLboolean
|
||||||
|
error_check_subtexture_dimensions(struct gl_context *ctx,
|
||||||
|
const char *function,
|
||||||
|
GLuint dims,
|
||||||
|
gl_format texFormat,
|
||||||
|
GLint xoffset, GLint yoffset,
|
||||||
|
GLsizei subWidth, GLsizei subHeight,
|
||||||
|
GLsizei texWidth, GLsizei texHeight)
|
||||||
|
{
|
||||||
|
GLuint bw, bh;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The OpenGL spec (and GL_ARB_texture_compression) says only whole
|
||||||
|
* compressed texture images can be updated. But, that restriction may be
|
||||||
|
* relaxed for particular compressed formats. At this time, all the
|
||||||
|
* compressed formats supported by Mesa allow sub-textures to be updated
|
||||||
|
* along compressed block boundaries.
|
||||||
|
*/
|
||||||
|
_mesa_get_format_block_size(texFormat, &bw, &bh);
|
||||||
|
|
||||||
|
/* offset must be multiple of block size */
|
||||||
|
if ((xoffset % bw != 0) || (yoffset % bh != 0)) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||||
|
"%s%dD(xoffset = %d, yoffset = %d)",
|
||||||
|
function, dims, xoffset, yoffset);
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* size must be multiple of bw by bh or equal to whole texture size */
|
||||||
|
if ((subWidth % bw != 0) && subWidth != texWidth) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||||
|
"%s%dD(width = %d)", function, dims, subWidth);
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((subHeight % bh != 0) && subHeight != texHeight) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||||
|
"%s%dD(height = %d)", function, dims, subHeight);
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the fallback for Driver.TestProxyTexImage() for doing device-
|
* This is the fallback for Driver.TestProxyTexImage() for doing device-
|
||||||
* specific texture image size checks.
|
* specific texture image size checks.
|
||||||
|
|
@ -1649,17 +1703,6 @@ compressed_tex_size(GLsizei width, GLsizei height, GLsizei depth,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return compressed texture block size, in pixels.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
get_compressed_block_size(GLenum glformat, GLuint *bw, GLuint *bh)
|
|
||||||
{
|
|
||||||
gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat);
|
|
||||||
_mesa_get_format_block_size(mesaFormat, bw, bh);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the glTexImage[123]D() parameters for errors.
|
* Test the glTexImage[123]D() parameters for errors.
|
||||||
*
|
*
|
||||||
|
|
@ -2195,35 +2238,19 @@ subtexture_error_check2( struct gl_context *ctx, GLuint dimensions,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_mesa_is_format_compressed(destTex->TexFormat)) {
|
if (_mesa_is_format_compressed(destTex->TexFormat)) {
|
||||||
GLuint bw, bh;
|
|
||||||
|
|
||||||
if (compressedteximage_only_format(ctx, destTex->InternalFormat)) {
|
if (compressedteximage_only_format(ctx, destTex->InternalFormat)) {
|
||||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||||
"glTexSubImage%dD(no compression for format)", dimensions);
|
"glTexSubImage%dD(no compression for format)", dimensions);
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* do tests which depend on compression block size */
|
if (error_check_subtexture_dimensions(ctx, "glTexSubImage", dimensions,
|
||||||
_mesa_get_format_block_size(destTex->TexFormat, &bw, &bh);
|
destTex->TexFormat,
|
||||||
|
xoffset, yoffset,
|
||||||
/* offset must be multiple of block size */
|
width, height,
|
||||||
if ((xoffset % bw != 0) || (yoffset % bh != 0)) {
|
destTex->Width, destTex->Height)) {
|
||||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
|
||||||
"glTexSubImage%dD(xoffset = %d, yoffset = %d)",
|
|
||||||
dimensions, xoffset, yoffset);
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
/* size must be multiple of bw by bh or equal to whole texture size */
|
|
||||||
if ((width % bw != 0) && (GLuint) width != destTex->Width) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
|
||||||
"glTexSubImage%dD(width = %d)", dimensions, width);
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
if ((height % bh != 0) && (GLuint) height != destTex->Height) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
|
||||||
"glTexSubImage%dD(height = %d)", dimensions, height);
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) {
|
if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) {
|
||||||
|
|
@ -2514,23 +2541,14 @@ copytexsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
|
||||||
"glCopyTexSubImage%dD(no compression for format)", dimensions);
|
"glCopyTexSubImage%dD(no compression for format)", dimensions);
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
/* offset must be multiple of 4 */
|
|
||||||
if ((xoffset & 3) || (yoffset & 3)) {
|
if (error_check_subtexture_dimensions(ctx, "glCopyTexSubImage",
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
dimensions, texImage->TexFormat,
|
||||||
"glCopyTexSubImage%dD(xoffset or yoffset)", dimensions);
|
xoffset, yoffset, width, height,
|
||||||
|
texImage->Width,
|
||||||
|
texImage->Height)) {
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
/* size must be multiple of 4 */
|
|
||||||
if ((width & 3) != 0 && (GLuint) width != texImage->Width) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
|
||||||
"glCopyTexSubImage%dD(width)", dimensions);
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
if ((height & 3) != 0 && (GLuint) height != texImage->Height) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
|
||||||
"glCopyTexSubImage%dD(height)", dimensions);
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (texImage->InternalFormat == GL_YCBCR_MESA) {
|
if (texImage->InternalFormat == GL_YCBCR_MESA) {
|
||||||
|
|
@ -3500,7 +3518,7 @@ compressed_subtexture_error_check(struct gl_context *ctx, GLint dimensions,
|
||||||
GLenum format, GLsizei imageSize)
|
GLenum format, GLsizei imageSize)
|
||||||
{
|
{
|
||||||
GLint expectedSize, maxLevels = 0, maxTextureSize;
|
GLint expectedSize, maxLevels = 0, maxTextureSize;
|
||||||
GLuint bw, bh;
|
|
||||||
(void) zoffset;
|
(void) zoffset;
|
||||||
|
|
||||||
if (dimensions == 1) {
|
if (dimensions == 1) {
|
||||||
|
|
@ -3549,20 +3567,6 @@ compressed_subtexture_error_check(struct gl_context *ctx, GLint dimensions,
|
||||||
if (level < 0 || level >= maxLevels)
|
if (level < 0 || level >= maxLevels)
|
||||||
return GL_INVALID_VALUE;
|
return GL_INVALID_VALUE;
|
||||||
|
|
||||||
/*
|
|
||||||
* do checks which depend on compression block size
|
|
||||||
*/
|
|
||||||
get_compressed_block_size(format, &bw, &bh);
|
|
||||||
|
|
||||||
if ((xoffset % bw != 0) || (yoffset % bh != 0))
|
|
||||||
return GL_INVALID_OPERATION;
|
|
||||||
|
|
||||||
if ((width % bw != 0) && width != 2 && width != 1)
|
|
||||||
return GL_INVALID_OPERATION;
|
|
||||||
|
|
||||||
if ((height % bh != 0) && height != 2 && height != 1)
|
|
||||||
return GL_INVALID_OPERATION;
|
|
||||||
|
|
||||||
expectedSize = compressed_tex_size(width, height, depth, format);
|
expectedSize = compressed_tex_size(width, height, depth, format);
|
||||||
if (expectedSize != imageSize)
|
if (expectedSize != imageSize)
|
||||||
return GL_INVALID_VALUE;
|
return GL_INVALID_VALUE;
|
||||||
|
|
@ -3577,6 +3581,7 @@ compressed_subtexture_error_check(struct gl_context *ctx, GLint dimensions,
|
||||||
*/
|
*/
|
||||||
static GLboolean
|
static GLboolean
|
||||||
compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims,
|
compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims,
|
||||||
|
GLint xoffset, GLint yoffset,
|
||||||
GLsizei width, GLsizei height,
|
GLsizei width, GLsizei height,
|
||||||
GLsizei depth, GLenum format,
|
GLsizei depth, GLenum format,
|
||||||
struct gl_texture_image *texImage)
|
struct gl_texture_image *texImage)
|
||||||
|
|
@ -3595,34 +3600,13 @@ compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims,
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((width == 1 || width == 2) &&
|
if (error_check_subtexture_dimensions(ctx, "glCompressedTexSubImage", dims,
|
||||||
width != (GLsizei) texImage->Width) ||
|
texImage->TexFormat,
|
||||||
(width > (GLsizei) texImage->Width)) {
|
xoffset, yoffset, width, height,
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
texImage->Width, texImage->Height)) {
|
||||||
"glCompressedTexSubImage%uD(width=%d)", dims, width);
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dims >= 2) {
|
|
||||||
if (((height == 1 || height == 2) &&
|
|
||||||
height != (GLsizei) texImage->Height) ||
|
|
||||||
(height > (GLsizei) texImage->Height)) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
|
||||||
"glCompressedTexSubImage%uD(height=%d)", dims, height);
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dims >= 3) {
|
|
||||||
if (((depth == 1 || depth == 2) &&
|
|
||||||
depth != (GLsizei) texImage->Depth) ||
|
|
||||||
(depth > (GLsizei) texImage->Depth)) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
|
||||||
"glCompressedTexSubImage%uD(depth=%d)", dims, depth);
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3694,7 +3678,8 @@ compressed_tex_sub_image(GLuint dims, GLenum target, GLint level,
|
||||||
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
|
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
|
||||||
assert(texImage);
|
assert(texImage);
|
||||||
|
|
||||||
if (compressed_subtexture_error_check2(ctx, dims, width, height, depth,
|
if (compressed_subtexture_error_check2(ctx, dims, xoffset, yoffset,
|
||||||
|
width, height, depth,
|
||||||
format, texImage)) {
|
format, texImage)) {
|
||||||
/* error was recorded */
|
/* error was recorded */
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue