Commit 68c424fe by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Workaround oldSwapchin bug on Android

When vkCreateSwapchainKHR is called with a valid oldSwapchain, the Android framework destroys the images in oldSwapchain. This is not correct, as it should be deferred to the actual vkDestroySwapchainKHR call performed later by ANGLE. This is because rendering to the oldSwapchain could still be in progress. While this issue affects all of Android, currently only ARM shows any symptoms. A workaround is added for ARM to vkDeviceWaitIdle before recreating the swapchain if oldSwapchain is valid. Bug: angleproject:5061 Change-Id: I308e4798c6418d7891d880218b0ebcfd7a795643 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2416238Reviewed-by: 's avatarSunny Sun <sunny.sun@arm.com> Reviewed-by: 's avatarIan Elliott <ianelliott@google.com> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
parent 4043b9d1
...@@ -370,6 +370,14 @@ struct FeaturesVk : FeatureSetBase ...@@ -370,6 +370,14 @@ struct FeaturesVk : FeatureSetBase
"defer_flush_until_endrenderpass", FeatureCategory::VulkanWorkarounds, "defer_flush_until_endrenderpass", FeatureCategory::VulkanWorkarounds,
"Allow glFlush to be deferred until renderpass ends", &members, "Allow glFlush to be deferred until renderpass ends", &members,
"https://issuetracker.google.com/issues/166475273"}; "https://issuetracker.google.com/issues/166475273"};
// Android mistakenly destroys oldSwapchain passed to vkCreateSwapchainKHR, causing crashes on
// certain drivers. http://anglebug.com/5061
Feature waitIdleBeforeSwapchainRecreation = {
"wait_idle_before_swapchain_recreation", FeatureCategory::VulkanWorkarounds,
"Before passing an oldSwapchain to VkSwapchainCreateInfoKHR, wait for queue to be idle. "
"Works around a bug on platforms which destroy oldSwapchain in vkCreateSwapchainKHR.",
&members, "http://anglebug.com/5061"};
}; };
inline FeaturesVk::FeaturesVk() = default; inline FeaturesVk::FeaturesVk() = default;
......
...@@ -1868,6 +1868,9 @@ void RendererVk::initFeatures(DisplayVk *displayVk, const ExtensionNameList &dev ...@@ -1868,6 +1868,9 @@ void RendererVk::initFeatures(DisplayVk *displayVk, const ExtensionNameList &dev
ANGLE_FEATURE_CONDITION(&mFeatures, deferFlushUntilEndRenderPass, true); ANGLE_FEATURE_CONDITION(&mFeatures, deferFlushUntilEndRenderPass, true);
// Android mistakenly destroys the old swapchain when creating a new one.
ANGLE_FEATURE_CONDITION(&mFeatures, waitIdleBeforeSwapchainRecreation, IsAndroid() && isARM);
angle::PlatformMethods *platform = ANGLEPlatformCurrent(); angle::PlatformMethods *platform = ANGLEPlatformCurrent();
platform->overrideFeaturesVk(platform, &mFeatures); platform->overrideFeaturesVk(platform, &mFeatures);
......
...@@ -927,6 +927,13 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context, ...@@ -927,6 +927,13 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context,
swapchainInfo.clipped = VK_TRUE; swapchainInfo.clipped = VK_TRUE;
swapchainInfo.oldSwapchain = lastSwapchain; swapchainInfo.oldSwapchain = lastSwapchain;
// On Android, vkCreateSwapchainKHR destroys lastSwapchain, which is incorrect. Wait idle in
// that case as a workaround.
if (lastSwapchain && renderer->getFeatures().waitIdleBeforeSwapchainRecreation.enabled)
{
ANGLE_TRY(renderer->deviceWaitIdle(context));
}
// TODO(syoussefi): Once EGL_SWAP_BEHAVIOR_PRESERVED_BIT is supported, the contents of the old // TODO(syoussefi): Once EGL_SWAP_BEHAVIOR_PRESERVED_BIT is supported, the contents of the old
// swapchain need to carry over to the new one. http://anglebug.com/2942 // swapchain need to carry over to the new one. http://anglebug.com/2942
VkSwapchainKHR newSwapChain = VK_NULL_HANDLE; VkSwapchainKHR newSwapChain = VK_NULL_HANDLE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment