Vulkan: Handle errors when wrapping external images
This also introduces another combinator to ConsumeError for
ResultOrError.
BUG=dawn:19
Change-Id: Ic204313436f5e919473d604efd049fe3d3c27a66
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/11862
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
diff --git a/src/dawn_native/Device.h b/src/dawn_native/Device.h
index 4ed2f629..85ca254 100644
--- a/src/dawn_native/Device.h
+++ b/src/dawn_native/Device.h
@@ -56,6 +56,16 @@
return false;
}
+ template <typename T>
+ bool ConsumedError(ResultOrError<T> resultOrError, T* result) {
+ if (DAWN_UNLIKELY(resultOrError.IsError())) {
+ ConsumeError(resultOrError.AcquireError());
+ return true;
+ }
+ *result = resultOrError.AcquireSuccess();
+ return false;
+ }
+
MaybeError ValidateObject(const ObjectBase* object) const;
AdapterBase* GetAdapter() const;
diff --git a/src/dawn_native/vulkan/DeviceVk.cpp b/src/dawn_native/vulkan/DeviceVk.cpp
index 7cbba72..f950661 100644
--- a/src/dawn_native/vulkan/DeviceVk.cpp
+++ b/src/dawn_native/vulkan/DeviceVk.cpp
@@ -672,9 +672,14 @@
std::vector<VkSemaphore> waitSemaphores;
waitSemaphores.reserve(waitHandles.size());
- // If failed, cleanup
+ // Cleanup in case of a failure, the image creation doesn't acquire the external objects
+ // if a failure happems.
+ Texture* result = nullptr;
if (ConsumedError(ImportExternalImage(descriptor, memoryHandle, waitHandles,
- &signalSemaphore, &allocation, &waitSemaphores))) {
+ &signalSemaphore, &allocation, &waitSemaphores)) ||
+ ConsumedError(Texture::CreateFromExternal(this, descriptor, textureDescriptor,
+ signalSemaphore, allocation, waitSemaphores),
+ &result)) {
// Clear the signal semaphore
fn.DestroySemaphore(GetVkDevice(), signalSemaphore, nullptr);
@@ -688,8 +693,7 @@
return nullptr;
}
- return new Texture(this, descriptor, textureDescriptor, signalSemaphore, allocation,
- waitSemaphores);
+ return result;
}
ResultOrError<ResourceMemoryAllocation> Device::AllocateMemory(
diff --git a/src/dawn_native/vulkan/TextureVk.cpp b/src/dawn_native/vulkan/TextureVk.cpp
index 5e90cf8..9ff1dd0 100644
--- a/src/dawn_native/vulkan/TextureVk.cpp
+++ b/src/dawn_native/vulkan/TextureVk.cpp
@@ -404,6 +404,20 @@
return texture.release();
}
+ // static
+ ResultOrError<Texture*> Texture::CreateFromExternal(Device* device,
+ const ExternalImageDescriptor* descriptor,
+ const TextureDescriptor* textureDescriptor,
+ VkSemaphore signalSemaphore,
+ VkDeviceMemory externalMemoryAllocation,
+ std::vector<VkSemaphore> waitSemaphores) {
+ std::unique_ptr<Texture> texture =
+ std::make_unique<Texture>(device, textureDescriptor, TextureState::OwnedInternal);
+ DAWN_TRY(texture->InitializeFromExternal(
+ descriptor, signalSemaphore, externalMemoryAllocation, std::move((waitSemaphores))));
+ return texture.release();
+ }
+
MaybeError Texture::InitializeAsInternalTexture() {
Device* device = ToBackend(GetDevice());
@@ -469,18 +483,14 @@
: TextureBase(device, descriptor, TextureState::OwnedExternal), mHandle(nativeImage) {
}
- // Internally managed, but imported from file descriptor
- Texture::Texture(Device* device,
- const ExternalImageDescriptor* descriptor,
- const TextureDescriptor* textureDescriptor,
- VkSemaphore signalSemaphore,
- VkDeviceMemory externalMemoryAllocation,
- std::vector<VkSemaphore> waitSemaphores)
- : TextureBase(device, textureDescriptor, TextureState::OwnedInternal),
- mExternalAllocation(externalMemoryAllocation),
- mExternalState(ExternalState::PendingAcquire),
- mSignalSemaphore(signalSemaphore),
- mWaitRequirements(std::move(waitSemaphores)) {
+ // Internally managed, but imported from external handle
+ MaybeError Texture::InitializeFromExternal(const ExternalImageDescriptor* descriptor,
+ VkSemaphore signalSemaphore,
+ VkDeviceMemory externalMemoryAllocation,
+ std::vector<VkSemaphore> waitSemaphores) {
+ mExternalState = ExternalState::PendingAcquire;
+ Device* device = ToBackend(GetDevice());
+
VkImageCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
createInfo.pNext = nullptr;
@@ -505,10 +515,9 @@
// also required for the implementation of robust resource initialization.
createInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
- if (device->fn.CreateImage(device->GetVkDevice(), &createInfo, nullptr, &mHandle) !=
- VK_SUCCESS) {
- ASSERT(false);
- }
+ DAWN_TRY(CheckVkSuccess(
+ device->fn.CreateImage(device->GetVkDevice(), &createInfo, nullptr, &mHandle),
+ "CreateImage"));
// Create the image memory and associate it with the container
VkMemoryRequirements requirements;
@@ -516,15 +525,21 @@
ASSERT(requirements.size <= descriptor->allocationSize);
- if (device->fn.BindImageMemory(device->GetVkDevice(), mHandle, mExternalAllocation, 0) !=
- VK_SUCCESS) {
- ASSERT(false);
- }
+ DAWN_TRY(CheckVkSuccess(
+ device->fn.BindImageMemory(device->GetVkDevice(), mHandle, externalMemoryAllocation, 0),
+ "BindImageMemory (external)"));
// Don't clear imported texture if already cleared
if (descriptor->isCleared) {
SetIsSubresourceContentInitialized(true, 0, 1, 0, 1);
}
+
+ // Success, acquire all the external objects.
+ mExternalAllocation = externalMemoryAllocation;
+ mSignalSemaphore = signalSemaphore;
+ mWaitRequirements = std::move(waitSemaphores);
+
+ return {};
}
MaybeError Texture::SignalAndDestroy(VkSemaphore* outSignalSemaphore) {
diff --git a/src/dawn_native/vulkan/TextureVk.h b/src/dawn_native/vulkan/TextureVk.h
index e32af0b..dd1d5f5 100644
--- a/src/dawn_native/vulkan/TextureVk.h
+++ b/src/dawn_native/vulkan/TextureVk.h
@@ -35,14 +35,21 @@
class Texture : public TextureBase {
public:
+ // Used to create a regular texture from a descriptor.
static ResultOrError<Texture*> Create(Device* device, const TextureDescriptor* descriptor);
+
+ // Used to create a texture from Vulkan external memory objects.
+ // Ownership of semaphores and the memory allocation is taken only if the creation is
+ // a success.
+ static ResultOrError<Texture*> CreateFromExternal(
+ Device* device,
+ const ExternalImageDescriptor* descriptor,
+ const TextureDescriptor* textureDescriptor,
+ VkSemaphore signalSemaphore,
+ VkDeviceMemory externalMemoryAllocation,
+ std::vector<VkSemaphore> waitSemaphores);
+
Texture(Device* device, const TextureDescriptor* descriptor, VkImage nativeImage);
- Texture(Device* device,
- const ExternalImageDescriptor* descriptor,
- const TextureDescriptor* textureDescriptor,
- VkSemaphore signalSemaphore,
- VkDeviceMemory externalMemoryAllocation,
- std::vector<VkSemaphore> waitSemaphores);
~Texture();
VkImage GetHandle() const;
@@ -64,6 +71,10 @@
private:
using TextureBase::TextureBase;
MaybeError InitializeAsInternalTexture();
+ MaybeError InitializeFromExternal(const ExternalImageDescriptor* descriptor,
+ VkSemaphore signalSemaphore,
+ VkDeviceMemory externalMemoryAllocation,
+ std::vector<VkSemaphore> waitSemaphores);
void DestroyImpl() override;
MaybeError ClearTexture(CommandRecordingContext* recordingContext,