Pass the old/new VkImageLayouts to Vulkan image import/export

Returning the layouts from an export operation and then using
them in a subsequent import operation allows the import to preserve
the texture contents.

This fixes Vukan image wrapping on some AMD/NVIDIA devices.

Bug: dawn:200
Change-Id: Icbb6e759856d410bb69724b9f439bc3088756d19
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/28380
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
Austin Eng
2020-09-22 20:10:46 +00:00
committed by Commit Bot service account
parent 670858da9b
commit 0b29732cd8
19 changed files with 635 additions and 377 deletions

View File

@@ -33,19 +33,49 @@ namespace dawn_native { namespace vulkan {
DAWN_NATIVE_EXPORT WGPUTextureFormat
GetNativeSwapChainPreferredFormat(const DawnSwapChainImplementation* swapChain);
// Can't use DAWN_PLATFORM_LINUX since header included in both dawn and chrome
struct DAWN_NATIVE_EXPORT ExternalImageDescriptorVk : ExternalImageDescriptor {
public:
// The following members may be ignored if |ExternalImageDescriptor::isInitialized| is false
// since the import does not need to preserve texture contents.
// See https://www.khronos.org/registry/vulkan/specs/1.1/html/chap7.html. The acquire
// operation old/new layouts must match exactly the layouts in the release operation. So
// we may need to issue two barriers releasedOldLayout -> releasedNewLayout ->
// cTextureDescriptor.usage if the new layout is not compatible with the desired usage.
// The first barrier is the queue transfer, the second is the layout transition to our
// desired usage.
VkImageLayout releasedOldLayout = VK_IMAGE_LAYOUT_GENERAL;
VkImageLayout releasedNewLayout = VK_IMAGE_LAYOUT_GENERAL;
protected:
using ExternalImageDescriptor::ExternalImageDescriptor;
};
struct ExternalImageExportInfoVk : ExternalImageExportInfo {
public:
// See comments in |ExternalImageDescriptorVk|
// Contains the old/new layouts used in the queue release operation.
VkImageLayout releasedOldLayout;
VkImageLayout releasedNewLayout;
protected:
using ExternalImageExportInfo::ExternalImageExportInfo;
};
// Can't use DAWN_PLATFORM_LINUX since header included in both Dawn and Chrome
#ifdef __linux__
// Common properties of external images represented by FDs. On successful import the file
// descriptor's ownership is transferred to the Dawn implementation and they shouldn't be
// used outside of Dawn again. TODO(enga): Also transfer ownership in the error case so the
// caller can assume the FD is always consumed.
struct DAWN_NATIVE_EXPORT ExternalImageDescriptorFD : ExternalImageDescriptor {
struct DAWN_NATIVE_EXPORT ExternalImageDescriptorFD : ExternalImageDescriptorVk {
public:
int memoryFD; // A file descriptor from an export of the memory of the image
std::vector<int> waitFDs; // File descriptors of semaphores which will be waited on
protected:
ExternalImageDescriptorFD(ExternalImageDescriptorType type);
using ExternalImageDescriptorVk::ExternalImageDescriptorVk;
};
// Descriptor for opaque file descriptor image import
@@ -64,8 +94,29 @@ namespace dawn_native { namespace vulkan {
uint64_t drmModifier; // DRM modifier of the buffer
};
// Info struct that is written to in |ExportVulkanImage|.
struct DAWN_NATIVE_EXPORT ExternalImageExportInfoFD : ExternalImageExportInfoVk {
public:
// Contains the exported semaphore handles.
std::vector<int> semaphoreHandles;
protected:
using ExternalImageExportInfoVk::ExternalImageExportInfoVk;
};
struct DAWN_NATIVE_EXPORT ExternalImageExportInfoOpaqueFD : ExternalImageExportInfoFD {
ExternalImageExportInfoOpaqueFD();
};
struct DAWN_NATIVE_EXPORT ExternalImageExportInfoDmaBuf : ExternalImageExportInfoFD {
ExternalImageExportInfoDmaBuf();
};
#endif // __linux__
// Exports a signal semaphore from a wrapped texture. This must be called on wrapped
// textures before they are destroyed. On failure, returns -1
// TODO(enga): Remove after updating Chromium to use ExportVulkanImage.
DAWN_NATIVE_EXPORT int ExportSignalSemaphoreOpaqueFD(WGPUDevice cDevice,
WGPUTexture cTexture);
@@ -74,8 +125,15 @@ namespace dawn_native { namespace vulkan {
// primitives before the texture can be used.
// On failure, returns a nullptr.
DAWN_NATIVE_EXPORT WGPUTexture WrapVulkanImage(WGPUDevice cDevice,
const ExternalImageDescriptor* descriptor);
#endif // __linux__
const ExternalImageDescriptorVk* descriptor);
// Exports external memory from a Vulkan image. This must be called on wrapped textures
// before they are destroyed. It writes the semaphore to wait on and the old/new image
// layouts to |info|. Pass VK_IMAGE_LAYOUT_UNDEFINED as |desiredLayout| if you don't want to
// perform a layout transition.
DAWN_NATIVE_EXPORT bool ExportVulkanImage(WGPUTexture cTexture,
VkImageLayout desiredLayout,
ExternalImageExportInfoVk* info);
}} // namespace dawn_native::vulkan