Fix validation for compressed texture functions.
* No validation that the format matched the texture level's format for
SubImage calls.
* WebGL does not allow the base level to be smaller than the block size.
* ANGLE used to allow mips of size 3 when this is disallowed.
* Don't early-exit validation when dimensions are 0, imageSize validation
happens later.
TEST=conformance/extensions/webgl-compressed-texture-s3tc
BUG=angleproject:1998
Change-Id: I05f5a0b5180344d67b036fdecc17edd2256e85ab
Reviewed-on: https://chromium-review.googlesource.com/480442
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
index 71f124e..e60768b 100644
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
@@ -1251,6 +1251,96 @@
EXPECT_EQ(0u, program);
}
+// Test dimension and image size validation of compressed textures
+TEST_P(WebGLCompatibilityTest, CompressedTextureS3TC)
+{
+ if (extensionRequestable("GL_EXT_texture_compression_dxt1"))
+ {
+ glRequestExtensionANGLE("GL_EXT_texture_compression_dxt1");
+ }
+
+ if (!extensionEnabled("GL_EXT_texture_compression_dxt1"))
+ {
+ std::cout << "Test skipped because GL_EXT_texture_compression_dxt1 is not available."
+ << std::endl;
+ return;
+ }
+
+ constexpr uint8_t CompressedImageDXT1[] = {0x00, 0xf8, 0x00, 0xf8, 0xaa, 0xaa, 0xaa, 0xaa};
+
+ GLTexture texture;
+ glBindTexture(GL_TEXTURE_2D, texture);
+
+ // Regular case, verify that it works
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0,
+ sizeof(CompressedImageDXT1), CompressedImageDXT1);
+ ASSERT_GL_NO_ERROR();
+
+ // Test various dimensions that are not valid
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 3, 4, 0,
+ sizeof(CompressedImageDXT1), CompressedImageDXT1);
+ ASSERT_GL_ERROR(GL_INVALID_OPERATION);
+
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 3, 0,
+ sizeof(CompressedImageDXT1), CompressedImageDXT1);
+ ASSERT_GL_ERROR(GL_INVALID_OPERATION);
+
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 2, 2, 0,
+ sizeof(CompressedImageDXT1), CompressedImageDXT1);
+ ASSERT_GL_ERROR(GL_INVALID_OPERATION);
+
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 1, 1, 0,
+ sizeof(CompressedImageDXT1), CompressedImageDXT1);
+ ASSERT_GL_ERROR(GL_INVALID_OPERATION);
+
+ // Test various image sizes that are not valid
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0,
+ sizeof(CompressedImageDXT1) - 1, CompressedImageDXT1);
+ ASSERT_GL_ERROR(GL_INVALID_VALUE);
+
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0,
+ sizeof(CompressedImageDXT1) + 1, CompressedImageDXT1);
+ ASSERT_GL_ERROR(GL_INVALID_VALUE);
+
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0, 0,
+ CompressedImageDXT1);
+ ASSERT_GL_ERROR(GL_INVALID_VALUE);
+
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 0, 0, 0,
+ sizeof(CompressedImageDXT1), CompressedImageDXT1);
+ ASSERT_GL_ERROR(GL_INVALID_VALUE);
+
+ // Fill a full mip chain and verify that it works
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0,
+ sizeof(CompressedImageDXT1), CompressedImageDXT1);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 2, 2, 0,
+ sizeof(CompressedImageDXT1), CompressedImageDXT1);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 2, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 1, 1, 0,
+ sizeof(CompressedImageDXT1), CompressedImageDXT1);
+ ASSERT_GL_NO_ERROR();
+
+ glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ sizeof(CompressedImageDXT1), CompressedImageDXT1);
+ ASSERT_GL_NO_ERROR();
+
+ // Test that non-block size sub-uploads are not valid for the 0 mip
+ glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 2, 2, 2, 2, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ sizeof(CompressedImageDXT1), CompressedImageDXT1);
+ ASSERT_GL_ERROR(GL_INVALID_OPERATION);
+
+ // Test that non-block size sub-uploads are valid for if they fill the whole mip
+ glCompressedTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 2, 2, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ sizeof(CompressedImageDXT1), CompressedImageDXT1);
+ glCompressedTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, 1, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ sizeof(CompressedImageDXT1), CompressedImageDXT1);
+ ASSERT_GL_NO_ERROR();
+
+ // Test that if the format miss-matches the texture, an error is generated
+ glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 2, 2, 2, 2, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
+ sizeof(CompressedImageDXT1), CompressedImageDXT1);
+ ASSERT_GL_ERROR(GL_INVALID_OPERATION);
+}
+
// This tests that rendering feedback loops works as expected with WebGL 2.
// Based on WebGL test conformance2/rendering/rendering-sampling-feedback-loop.html
TEST_P(WebGL2CompatibilityTest, RenderingFeedbackLoopWithDrawBuffers)