-
Notifications
You must be signed in to change notification settings - Fork 15.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: cherry-pick fix for 1234829 from angle (#30585)
* chore: cherry-pick 1234829 from angle * chore: update patches Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
- Loading branch information
1 parent
2cca38c
commit 7d129ac
Showing
4 changed files
with
394 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
cherry-pick-d8cb996.patch | ||
cherry-pick-1fb846c.patch |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
From: Alexey Knyazev <lexa.knyazev@gmail.com> | ||
Date: Tue, 3 Aug 2021 01:57:49 +0400 | ||
Subject: Validate texStorage dimensions with compressed formats | ||
|
||
Bug: angleproject:6230 | ||
Change-Id: I501ec1e6974bdc7e6731dcb88045edb0aa22b888 | ||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3067329 | ||
Commit-Queue: Alexey Knyazev <lexa.knyazev@gmail.com> | ||
Reviewed-by: Kenneth Russell <kbr@chromium.org> | ||
Reviewed-by: Jamie Madill <jmadill@chromium.org> | ||
|
||
diff --git a/src/libANGLE/validationES3.cpp b/src/libANGLE/validationES3.cpp | ||
index 53e1afd6e26ef8cc099e51c66457a968ca82b1c8..5c69d568ee45b9e8bf1d4d0da7b9a48b123a47c0 100644 | ||
--- a/src/libANGLE/validationES3.cpp | ||
+++ b/src/libANGLE/validationES3.cpp | ||
@@ -1339,17 +1339,26 @@ bool ValidateES3TexStorageParametersBase(const Context *context, | ||
return false; | ||
} | ||
|
||
- if (formatInfo.compressed && target == TextureType::Rectangle) | ||
+ if (formatInfo.compressed) | ||
{ | ||
- context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed); | ||
- return false; | ||
- } | ||
+ if (target == TextureType::Rectangle) | ||
+ { | ||
+ context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed); | ||
+ return false; | ||
+ } | ||
|
||
- if (formatInfo.compressed && target == TextureType::_3D) | ||
- { | ||
- if (!ValidateES3CompressedFormatForTexture3D(context, formatInfo.internalFormat)) | ||
+ if (target == TextureType::_3D) | ||
{ | ||
- // Error already generated. | ||
+ if (!ValidateES3CompressedFormatForTexture3D(context, formatInfo.internalFormat)) | ||
+ { | ||
+ // Error already generated. | ||
+ return false; | ||
+ } | ||
+ } | ||
+ | ||
+ if (!ValidCompressedImageSize(context, formatInfo.internalFormat, 0, width, height, depth)) | ||
+ { | ||
+ context->validationError(GL_INVALID_OPERATION, kInvalidCompressedImageSize); | ||
return false; | ||
} | ||
} | ||
diff --git a/src/tests/gl_tests/SRGBTextureTest.cpp b/src/tests/gl_tests/SRGBTextureTest.cpp | ||
index 271fe6dbaa1d5684f7c2e16bdef18bce30943e8b..a0eab1af9e34a5de75e226efef9c0af4a50c63ff 100644 | ||
--- a/src/tests/gl_tests/SRGBTextureTest.cpp | ||
+++ b/src/tests/gl_tests/SRGBTextureTest.cpp | ||
@@ -340,7 +340,7 @@ TEST_P(SRGBTextureTestES3, SRGBOverrideFormats) | ||
{ | ||
GLTexture tex; | ||
glBindTexture(GL_TEXTURE_2D, tex.get()); | ||
- glTexStorage2D(GL_TEXTURE_2D, 1, format, 1, 1); | ||
+ glTexStorage2D(GL_TEXTURE_2D, 1, format, 4, 4); | ||
GLenum error = glGetError(); | ||
if (error == GL_INVALID_ENUM) | ||
{ | ||
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp | ||
index fabaefbe33c94a048ec7c974951ac9ef886826ef..efbd9ebdb2bb29cf9673750e1e3e7b492bfbf87e 100644 | ||
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp | ||
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp | ||
@@ -5073,6 +5073,21 @@ void WebGLCompatibilityTest::testCompressedTexLevelDimension(GLenum format, | ||
{ | ||
EXPECT_GL_ERROR(expectedError) << explanation; | ||
} | ||
+ | ||
+ if (level == 0 && width > 0 && getClientMajorVersion() >= 3) | ||
+ { | ||
+ GLTexture sourceTextureStorage; | ||
+ glBindTexture(GL_TEXTURE_2D, sourceTextureStorage); | ||
+ glTexStorage2D(GL_TEXTURE_2D, 1, format, width, height); | ||
+ if (expectedError == 0) | ||
+ { | ||
+ EXPECT_GL_NO_ERROR() << explanation << " (texStorage)"; | ||
+ } | ||
+ else | ||
+ { | ||
+ EXPECT_GL_ERROR(expectedError) << explanation << " (texStorage)"; | ||
+ } | ||
+ } | ||
} | ||
|
||
void WebGLCompatibilityTest::testCompressedTexImage(GLenum format) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,300 @@ | ||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
From: Kenneth Russell <kbr@chromium.org> | ||
Date: Wed, 4 Aug 2021 18:15:51 -0700 | ||
Subject: In WebGL, constrain base level of compressed textures. | ||
|
||
Enforce that if a mipmap level > 0 is specified for a compressed | ||
texture, that it implies that the size of the base level of the | ||
texture is a multiple of the format's block size. | ||
|
||
Makes the test changes in | ||
https://github.com/KhronosGroup/WebGL/pull/3304 largely pass. There | ||
are some needed follow-on fixes to that PR, and this CL changes a | ||
sub-test result in the existing S3TC and S3TC-sRGB tests which will | ||
need to be suppressed Chromium-side first. | ||
|
||
Bug: angleproject:6245 | ||
Change-Id: I7723d7882091b78a353d8d273e80b819dd384021 | ||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3072568 | ||
Commit-Queue: Kenneth Russell <kbr@chromium.org> | ||
Reviewed-by: Jamie Madill <jmadill@chromium.org> | ||
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> | ||
|
||
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp | ||
index 656e51f17724af9e0959fcd741ceeebf25ee0f24..412b9aa0f1d75c40ce02522589c53e943d049228 100644 | ||
--- a/src/libANGLE/validationES.cpp | ||
+++ b/src/libANGLE/validationES.cpp | ||
@@ -1006,6 +1006,15 @@ bool ValidCompressedDimension(GLsizei size, GLuint blockSize, GLint level) | ||
return (level > 0) || (size % blockSize == 0); | ||
} | ||
|
||
+bool ValidCompressedBaseLevelForWebGL(GLsizei size, GLuint blockSize, GLint level) | ||
+{ | ||
+ // Avoid C++ undefined behavior. | ||
+ constexpr int maxValidShifts = 31; | ||
+ if (level > maxValidShifts) | ||
+ return false; | ||
+ return ((size << level) % blockSize) == 0; | ||
+} | ||
+ | ||
bool ValidCompressedImageSize(const Context *context, | ||
GLenum internalFormat, | ||
GLint level, | ||
@@ -1043,11 +1052,27 @@ bool ValidCompressedImageSize(const Context *context, | ||
|
||
if (CompressedTextureFormatRequiresExactSize(internalFormat)) | ||
{ | ||
- if (!ValidCompressedDimension(width, formatInfo.compressedBlockWidth, level) || | ||
- !ValidCompressedDimension(height, formatInfo.compressedBlockHeight, level) || | ||
- !ValidCompressedDimension(depth, formatInfo.compressedBlockDepth, level)) | ||
+ // In WebGL compatibility mode, enforce that the base level implied | ||
+ // by the compressed texture's mip level would conform to the block | ||
+ // size. This is more strict than the non-WebGL check. | ||
+ if (context->getExtensions().webglCompatibility) | ||
{ | ||
- return false; | ||
+ if (!ValidCompressedBaseLevelForWebGL(width, formatInfo.compressedBlockWidth, level) || | ||
+ !ValidCompressedBaseLevelForWebGL(height, formatInfo.compressedBlockHeight, | ||
+ level) || | ||
+ !ValidCompressedBaseLevelForWebGL(depth, formatInfo.compressedBlockDepth, level)) | ||
+ { | ||
+ return false; | ||
+ } | ||
+ } | ||
+ else | ||
+ { | ||
+ if (!ValidCompressedDimension(width, formatInfo.compressedBlockWidth, level) || | ||
+ !ValidCompressedDimension(height, formatInfo.compressedBlockHeight, level) || | ||
+ !ValidCompressedDimension(depth, formatInfo.compressedBlockDepth, level)) | ||
+ { | ||
+ return false; | ||
+ } | ||
} | ||
} | ||
|
||
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp | ||
index 40c9a02e3eafe9d437e20e72a391bad73c783516..fabaefbe33c94a048ec7c974951ac9ef886826ef 100644 | ||
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp | ||
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp | ||
@@ -296,6 +296,16 @@ void main() | ||
GLsizei blockSize, | ||
const std::string &extName, | ||
bool subImageAllowed); | ||
+ | ||
+ GLint expectedByteLength(GLenum format, GLsizei width, GLsizei height); | ||
+ void testCompressedTexLevelDimension(GLenum format, | ||
+ GLint level, | ||
+ GLsizei width, | ||
+ GLsizei height, | ||
+ GLsizei expectedByteLength, | ||
+ GLenum expectedError, | ||
+ const char *explanation); | ||
+ void testCompressedTexImage(GLenum format); | ||
}; | ||
|
||
class WebGL2CompatibilityTest : public WebGLCompatibilityTest | ||
@@ -3040,6 +3050,84 @@ TEST_P(WebGLCompatibilityTest, CompressedTextureS3TC) | ||
ASSERT_GL_ERROR(GL_INVALID_OPERATION); | ||
} | ||
|
||
+// Test WebGL-specific constraints on sizes of S3TC textures' mipmap levels. | ||
+TEST_P(WebGLCompatibilityTest, CompressedTexImageS3TC) | ||
+{ | ||
+ const char *extensions[] = { | ||
+ "GL_EXT_texture_compression_dxt1", | ||
+ "GL_ANGLE_texture_compression_dxt3", | ||
+ "GL_ANGLE_texture_compression_dxt5", | ||
+ }; | ||
+ | ||
+ for (const char *extension : extensions) | ||
+ { | ||
+ if (IsGLExtensionRequestable(extension)) | ||
+ { | ||
+ glRequestExtensionANGLE(extension); | ||
+ } | ||
+ | ||
+ ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(extension)); | ||
+ } | ||
+ | ||
+ // Ported from WebGL conformance suite: | ||
+ // sdk/tests/conformance/extensions/s3tc-and-srgb.html | ||
+ constexpr GLenum formats[] = { | ||
+ GL_COMPRESSED_RGB_S3TC_DXT1_EXT, | ||
+ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, | ||
+ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, | ||
+ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, | ||
+ }; | ||
+ | ||
+ for (GLenum format : formats) | ||
+ { | ||
+ testCompressedTexImage(format); | ||
+ } | ||
+} | ||
+ | ||
+// Test WebGL-specific constraints on sizes of RGTC textures' mipmap levels. | ||
+TEST_P(WebGLCompatibilityTest, CompressedTexImageRGTC) | ||
+{ | ||
+ if (IsGLExtensionRequestable("GL_EXT_texture_compression_rgtc")) | ||
+ { | ||
+ glRequestExtensionANGLE("GL_EXT_texture_compression_rgtc"); | ||
+ } | ||
+ | ||
+ ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_rgtc")); | ||
+ | ||
+ // Ported from WebGL conformance suite: | ||
+ // sdk/tests/conformance/extensions/ext-texture-compression-rgtc.html | ||
+ constexpr GLenum formats[] = {GL_COMPRESSED_RED_RGTC1_EXT, GL_COMPRESSED_SIGNED_RED_RGTC1_EXT, | ||
+ GL_COMPRESSED_RED_GREEN_RGTC2_EXT, | ||
+ GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT}; | ||
+ | ||
+ for (GLenum format : formats) | ||
+ { | ||
+ testCompressedTexImage(format); | ||
+ } | ||
+} | ||
+ | ||
+// Test WebGL-specific constraints on sizes of BPTC textures' mipmap levels. | ||
+TEST_P(WebGLCompatibilityTest, CompressedTexImageBPTC) | ||
+{ | ||
+ if (IsGLExtensionRequestable("GL_EXT_texture_compression_bptc")) | ||
+ { | ||
+ glRequestExtensionANGLE("GL_EXT_texture_compression_bptc"); | ||
+ } | ||
+ | ||
+ ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc")); | ||
+ | ||
+ // Ported from WebGL conformance suite: | ||
+ // sdk/tests/conformance/extensions/ext-texture-compression-bptc.html | ||
+ constexpr GLenum formats[] = { | ||
+ GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT, | ||
+ GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT}; | ||
+ | ||
+ for (GLenum format : formats) | ||
+ { | ||
+ testCompressedTexImage(format); | ||
+ } | ||
+} | ||
+ | ||
TEST_P(WebGLCompatibilityTest, L32FTextures) | ||
{ | ||
constexpr float textureData[] = {15.1f, 0.0f, 0.0f, 0.0f}; | ||
@@ -4937,6 +5025,119 @@ void WebGLCompatibilityTest::validateCompressedTexImageExtensionFormat(GLenum fo | ||
} | ||
} | ||
|
||
+GLint WebGLCompatibilityTest::expectedByteLength(GLenum format, GLsizei width, GLsizei height) | ||
+{ | ||
+ switch (format) | ||
+ { | ||
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: | ||
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: | ||
+ case GL_COMPRESSED_RED_RGTC1_EXT: | ||
+ case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT: | ||
+ return ((width + 3) / 4) * ((height + 3) / 4) * 8; | ||
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: | ||
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: | ||
+ case GL_COMPRESSED_RED_GREEN_RGTC2_EXT: | ||
+ case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: | ||
+ case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT: | ||
+ case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT: | ||
+ case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT: | ||
+ case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: | ||
+ return ((width + 3) / 4) * ((height + 3) / 4) * 16; | ||
+ } | ||
+ | ||
+ UNREACHABLE(); | ||
+ return 0; | ||
+} | ||
+ | ||
+void WebGLCompatibilityTest::testCompressedTexLevelDimension(GLenum format, | ||
+ GLint level, | ||
+ GLsizei width, | ||
+ GLsizei height, | ||
+ GLsizei expectedByteLength, | ||
+ GLenum expectedError, | ||
+ const char *explanation) | ||
+{ | ||
+ std::vector<uint8_t> tempVector(expectedByteLength, 0); | ||
+ | ||
+ EXPECT_GL_NO_ERROR(); | ||
+ | ||
+ GLTexture sourceTexture; | ||
+ glBindTexture(GL_TEXTURE_2D, sourceTexture); | ||
+ glCompressedTexImage2D(GL_TEXTURE_2D, level, format, width, height, 0, expectedByteLength, | ||
+ tempVector.data()); | ||
+ if (expectedError == 0) | ||
+ { | ||
+ EXPECT_GL_NO_ERROR() << explanation; | ||
+ } | ||
+ else | ||
+ { | ||
+ EXPECT_GL_ERROR(expectedError) << explanation; | ||
+ } | ||
+} | ||
+ | ||
+void WebGLCompatibilityTest::testCompressedTexImage(GLenum format) | ||
+{ | ||
+ struct TestCase | ||
+ { | ||
+ GLint level; | ||
+ GLsizei width; | ||
+ GLsizei height; | ||
+ GLenum expectedError; | ||
+ const char *explanation; | ||
+ }; | ||
+ | ||
+ constexpr TestCase testCases[] = { | ||
+ {0, 4, 3, GL_INVALID_OPERATION, "level is 0, height is not a multiple of 4"}, | ||
+ {0, 3, 4, GL_INVALID_OPERATION, "level is 0, width is not a multiple of 4"}, | ||
+ {0, 2, 2, GL_INVALID_OPERATION, "level is 0, width is not a multiple of 4"}, | ||
+ {0, 4, 4, GL_NO_ERROR, "is valid"}, | ||
+ {1, 1, 1, GL_INVALID_OPERATION, "implied base mip 2x2 is invalid"}, | ||
+ {1, 1, 2, GL_INVALID_OPERATION, "implied base mip 2x4 is invalid"}, | ||
+ {1, 2, 1, GL_INVALID_OPERATION, "implied base mip 4x2 is invalid"}, | ||
+ {1, 2, 2, GL_NO_ERROR, "implied base mip 4x4 is valid"}, | ||
+ }; | ||
+ | ||
+ constexpr TestCase webgl2TestCases[] = { | ||
+ {0, 0, 0, GL_NO_ERROR, "0: 0x0 is valid"}, | ||
+ {0, 1, 1, GL_INVALID_OPERATION, "0: 1x1 is invalid"}, | ||
+ {0, 2, 2, GL_INVALID_OPERATION, "0: 2x2 is invalid"}, | ||
+ {0, 3, 3, GL_INVALID_OPERATION, "0: 3x3 is invalid"}, | ||
+ {0, 10, 10, GL_INVALID_OPERATION, "0: 10x10 is invalid"}, | ||
+ {0, 11, 11, GL_INVALID_OPERATION, "0: 11x11 is invalid"}, | ||
+ {0, 11, 12, GL_INVALID_OPERATION, "0: 11x12 is invalid"}, | ||
+ {0, 12, 11, GL_INVALID_OPERATION, "0: 12x11 is invalid"}, | ||
+ {0, 12, 12, GL_NO_ERROR, "0: 12x12 is valid"}, | ||
+ {1, 0, 0, GL_NO_ERROR, "1: 0x0 is valid"}, | ||
+ {1, 3, 3, GL_INVALID_OPERATION, "1: 3x3 is invalid"}, | ||
+ {1, 5, 5, GL_INVALID_OPERATION, "1: 5x5 is invalid"}, | ||
+ {1, 5, 6, GL_INVALID_OPERATION, "1: 5x6 is invalid"}, | ||
+ {1, 6, 5, GL_INVALID_OPERATION, "1: 6x5 is invalid"}, | ||
+ {1, 6, 6, GL_NO_ERROR, "1: 6x6 is valid"}, | ||
+ {2, 0, 0, GL_NO_ERROR, "2: 0x0 is valid"}, | ||
+ {2, 3, 3, GL_NO_ERROR, "2: 3x3 is valid"}, | ||
+ {3, 1, 3, GL_NO_ERROR, "3: 1x3 is valid"}, | ||
+ {3, 1, 1, GL_NO_ERROR, "3: 1x1 is valid"}, | ||
+ {2, 1, 3, GL_NO_ERROR, "implied base mip 4x12 is valid"}, | ||
+ }; | ||
+ | ||
+ for (const TestCase &test : testCases) | ||
+ { | ||
+ testCompressedTexLevelDimension(format, test.level, test.width, test.height, | ||
+ expectedByteLength(format, test.width, test.height), | ||
+ test.expectedError, test.explanation); | ||
+ } | ||
+ | ||
+ if (getClientMajorVersion() >= 3) | ||
+ { | ||
+ for (const TestCase &test : webgl2TestCases) | ||
+ { | ||
+ testCompressedTexLevelDimension(format, test.level, test.width, test.height, | ||
+ expectedByteLength(format, test.width, test.height), | ||
+ test.expectedError, test.explanation); | ||
+ } | ||
+ } | ||
+} | ||
+ | ||
// Test enabling GL_EXT_texture_compression_dxt1 for GL_COMPRESSED_RGB_S3TC_DXT1_EXT | ||
TEST_P(WebGLCompatibilityTest, EnableCompressedTextureExtensionDXT1RGB) | ||
{ |
Oops, something went wrong.