diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.cpp b/src/libANGLE/renderer/vulkan/vk_helpers.cpp index 1429619383..5523127392 100644 --- a/src/libANGLE/renderer/vulkan/vk_helpers.cpp +++ b/src/libANGLE/renderer/vulkan/vk_helpers.cpp @@ -9818,7 +9818,22 @@ void ImageHelper::stageSelfAsSubresourceUpdates( << mFirstAllocatedLevel.get()); const gl::TexLevelMask skipLevelsAllFaces = AggregateSkipLevels(skipLevels); - if ((~skipLevelsAllFaces & levelsMask).none()) + // For cube maps, a level can only be skipped entirely if *every* face of + // that level is being redefined. AggregateSkipLevels() OR-aggregates the + // per-face masks, which is correct for "is any face of this level + // redefined?" but wrong for "can the whole level be dropped?". Using the + // OR-aggregated mask here would silently discard the non-redefined faces' + // pixel data when the VkImage is released by the caller. Use the + // intersection (AND) of the per-face masks for the early-return test. + gl::TexLevelMask skipLevelsEveryFace = skipLevels[0]; + if (textureType == gl::TextureType::CubeMap) + { + for (size_t face = 1; face < gl::kCubeFaceCount; ++face) + { + skipLevelsEveryFace &= skipLevels[face]; + } + } + if ((~skipLevelsEveryFace & levelsMask).none()) { return; }