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>
This commit is contained in:
Austin Eng 2022-10-04 17:27:21 +00:00 committed by Dawn LUCI CQ
parent 9ecc310210
commit 663932d741
8 changed files with 31 additions and 41 deletions

View File

@ -174,6 +174,8 @@ DAWN_NATIVE_EXPORT WGPUTexture WrapVulkanImage(WGPUDevice device,
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

View File

@ -882,6 +882,9 @@ MaybeError Texture::ExportExternalTexture(VkImageLayout desiredLayout,
"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 @@ MaybeError Texture::ExportExternalTexture(VkImageLayout desiredLayout,
// 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;

View File

@ -136,4 +136,8 @@ bool ExportVulkanImage(WGPUTexture texture,
#endif // DAWN_PLATFORM_IS(LINUX)
}
bool ExportVulkanImage(WGPUTexture texture, ExternalImageExportInfoVk* info) {
return ExportVulkanImage(texture, VK_IMAGE_LAYOUT_UNDEFINED, info);
}
} // namespace dawn::native::vulkan

View File

@ -204,7 +204,7 @@ class VideoViewsTestBackendGbm : public VideoViewsTestBackend {
// 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);

View File

@ -134,7 +134,7 @@ class VulkanImageWrappingTestBase : public DawnTestWithParams<ImageWrappingParam
// 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 @@ TEST_P(VulkanImageWrappingValidationTests, DoubleSignalSemaphoreExport) {
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 @@ TEST_P(VulkanImageWrappingValidationTests, NormalTextureSignalSemaphoreExport) {
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 @@ TEST_P(VulkanImageWrappingUsageTests, ClearImageAcrossDevices) {
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 @@ TEST_P(VulkanImageWrappingUsageTests, UninitializedTextureIsCleared) {
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 @@ TEST_P(VulkanImageWrappingUsageTests, CopyTextureToTextureSrcSync) {
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 @@ TEST_P(VulkanImageWrappingUsageTests, CopyTextureToTextureDstSync) {
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 @@ TEST_P(VulkanImageWrappingUsageTests, CopyTextureToTextureDstSync) {
// 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 @@ TEST_P(VulkanImageWrappingUsageTests, CopyTextureToBufferSrcSync) {
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 @@ TEST_P(VulkanImageWrappingUsageTests, CopyBufferToTextureDstSync) {
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 @@ TEST_P(VulkanImageWrappingUsageTests, CopyBufferToTextureDstSync) {
// 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 @@ TEST_P(VulkanImageWrappingUsageTests, DoubleTextureUsage) {
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 @@ TEST_P(VulkanImageWrappingUsageTests, ChainTextureCopy) {
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 @@ TEST_P(VulkanImageWrappingUsageTests, ChainTextureCopy) {
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 @@ TEST_P(VulkanImageWrappingUsageTests, LargerImage) {
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 =

View File

@ -66,7 +66,6 @@ class VulkanImageWrappingTestBackend {
std::vector<std::unique_ptr<ExternalSemaphore>> semaphores) = 0;
virtual bool ExportImage(const wgpu::Texture& texture,
VkImageLayout layout,
ExternalImageExportInfoVkForTesting* exportInfo) = 0;
private:

View File

@ -143,10 +143,9 @@ class VulkanImageWrappingTestBackendDmaBuf : public VulkanImageWrappingTestBacke
}
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) {

View File

@ -160,10 +160,9 @@ class VulkanImageWrappingTestBackendOpaqueFD : public VulkanImageWrappingTestBac
}
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) {