TextureVk: Don't transition to UNDEFINED in queue transitions.

When an imported texture with layout UNDEFINED was never used and then
exported with target layout UNDEFINED, Dawn would create a queue
transition barrier with dstLayout UNDEFINED which is not allowed by the
Vulkan specification. Instead detect this case and transition to
GENERAL.

Found by running dawn_end2end_tests with the VLL.

Bug: chromium:1258986
Change-Id: I5e36efda35cb27cecc0683846a314783a8a72fe6
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/103025
Reviewed-by: Austin Eng <enga@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Loko Kung <lokokung@google.com>
This commit is contained in:
Corentin Wallez 2022-10-03 17:12:12 +00:00 committed by Dawn LUCI CQ
parent 5f9996dc9c
commit 4d96762781
1 changed files with 23 additions and 11 deletions

View File

@ -884,26 +884,38 @@ MaybeError Texture::ExportExternalTexture(VkImageLayout desiredLayout,
ASSERT(GetNumMipLevels() == 1 && GetArrayLayers() == 1);
wgpu::TextureUsage usage = mSubresourceLastUsages.Get(GetDisjointVulkanAspects(), 0, 0);
VkImageLayout layout = VulkanImageLayout(this, usage);
// Compute the layouts for the queue transition for export. desiredLayout == UNDEFINED is a tag
// value used to export with whatever the current layout is. However queue transitioning to the
// UNDEFINED layout is disallowed so we handle the case where currentLayout is UNDEFINED by
// 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) {
targetLayout = currentLayout;
} else {
targetLayout = VK_IMAGE_LAYOUT_GENERAL;
}
// Write out the layouts and signal semaphore
*releasedOldLayout = layout;
*releasedNewLayout = (desiredLayout == VK_IMAGE_LAYOUT_UNDEFINED ? layout : desiredLayout);
mDesiredExportLayout = desiredLayout;
// We have to manually trigger a transition if the texture hasn't been actually used, or the
// desired layout is not VK_IMAGE_LAYOUT_UNDEFINED.
// We have to manually trigger a transition if the texture hasn't been actually used or if we
// need a layout transition.
// TODO(dawn:1509): Avoid the empty submit.
if (mExternalSemaphoreHandle == kNullExternalSemaphoreHandle ||
desiredLayout != VK_IMAGE_LAYOUT_UNDEFINED) {
if (mExternalSemaphoreHandle == kNullExternalSemaphoreHandle || targetLayout != currentLayout) {
mDesiredExportLayout = targetLayout;
Device* device = ToBackend(GetDevice());
CommandRecordingContext* recordingContext = device->GetPendingRecordingContext();
recordingContext->externalTexturesForEagerTransition.insert(this);
DAWN_TRY(device->SubmitPendingCommands());
currentLayout = targetLayout;
}
ASSERT(mExternalSemaphoreHandle != kNullExternalSemaphoreHandle);
// Write out the layouts and signal semaphore
*releasedOldLayout = currentLayout;
*releasedNewLayout = targetLayout;
*handle = mExternalSemaphoreHandle;
mExternalSemaphoreHandle = kNullExternalSemaphoreHandle;