Commit 44ff5a76 by Geoff Lang Committed by Commit Bot

Validate xoffset and yoffset are multiples of blocksize.

Affects glCompressedTexSubImage and glCopyCompressedTexSubImage calls. BUG=668223 Change-Id: Ie71faa1fa7dac12cec51a2e29e0ce212ac54e411 Reviewed-on: https://chromium-review.googlesource.com/437605 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent c295e516
...@@ -1718,6 +1718,8 @@ bool CompressedTextureFormatRequiresExactSize(GLenum internalFormat) ...@@ -1718,6 +1718,8 @@ bool CompressedTextureFormatRequiresExactSize(GLenum internalFormat)
bool ValidCompressedImageSize(const ValidationContext *context, bool ValidCompressedImageSize(const ValidationContext *context,
GLenum internalFormat, GLenum internalFormat,
GLint xoffset,
GLint yoffset,
GLsizei width, GLsizei width,
GLsizei height) GLsizei height)
{ {
...@@ -1727,14 +1729,16 @@ bool ValidCompressedImageSize(const ValidationContext *context, ...@@ -1727,14 +1729,16 @@ bool ValidCompressedImageSize(const ValidationContext *context,
return false; return false;
} }
if (width < 0 || height < 0) if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
{ {
return false; return false;
} }
if (CompressedTextureFormatRequiresExactSize(internalFormat)) if (CompressedTextureFormatRequiresExactSize(internalFormat))
{ {
if ((static_cast<GLuint>(width) > formatInfo.compressedBlockWidth && if (xoffset % formatInfo.compressedBlockWidth != 0 ||
yoffset % formatInfo.compressedBlockHeight != 0 ||
(static_cast<GLuint>(width) > formatInfo.compressedBlockWidth &&
width % formatInfo.compressedBlockWidth != 0) || width % formatInfo.compressedBlockWidth != 0) ||
(static_cast<GLuint>(height) > formatInfo.compressedBlockHeight && (static_cast<GLuint>(height) > formatInfo.compressedBlockHeight &&
height % formatInfo.compressedBlockHeight != 0)) height % formatInfo.compressedBlockHeight != 0))
...@@ -3143,7 +3147,8 @@ bool ValidateCopyTexImageParametersBase(ValidationContext *context, ...@@ -3143,7 +3147,8 @@ bool ValidateCopyTexImageParametersBase(ValidationContext *context,
return false; return false;
} }
if (formatInfo.compressed && !ValidCompressedImageSize(context, internalformat, width, height)) if (formatInfo.compressed &&
!ValidCompressedImageSize(context, internalformat, xoffset, yoffset, width, height))
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION));
return false; return false;
......
...@@ -49,6 +49,8 @@ bool ValidImageSizeParameters(const ValidationContext *context, ...@@ -49,6 +49,8 @@ bool ValidImageSizeParameters(const ValidationContext *context,
bool isSubImage); bool isSubImage);
bool ValidCompressedImageSize(const ValidationContext *context, bool ValidCompressedImageSize(const ValidationContext *context,
GLenum internalFormat, GLenum internalFormat,
GLint xoffset,
GLint yoffset,
GLsizei width, GLsizei width,
GLsizei height); GLsizei height);
bool ValidImageDataSize(ValidationContext *context, bool ValidImageDataSize(ValidationContext *context,
......
...@@ -467,7 +467,8 @@ bool ValidateES2TexImageParameters(Context *context, ...@@ -467,7 +467,8 @@ bool ValidateES2TexImageParameters(Context *context,
"internalformat is not a supported compressed internal format")); "internalformat is not a supported compressed internal format"));
return false; return false;
} }
if (!ValidCompressedImageSize(context, actualInternalFormat, width, height)) if (!ValidCompressedImageSize(context, actualInternalFormat, xoffset, yoffset, width,
height))
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION));
return false; return false;
......
...@@ -188,7 +188,8 @@ bool ValidateES3TexImageParametersBase(Context *context, ...@@ -188,7 +188,8 @@ bool ValidateES3TexImageParametersBase(Context *context,
return false; return false;
} }
if (!ValidCompressedImageSize(context, actualInternalFormat, width, height)) if (!ValidCompressedImageSize(context, actualInternalFormat, xoffset, yoffset, width,
height))
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION));
return false; return false;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
// //
#include "test_utils/ANGLETest.h" #include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
#include "media/pixel.inl" #include "media/pixel.inl"
...@@ -174,6 +175,29 @@ TEST_P(DXT1CompressedTextureTest, CompressedTexStorage) ...@@ -174,6 +175,29 @@ TEST_P(DXT1CompressedTextureTest, CompressedTexStorage)
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
} }
// Test validation of glCompressedTexSubImage2D with DXT formats
TEST_P(DXT1CompressedTextureTest, CompressedTexSubImageValidation)
{
if (!extensionEnabled("GL_EXT_texture_compression_dxt1"))
{
std::cout << "Test skipped due to missing GL_EXT_texture_compression_dxt1" << std::endl;
return;
}
GLTexture texture;
glBindTexture(GL_TEXTURE_2D, texture.get());
// Size mip 0 to a large size
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
pixel_0_height, 0, pixel_0_size, nullptr);
ASSERT_GL_NO_ERROR();
// Set a sub image with an offset that isn't a multiple of the block size
glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 1, 3, pixel_1_width, pixel_1_height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_1_size, pixel_1_data);
ASSERT_GL_ERROR(GL_INVALID_OPERATION);
}
class DXT1CompressedTextureTestES3 : public DXT1CompressedTextureTest { }; class DXT1CompressedTextureTestES3 : public DXT1CompressedTextureTest { };
class DXT1CompressedTextureTestD3D11 : public DXT1CompressedTextureTest { }; class DXT1CompressedTextureTestD3D11 : public DXT1CompressedTextureTest { };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment