Vulkan: Support recreating swapchain with SwapChain.Configure()

This patch adds the support of recreating a swapchain with SwapChain.
Configure() on Vulkan backends.
1. Query the Vulkan surface information again.
2. Clean up old swapchain.

BUG=dawn:177

Change-Id: Id7e9e07e9dbbba4a71322367cae10fb179106220
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/9340
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
diff --git a/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp b/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp
index 0b037db..264ad32 100644
--- a/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp
+++ b/src/dawn_native/vulkan/NativeSwapChainImplVk.cpp
@@ -57,7 +57,7 @@
         }
     }
 
-    void NativeSwapChainImpl::Init(DawnWSIContextVulkan* /*context*/) {
+    void NativeSwapChainImpl::UpdateSurfaceConfig() {
         if (mDevice->ConsumedError(
                 GatherSurfaceInfo(*ToBackend(mDevice->GetAdapter()), mSurface, &mInfo))) {
             ASSERT(false);
@@ -68,10 +68,16 @@
         }
     }
 
+    void NativeSwapChainImpl::Init(DawnWSIContextVulkan* /*context*/) {
+        UpdateSurfaceConfig();
+    }
+
     DawnSwapChainError NativeSwapChainImpl::Configure(DawnTextureFormat format,
                                                       DawnTextureUsageBit usage,
                                                       uint32_t width,
                                                       uint32_t height) {
+        UpdateSurfaceConfig();
+
         ASSERT(mInfo.capabilities.minImageExtent.width <= width);
         ASSERT(mInfo.capabilities.maxImageExtent.width >= width);
         ASSERT(mInfo.capabilities.minImageExtent.height <= height);
@@ -81,6 +87,7 @@
         // TODO(cwallez@chromium.org): need to check usage works too
 
         // Create the swapchain with the configuration we chose
+        VkSwapchainKHR oldSwapchain = mSwapChain;
         VkSwapchainCreateInfoKHR createInfo;
         createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
         createInfo.pNext = nullptr;
@@ -101,7 +108,7 @@
         createInfo.compositeAlpha = mConfig.compositeAlpha;
         createInfo.presentMode = mConfig.presentMode;
         createInfo.clipped = false;
-        createInfo.oldSwapchain = VK_NULL_HANDLE;
+        createInfo.oldSwapchain = oldSwapchain;
 
         if (mDevice->fn.CreateSwapchainKHR(mDevice->GetVkDevice(), &createInfo, nullptr,
                                            &mSwapChain) != VK_SUCCESS) {
@@ -148,6 +155,10 @@
                                            nullptr, 1, &barrier);
         }
 
+        if (oldSwapchain != VK_NULL_HANDLE) {
+            mDevice->GetFencedDeleter()->DeleteWhenUnused(oldSwapchain);
+        }
+
         return DAWN_SWAP_CHAIN_NO_ERROR;
     }
 
diff --git a/src/dawn_native/vulkan/NativeSwapChainImplVk.h b/src/dawn_native/vulkan/NativeSwapChainImplVk.h
index f5dc27d..1b897848 100644
--- a/src/dawn_native/vulkan/NativeSwapChainImplVk.h
+++ b/src/dawn_native/vulkan/NativeSwapChainImplVk.h
@@ -52,6 +52,8 @@
         };
 
       private:
+        void UpdateSurfaceConfig();
+
         VkSurfaceKHR mSurface = VK_NULL_HANDLE;
         VkSwapchainKHR mSwapChain = VK_NULL_HANDLE;
         std::vector<VkImage> mSwapChainImages;