Define an interface to import dma-bufs
This CL adds an API to import a dma-buf into Dawn as a WGPUTexture. We also add a descriptor type enum to the base ExternalImageDescriptor struct. This is because all memory import code (e.g. MemoryService, Texture::CreateFromExternal) takes the a base ExternalImageDescriptor as a parameter. The dma-buf external memory and image services, however, will need to downcast to ExternalImageDescriptorDmaBuf to access import parameters like stride. Explicitly adding a type enum will let us more safely verify the type before downcasting. BUG=chromium:996470 Change-Id: I2d9883a15e9059a91f2c7bdb7a96d74373e18c56 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/13782 Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Brian Ho <hob@chromium.org>
This commit is contained in:
parent
ae687f5b83
commit
98ba76af00
|
@ -518,11 +518,6 @@ namespace dawn_native { namespace vulkan {
|
||||||
VkDeviceMemory externalMemoryAllocation,
|
VkDeviceMemory externalMemoryAllocation,
|
||||||
std::vector<VkSemaphore> waitSemaphores) {
|
std::vector<VkSemaphore> waitSemaphores) {
|
||||||
Device* device = ToBackend(GetDevice());
|
Device* device = ToBackend(GetDevice());
|
||||||
VkMemoryRequirements requirements;
|
|
||||||
device->fn.GetImageMemoryRequirements(device->GetVkDevice(), mHandle, &requirements);
|
|
||||||
|
|
||||||
ASSERT(requirements.size <= descriptor->allocationSize);
|
|
||||||
|
|
||||||
DAWN_TRY(CheckVkSuccess(
|
DAWN_TRY(CheckVkSuccess(
|
||||||
device->fn.BindImageMemory(device->GetVkDevice(), mHandle, externalMemoryAllocation, 0),
|
device->fn.BindImageMemory(device->GetVkDevice(), mHandle, externalMemoryAllocation, 0),
|
||||||
"BindImageMemory (external)"));
|
"BindImageMemory (external)"));
|
||||||
|
|
|
@ -60,6 +60,23 @@ namespace dawn_native { namespace vulkan {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DAWN_PLATFORM_LINUX
|
#ifdef DAWN_PLATFORM_LINUX
|
||||||
|
ExternalImageDescriptor::ExternalImageDescriptor(ExternalImageDescriptorType type)
|
||||||
|
: type(type) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ExternalImageDescriptorFD::ExternalImageDescriptorFD(ExternalImageDescriptorType type)
|
||||||
|
: ExternalImageDescriptor(type) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ExternalImageDescriptorOpaqueFD::ExternalImageDescriptorOpaqueFD()
|
||||||
|
: ExternalImageDescriptorFD(ExternalImageDescriptorType::OpaqueFD) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ExternalImageDescriptorDmaBuf::ExternalImageDescriptorDmaBuf()
|
||||||
|
: ExternalImageDescriptorFD(ExternalImageDescriptorType::DmaBuf) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(hob): Remove this once we switch over to WrapVulkanImage in Chromium.
|
||||||
WGPUTexture WrapVulkanImageOpaqueFD(WGPUDevice cDevice,
|
WGPUTexture WrapVulkanImageOpaqueFD(WGPUDevice cDevice,
|
||||||
const ExternalImageDescriptorOpaqueFD* descriptor) {
|
const ExternalImageDescriptorOpaqueFD* descriptor) {
|
||||||
Device* device = reinterpret_cast<Device*>(cDevice);
|
Device* device = reinterpret_cast<Device*>(cDevice);
|
||||||
|
@ -85,6 +102,23 @@ namespace dawn_native { namespace vulkan {
|
||||||
|
|
||||||
return outHandle;
|
return outHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WGPUTexture WrapVulkanImage(WGPUDevice cDevice, const ExternalImageDescriptor* descriptor) {
|
||||||
|
Device* device = reinterpret_cast<Device*>(cDevice);
|
||||||
|
|
||||||
|
switch (descriptor->type) {
|
||||||
|
case ExternalImageDescriptorType::OpaqueFD:
|
||||||
|
case ExternalImageDescriptorType::DmaBuf: {
|
||||||
|
const ExternalImageDescriptorFD* fdDescriptor =
|
||||||
|
static_cast<const ExternalImageDescriptorFD*>(descriptor);
|
||||||
|
TextureBase* texture = device->CreateTextureWrappingVulkanImage(
|
||||||
|
descriptor, fdDescriptor->memoryFD, fdDescriptor->waitFDs);
|
||||||
|
return reinterpret_cast<WGPUTexture>(texture);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}} // namespace dawn_native::vulkan
|
}} // namespace dawn_native::vulkan
|
||||||
|
|
|
@ -88,7 +88,14 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||||
ResultOrError<MemoryImportParams> Service::GetMemoryImportParams(
|
ResultOrError<MemoryImportParams> Service::GetMemoryImportParams(
|
||||||
const ExternalImageDescriptor* descriptor,
|
const ExternalImageDescriptor* descriptor,
|
||||||
VkImage image) {
|
VkImage image) {
|
||||||
MemoryImportParams params = {descriptor->allocationSize, descriptor->memoryTypeIndex};
|
if (descriptor->type != ExternalImageDescriptorType::OpaqueFD) {
|
||||||
|
return DAWN_VALIDATION_ERROR("ExternalImageDescriptor is not an OpaqueFD descriptor");
|
||||||
|
}
|
||||||
|
const ExternalImageDescriptorOpaqueFD* opaqueFDDescriptor =
|
||||||
|
static_cast<const ExternalImageDescriptorOpaqueFD*>(descriptor);
|
||||||
|
|
||||||
|
MemoryImportParams params = {opaqueFDDescriptor->allocationSize,
|
||||||
|
opaqueFDDescriptor->memoryTypeIndex};
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,6 +106,12 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||||
return DAWN_VALIDATION_ERROR("Trying to import memory with invalid handle");
|
return DAWN_VALIDATION_ERROR("Trying to import memory with invalid handle");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkMemoryRequirements requirements;
|
||||||
|
mDevice->fn.GetImageMemoryRequirements(mDevice->GetVkDevice(), image, &requirements);
|
||||||
|
if (requirements.size > importParams.allocationSize) {
|
||||||
|
return DAWN_VALIDATION_ERROR("Requested allocation size is too small for image");
|
||||||
|
}
|
||||||
|
|
||||||
VkImportMemoryFdInfoKHR importMemoryFdInfo;
|
VkImportMemoryFdInfoKHR importMemoryFdInfo;
|
||||||
importMemoryFdInfo.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR;
|
importMemoryFdInfo.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR;
|
||||||
importMemoryFdInfo.pNext = nullptr;
|
importMemoryFdInfo.pNext = nullptr;
|
||||||
|
|
|
@ -88,7 +88,14 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||||
ResultOrError<MemoryImportParams> Service::GetMemoryImportParams(
|
ResultOrError<MemoryImportParams> Service::GetMemoryImportParams(
|
||||||
const ExternalImageDescriptor* descriptor,
|
const ExternalImageDescriptor* descriptor,
|
||||||
VkImage image) {
|
VkImage image) {
|
||||||
MemoryImportParams params = {descriptor->allocationSize, descriptor->memoryTypeIndex};
|
if (descriptor->type != ExternalImageDescriptorType::OpaqueFD) {
|
||||||
|
return DAWN_VALIDATION_ERROR("ExternalImageDescriptor is not an OpaqueFD descriptor");
|
||||||
|
}
|
||||||
|
const ExternalImageDescriptorOpaqueFD* opaqueFDDescriptor =
|
||||||
|
static_cast<const ExternalImageDescriptorOpaqueFD*>(descriptor);
|
||||||
|
|
||||||
|
MemoryImportParams params = {opaqueFDDescriptor->allocationSize,
|
||||||
|
opaqueFDDescriptor->memoryTypeIndex};
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,6 +106,12 @@ namespace dawn_native { namespace vulkan { namespace external_memory {
|
||||||
return DAWN_VALIDATION_ERROR("Trying to import memory with invalid handle");
|
return DAWN_VALIDATION_ERROR("Trying to import memory with invalid handle");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkMemoryRequirements requirements;
|
||||||
|
mDevice->fn.GetImageMemoryRequirements(mDevice->GetVkDevice(), image, &requirements);
|
||||||
|
if (requirements.size > importParams.allocationSize) {
|
||||||
|
return DAWN_VALIDATION_ERROR("Requested allocation size is too small for image");
|
||||||
|
}
|
||||||
|
|
||||||
VkImportMemoryZirconHandleInfoFUCHSIA importMemoryHandleInfo;
|
VkImportMemoryZirconHandleInfoFUCHSIA importMemoryHandleInfo;
|
||||||
importMemoryHandleInfo.sType =
|
importMemoryHandleInfo.sType =
|
||||||
VK_STRUCTURE_TYPE_TEMP_MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA;
|
VK_STRUCTURE_TYPE_TEMP_MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA;
|
||||||
|
|
|
@ -24,12 +24,23 @@
|
||||||
|
|
||||||
namespace dawn_native { namespace vulkan {
|
namespace dawn_native { namespace vulkan {
|
||||||
|
|
||||||
|
// The different types of ExternalImageDescriptors
|
||||||
|
enum ExternalImageDescriptorType {
|
||||||
|
#ifdef __linux__
|
||||||
|
OpaqueFD,
|
||||||
|
DmaBuf,
|
||||||
|
#endif // __linux__
|
||||||
|
};
|
||||||
|
|
||||||
// Common properties of external images
|
// Common properties of external images
|
||||||
struct ExternalImageDescriptor {
|
struct ExternalImageDescriptor {
|
||||||
|
public:
|
||||||
|
const ExternalImageDescriptorType type; // Must match the subclass
|
||||||
const WGPUTextureDescriptor* cTextureDescriptor; // Must match image creation params
|
const WGPUTextureDescriptor* cTextureDescriptor; // Must match image creation params
|
||||||
bool isCleared; // Sets whether the texture will be cleared before use
|
bool isCleared; // Sets whether the texture will be cleared before use
|
||||||
VkDeviceSize allocationSize; // Must match VkMemoryAllocateInfo from image creation
|
|
||||||
uint32_t memoryTypeIndex; // Must match VkMemoryAllocateInfo from image creation
|
protected:
|
||||||
|
ExternalImageDescriptor(ExternalImageDescriptorType type);
|
||||||
};
|
};
|
||||||
|
|
||||||
DAWN_NATIVE_EXPORT VkInstance GetInstance(WGPUDevice device);
|
DAWN_NATIVE_EXPORT VkInstance GetInstance(WGPUDevice device);
|
||||||
|
@ -43,10 +54,30 @@ namespace dawn_native { namespace vulkan {
|
||||||
|
|
||||||
// Can't use DAWN_PLATFORM_LINUX since header included in both dawn and chrome
|
// Can't use DAWN_PLATFORM_LINUX since header included in both dawn and chrome
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
// Descriptor for opaque file descriptor image import
|
// Common properties of external images represented by FDs
|
||||||
struct ExternalImageDescriptorOpaqueFD : ExternalImageDescriptor {
|
struct ExternalImageDescriptorFD : ExternalImageDescriptor {
|
||||||
|
public:
|
||||||
int memoryFD; // A file descriptor from an export of the memory of the image
|
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
|
std::vector<int> waitFDs; // File descriptors of semaphores which will be waited on
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ExternalImageDescriptorFD(ExternalImageDescriptorType type);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Descriptor for opaque file descriptor image import
|
||||||
|
struct ExternalImageDescriptorOpaqueFD : ExternalImageDescriptorFD {
|
||||||
|
ExternalImageDescriptorOpaqueFD();
|
||||||
|
|
||||||
|
VkDeviceSize allocationSize; // Must match VkMemoryAllocateInfo from image creation
|
||||||
|
uint32_t memoryTypeIndex; // Must match VkMemoryAllocateInfo from image creation
|
||||||
|
};
|
||||||
|
|
||||||
|
// Descriptor for dma-buf file descriptor image import
|
||||||
|
struct ExternalImageDescriptorDmaBuf : ExternalImageDescriptorFD {
|
||||||
|
ExternalImageDescriptorDmaBuf();
|
||||||
|
|
||||||
|
uint32_t stride; // Stride of the buffer in bytes
|
||||||
|
uint64_t drmModifier; // DRM modifier of the buffer
|
||||||
};
|
};
|
||||||
|
|
||||||
// Imports an external vulkan image from an opaque file descriptor. Internally, this uses
|
// Imports an external vulkan image from an opaque file descriptor. Internally, this uses
|
||||||
|
@ -54,6 +85,8 @@ namespace dawn_native { namespace vulkan {
|
||||||
// |descriptor->waitFDs| before the texture can be used. Finally, a signal semaphore
|
// |descriptor->waitFDs| before the texture can be used. Finally, a signal semaphore
|
||||||
// can be exported, transferring control back to the caller.
|
// can be exported, transferring control back to the caller.
|
||||||
// On failure, returns a nullptr
|
// On failure, returns a nullptr
|
||||||
|
// NOTE: This is deprecated. Use WrapVulkanImage instead.
|
||||||
|
// TODO(hob): Remove this once Chromium has switched over to WrapVulkanImage.
|
||||||
DAWN_NATIVE_EXPORT WGPUTexture
|
DAWN_NATIVE_EXPORT WGPUTexture
|
||||||
WrapVulkanImageOpaqueFD(WGPUDevice cDevice,
|
WrapVulkanImageOpaqueFD(WGPUDevice cDevice,
|
||||||
const ExternalImageDescriptorOpaqueFD* descriptor);
|
const ExternalImageDescriptorOpaqueFD* descriptor);
|
||||||
|
@ -62,6 +95,13 @@ namespace dawn_native { namespace vulkan {
|
||||||
// textures before they are destroyed. On failure, returns -1
|
// textures before they are destroyed. On failure, returns -1
|
||||||
DAWN_NATIVE_EXPORT int ExportSignalSemaphoreOpaqueFD(WGPUDevice cDevice,
|
DAWN_NATIVE_EXPORT int ExportSignalSemaphoreOpaqueFD(WGPUDevice cDevice,
|
||||||
WGPUTexture cTexture);
|
WGPUTexture cTexture);
|
||||||
|
|
||||||
|
// Imports external memory into a Vulkan image. Internally, this uses external memory /
|
||||||
|
// semaphore extensions to import the image and wait on the provided synchronizaton
|
||||||
|
// primitives before the texture can be used.
|
||||||
|
// On failure, returns a nullptr.
|
||||||
|
DAWN_NATIVE_EXPORT WGPUTexture WrapVulkanImage(WGPUDevice cDevice,
|
||||||
|
const ExternalImageDescriptor* descriptor);
|
||||||
#endif // __linux__
|
#endif // __linux__
|
||||||
}} // namespace dawn_native::vulkan
|
}} // namespace dawn_native::vulkan
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue