vulkan: Validate that exporting a texture uses VK_IMAGE_LAYOUT_UNDEFINED

Using any other desiredLayout is deprecated. This simplifies future
changes which as much as possible eliminate any transitions during
texture export.

Bug: chromium:1359106
Change-Id: Ifb5818775e8f15ec77a229d3cbf593348740da46
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/104543
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Austin Eng <enga@chromium.org>
diff --git a/include/dawn/native/VulkanBackend.h b/include/dawn/native/VulkanBackend.h
index 8fb8a71..68767b8 100644
--- a/include/dawn/native/VulkanBackend.h
+++ b/include/dawn/native/VulkanBackend.h
@@ -174,6 +174,8 @@
 DAWN_NATIVE_EXPORT bool ExportVulkanImage(WGPUTexture texture,
                                           VkImageLayout desiredLayout,
                                           ExternalImageExportInfoVk* info);
+// |ExportVulkanImage| with default desiredLayout of VK_IMAGE_LAYOUT_UNDEFINED.
+DAWN_NATIVE_EXPORT bool ExportVulkanImage(WGPUTexture texture, ExternalImageExportInfoVk* info);
 
 }  // namespace dawn::native::vulkan
 
diff --git a/src/dawn/native/vulkan/TextureVk.cpp b/src/dawn/native/vulkan/TextureVk.cpp
index 3725e19..89e036b 100644
--- a/src/dawn/native/vulkan/TextureVk.cpp
+++ b/src/dawn/native/vulkan/TextureVk.cpp
@@ -882,6 +882,9 @@
                     "Can't export a signal semaphore from destroyed or non-external texture %s.",
                     this);
 
+    DAWN_INVALID_IF(desiredLayout != VK_IMAGE_LAYOUT_UNDEFINED,
+                    "desiredLayout (%d) was not VK_IMAGE_LAYOUT_UNDEFINED", desiredLayout);
+
     // Release the texture
     mExternalState = ExternalState::Released;
 
@@ -894,9 +897,7 @@
     // promoting to GENERAL.
     VkImageLayout currentLayout = VulkanImageLayout(this, usage);
     VkImageLayout targetLayout;
-    if (desiredLayout != VK_IMAGE_LAYOUT_UNDEFINED) {
-        targetLayout = desiredLayout;
-    } else if (currentLayout != VK_IMAGE_LAYOUT_UNDEFINED) {
+    if (currentLayout != VK_IMAGE_LAYOUT_UNDEFINED) {
         targetLayout = currentLayout;
     } else {
         targetLayout = VK_IMAGE_LAYOUT_GENERAL;
diff --git a/src/dawn/native/vulkan/VulkanBackend.cpp b/src/dawn/native/vulkan/VulkanBackend.cpp
index f8f9401..f6788c5 100644
--- a/src/dawn/native/vulkan/VulkanBackend.cpp
+++ b/src/dawn/native/vulkan/VulkanBackend.cpp
@@ -136,4 +136,8 @@
 #endif  // DAWN_PLATFORM_IS(LINUX)
 }
 
+bool ExportVulkanImage(WGPUTexture texture, ExternalImageExportInfoVk* info) {
+    return ExportVulkanImage(texture, VK_IMAGE_LAYOUT_UNDEFINED, info);
+}
+
 }  // namespace dawn::native::vulkan
