diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.cpp b/src/libANGLE/renderer/vulkan/vk_helpers.cpp index d4930407b1..01ec20ac96 100644 --- a/src/libANGLE/renderer/vulkan/vk_helpers.cpp +++ b/src/libANGLE/renderer/vulkan/vk_helpers.cpp @@ -10717,6 +10717,15 @@ void ImageHelper::pruneSupersededUpdatesForLevelImpl(ContextVk *contextVk, const gl::LevelIndex level, const gl::Box &upcomingUpdateBoundingBox) { + // The bounding box of a Clear update is derived from |mLayerCount| and |mExtents|, which are + // not known until the image is created. Defer pruning so such updates are not dropped based + // on an incorrectly sized box; they will be revisited from removeSupersededUpdates() once the + // image is valid. + if (!valid()) + { + return; + } + SubresourceUpdates *levelUpdates = getLevelUpdates(level); if (levelUpdates == nullptr || levelUpdates->size() == 0) { diff --git a/src/tests/gl_tests/RobustResourceInitTest.cpp b/src/tests/gl_tests/RobustResourceInitTest.cpp index 5c54ef1888..646a926464 100644 --- a/src/tests/gl_tests/RobustResourceInitTest.cpp +++ b/src/tests/gl_tests/RobustResourceInitTest.cpp @@ -2744,6 +2744,43 @@ TEST_P(RobustResourceInitTestES3, Texture2DArrayPartiallyCleared) ASSERT_GL_NO_ERROR(); } +// Test that a large upload to a single layer of a 2D array texture defined with TexImage3D does +// not interfere with robust initialization of the remaining layers. +TEST_P(RobustResourceInitTestES3, Texture2DArrayLargeSingleLayerSubImage) +{ + ANGLE_SKIP_TEST_IF(!hasGLExtension()); + + constexpr int kSize = 2048; + constexpr int kLayers = 4; + + GLTexture texture; + glBindTexture(GL_TEXTURE_2D_ARRAY, texture); + glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, kSize, kSize, kLayers, 0, GL_RGBA, + GL_UNSIGNED_BYTE, nullptr); + + // Fully overwrite layer 0 only. The upload is large enough that the backend may try to drop + // earlier staged updates that it believes are now redundant. + std::vector data(kSize * kSize, GLColor::red); + glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kSize, kSize, 1, GL_RGBA, GL_UNSIGNED_BYTE, + data.data()); + ASSERT_GL_NO_ERROR(); + + GLFramebuffer framebuffer; + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, 0); + EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); + EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, GLColor::red); + + for (int layer = 1; layer < kLayers; ++layer) + { + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, layer); + EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); + EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, GLColor::transparentBlack); + } + ASSERT_GL_NO_ERROR(); +} + // Test that using TexStorage2D followed by CompressedSubImage works with robust init. // Taken from WebGL test conformance/extensions/webgl-compressed-texture-s3tc. TEST_P(RobustResourceInitTestES3, CompressedSubImage) @@ -3615,7 +3652,8 @@ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RobustResourceInitTestES3); ANGLE_INSTANTIATE_TEST_ES3_AND(RobustResourceInitTestES3, ES3_METAL().enable(Feature::EmulateDontCareLoadWithRandomClear), ES3_METAL().enable(Feature::AllocateNonZeroTextures), - ES3_VULKAN().enable(Feature::AllocateNonZeroMemory)); + ES3_VULKAN().enable(Feature::AllocateNonZeroMemory), + ES3_VULKAN_SWIFTSHADER().enable(Feature::AllocateNonZeroMemory)); GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RobustResourceInitTestES31); ANGLE_INSTANTIATE_TEST_ES31_AND(RobustResourceInitTestES31,