-
Notifications
You must be signed in to change notification settings - Fork 15k
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 (#30624)
* chore: cherry-pick fix for 1234829 from angle * chore: update patches Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
- Loading branch information
1 parent
cdf0387
commit c7d61b6
Showing
3 changed files
with
392 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 |
---|---|---|
@@ -1,2 +1,4 @@ | ||
d3d11_skip_blits_if_there_is_no_intersection_of_dest_areas.patch | ||
cherry-pick-3d4f87ab5b9b.patch | ||
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 1d93a066580818c7616fa66252e6465f6137aceb..3935c52a894c5584eef66bea34a8684176909358 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 68fd9f7165ff237ed3c86a42be0b2a24dd9819c7..6c65740cb406e1c598dc41ff0e8998230a926883 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 89eb4d639a3853636524ad112a24f15d46fa1119..b9380bb10ad434acfc858c08db8a629db0bfaecf 100644 | ||
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp | ||
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp | ||
@@ -5023,6 +5023,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 74acb9e0c4d87c08478dd334a1b38124fab9f94f..4ed0ea4f47c89090d06f706199d32bb0f5b745b9 100644 | ||
--- a/src/libANGLE/validationES.cpp | ||
+++ b/src/libANGLE/validationES.cpp | ||
@@ -985,6 +985,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, | ||
@@ -1005,11 +1014,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 bfa8f3066fa418c87477dd553e66a34b79974455..89eb4d639a3853636524ad112a24f15d46fa1119 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 | ||
@@ -3056,6 +3066,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}; | ||
@@ -4887,6 +4975,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) | ||
{ |