diff --git a/src/dawn/tests/end2end/VideoViewsTests_gbm.cpp b/src/dawn/tests/end2end/VideoViewsTests_gbm.cpp
index a7d64eb..d9adb4f 100644
--- a/src/dawn/tests/end2end/VideoViewsTests_gbm.cpp
+++ b/src/dawn/tests/end2end/VideoViewsTests_gbm.cpp
@@ -204,7 +204,7 @@
         // Exports the signal and ignores it.
         dawn::native::vulkan::ExternalImageExportInfoDmaBuf exportInfo;
         dawn::native::vulkan::ExportVulkanImage(platformTexture->wgpuTexture.Get(),
-                                                VK_IMAGE_LAYOUT_GENERAL, &exportInfo);
+                                                VK_IMAGE_LAYOUT_UNDEFINED, &exportInfo);
         for (int fd : exportInfo.semaphoreHandles) {
             ASSERT_NE(fd, -1);
             close(fd);
diff --git a/src/dawn/tests/white_box/VulkanImageWrappingTests.cpp b/src/dawn/tests/white_box/VulkanImageWrappingTests.cpp
index f98c6cb..ee7e132 100644
--- a/src/dawn/tests/white_box/VulkanImageWrappingTests.cpp
+++ b/src/dawn/tests/white_box/VulkanImageWrappingTests.cpp
@@ -134,7 +134,7 @@
     // assertion failure
     void IgnoreSignalSemaphore(wgpu::Texture wrappedTexture) {
         ExternalImageExportInfoVkForTesting exportInfo;
-        bool result = mBackend->ExportImage(wrappedTexture, VK_IMAGE_LAYOUT_UNDEFINED, &exportInfo);
+        bool result = mBackend->ExportImage(wrappedTexture, &exportInfo);
         ASSERT(result);
     }
 
@@ -225,8 +225,7 @@
     IgnoreSignalSemaphore(texture);
 
     ExternalImageExportInfoVkForTesting exportInfo;
-    ASSERT_DEVICE_ERROR(bool success =
-                            mBackend->ExportImage(texture, VK_IMAGE_LAYOUT_UNDEFINED, &exportInfo));
+    ASSERT_DEVICE_ERROR(bool success = mBackend->ExportImage(texture, &exportInfo));
     ASSERT_FALSE(success);
     ASSERT_EQ(exportInfo.semaphores.size(), 0u);
 }
@@ -237,21 +236,20 @@
     ASSERT_NE(texture.Get(), nullptr);
 
     ExternalImageExportInfoVkForTesting exportInfo;
-    ASSERT_DEVICE_ERROR(bool success =
-                            mBackend->ExportImage(texture, VK_IMAGE_LAYOUT_UNDEFINED, &exportInfo));
+    ASSERT_DEVICE_ERROR(bool success = mBackend->ExportImage(texture, &exportInfo));
     ASSERT_FALSE(success);
     ASSERT_EQ(exportInfo.semaphores.size(), 0u);
 }
 
 // Test an error occurs if we try to export the signal semaphore from a destroyed texture
 TEST_P(VulkanImageWrappingValidationTests, DestroyedTextureSignalSemaphoreExport) {
-    wgpu::Texture texture = device.CreateTexture(&defaultDescriptor);
+    wgpu::Texture texture =
+        WrapVulkanImage(device, &defaultDescriptor, defaultTexture.get(), {}, true, true);
     ASSERT_NE(texture.Get(), nullptr);
     texture.Destroy();
 
     ExternalImageExportInfoVkForTesting exportInfo;
-    ASSERT_DEVICE_ERROR(bool success =
-                            mBackend->ExportImage(texture, VK_IMAGE_LAYOUT_UNDEFINED, &exportInfo));
+    ASSERT_DEVICE_ERROR(bool success = mBackend->ExportImage(texture, &exportInfo));
     ASSERT_FALSE(success);
     ASSERT_EQ(exportInfo.semaphores.size(), 0u);
 }
@@ -337,8 +335,7 @@
     ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
 
     ExternalImageExportInfoVkForTesting exportInfo;
-    ASSERT_TRUE(
-        mBackend->ExportImage(wrappedTexture, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo));
+    ASSERT_TRUE(mBackend->ExportImage(wrappedTexture, &exportInfo));
 
     // Import the image to |device|, making sure we wait on signalFd
     wgpu::Texture nextWrappedTexture = WrapVulkanImage(
@@ -363,8 +360,7 @@
     ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
 
     ExternalImageExportInfoVkForTesting exportInfo;
-    ASSERT_TRUE(
-        mBackend->ExportImage(wrappedTexture, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo));
+    ASSERT_TRUE(mBackend->ExportImage(wrappedTexture, &exportInfo));
 
     // Import the image to |device|, making sure we wait on signalFd
     wgpu::Texture nextWrappedTexture = WrapVulkanImage(
@@ -391,8 +387,7 @@
     ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
 
     ExternalImageExportInfoVkForTesting exportInfo;
-    ASSERT_TRUE(
-        mBackend->ExportImage(wrappedTexture, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo));
+    ASSERT_TRUE(mBackend->ExportImage(wrappedTexture, &exportInfo));
 
     // Import the image to |device|, making sure we wait on |signalFd|
     wgpu::Texture deviceWrappedTexture = WrapVulkanImage(
@@ -430,8 +425,7 @@
     ClearImage(device, wrappedTexture, {5 / 255.0f, 6 / 255.0f, 7 / 255.0f, 8 / 255.0f});
 
     ExternalImageExportInfoVkForTesting exportInfo;
-    ASSERT_TRUE(
-        mBackend->ExportImage(wrappedTexture, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &exportInfo));
+    ASSERT_TRUE(mBackend->ExportImage(wrappedTexture, &exportInfo));
 
     // Import the image to |secondDevice|, making sure we wait on |signalFd|
     wgpu::Texture secondDeviceWrappedTexture = WrapVulkanImage(
@@ -449,8 +443,7 @@
 
     // Re-import back into |device|, waiting on |secondDevice|'s signal
     ExternalImageExportInfoVkForTesting secondExportInfo;
-    ASSERT_TRUE(mBackend->ExportImage(secondDeviceWrappedTexture,
-                                      VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &secondExportInfo));
+    ASSERT_TRUE(mBackend->ExportImage(secondDeviceWrappedTexture, &secondExportInfo));
 
     wgpu::Texture nextWrappedTexture = WrapVulkanImage(
         device, &defaultDescriptor, defaultTexture.get(), std::move(secondExportInfo.semaphores),
@@ -476,8 +469,7 @@
     ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
 
     ExternalImageExportInfoVkForTesting exportInfo;
-    ASSERT_TRUE(
-        mBackend->ExportImage(wrappedTexture, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo));
+    ASSERT_TRUE(mBackend->ExportImage(wrappedTexture, &exportInfo));
 
     // Import the image to |device|, making sure we wait on |signalFd|
     wgpu::Texture deviceWrappedTexture = WrapVulkanImage(
@@ -527,8 +519,7 @@
     ClearImage(device, wrappedTexture, {5 / 255.0f, 6 / 255.0f, 7 / 255.0f, 8 / 255.0f});
 
     ExternalImageExportInfoVkForTesting exportInfo;
-    ASSERT_TRUE(
-        mBackend->ExportImage(wrappedTexture, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo));
+    ASSERT_TRUE(mBackend->ExportImage(wrappedTexture, &exportInfo));
 
     // Import the image to |secondDevice|, making sure we wait on |signalFd|
     wgpu::Texture secondDeviceWrappedTexture = WrapVulkanImage(
@@ -556,8 +547,7 @@
 
     // Re-import back into |device|, waiting on |secondDevice|'s signal
     ExternalImageExportInfoVkForTesting secondExportInfo;
-    ASSERT_TRUE(mBackend->ExportImage(secondDeviceWrappedTexture,
-                                      VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &secondExportInfo));
+    ASSERT_TRUE(mBackend->ExportImage(secondDeviceWrappedTexture, &secondExportInfo));
 
     wgpu::Texture nextWrappedTexture = WrapVulkanImage(
         device, &defaultDescriptor, defaultTexture.get(), std::move(secondExportInfo.semaphores),
@@ -584,8 +574,7 @@
     ClearImage(secondDevice, wrappedTexture, {1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f});
 
     ExternalImageExportInfoVkForTesting exportInfo;
-    ASSERT_TRUE(
-        mBackend->ExportImage(wrappedTexture, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo));
+    ASSERT_TRUE(mBackend->ExportImage(wrappedTexture, &exportInfo));
 
     // Import the image to |device|, making sure we wait on |signalFd|
     wgpu::Texture deviceWrappedTexture = WrapVulkanImage(
@@ -658,8 +647,7 @@
                                wrappedTexBDevice3);
 
     ExternalImageExportInfoVkForTesting exportInfoTexBDevice3;
-    ASSERT_TRUE(mBackend->ExportImage(wrappedTexBDevice3, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                      &exportInfoTexBDevice3));
+    ASSERT_TRUE(mBackend->ExportImage(wrappedTexBDevice3, &exportInfoTexBDevice3));
     IgnoreSignalSemaphore(wrappedTexADevice3);
 
     // Import TexB, TexC on device 2
@@ -677,8 +665,7 @@
                                wrappedTexCDevice2);
 
     ExternalImageExportInfoVkForTesting exportInfoTexCDevice2;
-    ASSERT_TRUE(mBackend->ExportImage(wrappedTexCDevice2, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                      &exportInfoTexCDevice2));
+    ASSERT_TRUE(mBackend->ExportImage(wrappedTexCDevice2, &exportInfoTexCDevice2));
     IgnoreSignalSemaphore(wrappedTexBDevice2);
 
     // Import TexC on device 1
@@ -760,8 +747,7 @@
         secondDeviceQueue.Submit(1, &commands);
     }
     ExternalImageExportInfoVkForTesting exportInfo;
-    ASSERT_TRUE(
-        mBackend->ExportImage(wrappedTexture, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &exportInfo));
+    ASSERT_TRUE(mBackend->ExportImage(wrappedTexture, &exportInfo));
 
     // Import the image on |device|
     wgpu::Texture nextWrappedTexture =
diff --git a/src/dawn/tests/white_box/VulkanImageWrappingTests.h b/src/dawn/tests/white_box/VulkanImageWrappingTests.h
index a430783..837d0c5 100644
--- a/src/dawn/tests/white_box/VulkanImageWrappingTests.h
+++ b/src/dawn/tests/white_box/VulkanImageWrappingTests.h
@@ -66,7 +66,6 @@
                                     std::vector<std::unique_ptr<ExternalSemaphore>> semaphores) = 0;
 
     virtual bool ExportImage(const wgpu::Texture& texture,
-                             VkImageLayout layout,
                              ExternalImageExportInfoVkForTesting* exportInfo) = 0;
 
   private:
diff --git a/src/dawn/tests/white_box/VulkanImageWrappingTests_DmaBuf.cpp b/src/dawn/tests/white_box/VulkanImageWrappingTests_DmaBuf.cpp
index d2be7ba..1373e1d 100644
--- a/src/dawn/tests/white_box/VulkanImageWrappingTests_DmaBuf.cpp
+++ b/src/dawn/tests/white_box/VulkanImageWrappingTests_DmaBuf.cpp
@@ -143,10 +143,9 @@
     }
 
     bool ExportImage(const wgpu::Texture& texture,
-                     VkImageLayout layout,
                      ExternalImageExportInfoVkForTesting* exportInfo) override {
         ExternalImageExportInfoDmaBuf infoDmaBuf;
-        bool success = ExportVulkanImage(texture.Get(), layout, &infoDmaBuf);
+        bool success = ExportVulkanImage(texture.Get(), VK_IMAGE_LAYOUT_UNDEFINED, &infoDmaBuf);
 
         *static_cast<ExternalImageExportInfoVk*>(exportInfo) = infoDmaBuf;
         for (int fd : infoDmaBuf.semaphoreHandles) {
diff --git a/src/dawn/tests/white_box/VulkanImageWrappingTests_OpaqueFD.cpp b/src/dawn/tests/white_box/VulkanImageWrappingTests_OpaqueFD.cpp
index 8944dee..a99e5c3 100644
--- a/src/dawn/tests/white_box/VulkanImageWrappingTests_OpaqueFD.cpp
+++ b/src/dawn/tests/white_box/VulkanImageWrappingTests_OpaqueFD.cpp
@@ -160,10 +160,9 @@
     }
 
     bool ExportImage(const wgpu::Texture& texture,
-                     VkImageLayout layout,
                      ExternalImageExportInfoVkForTesting* exportInfo) override {
         ExternalImageExportInfoOpaqueFD infoOpaqueFD;
-        bool success = ExportVulkanImage(texture.Get(), layout, &infoOpaqueFD);
+        bool success = ExportVulkanImage(texture.Get(), VK_IMAGE_LAYOUT_UNDEFINED, &infoOpaqueFD);
 
         *static_cast<ExternalImageExportInfoVk*>(exportInfo) = infoOpaqueFD;
         for (int fd : infoOpaqueFD.semaphoreHandles) {