diff --git a/src/virtio/vulkan/vn_android.c b/src/virtio/vulkan/vn_android.c index c410ab95a08..f483531ade1 100644 --- a/src/virtio/vulkan/vn_android.c +++ b/src/virtio/vulkan/vn_android.c @@ -20,6 +20,7 @@ #include "util/libsync.h" #include "util/os_file.h" +#include "vn_buffer.h" #include "vn_device.h" #include "vn_device_memory.h" #include "vn_image.h" @@ -1083,3 +1084,57 @@ vn_GetMemoryAndroidHardwareBufferANDROID( return VK_SUCCESS; } + +struct vn_android_buffer_create_info { + VkBufferCreateInfo create; + VkExternalMemoryBufferCreateInfo external; + VkBufferOpaqueCaptureAddressCreateInfo address; +}; + +static const VkBufferCreateInfo * +vn_android_fix_buffer_create_info( + const VkBufferCreateInfo *create_info, + struct vn_android_buffer_create_info *local_info) +{ + local_info->create = *create_info; + VkBaseOutStructure *dst = (void *)&local_info->create; + + vk_foreach_struct_const(src, create_info->pNext) { + void *pnext = NULL; + switch (src->sType) { + case VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO: + memcpy(&local_info->external, src, sizeof(local_info->external)); + local_info->external.handleTypes = + VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; + pnext = &local_info->external; + break; + case VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO: + memcpy(&local_info->address, src, sizeof(local_info->address)); + pnext = &local_info->address; + break; + default: + break; + } + + if (pnext) { + dst->pNext = pnext; + dst = pnext; + } + } + + dst->pNext = NULL; + + return &local_info->create; +} + +VkResult +vn_android_buffer_from_ahb(struct vn_device *dev, + const VkBufferCreateInfo *create_info, + const VkAllocationCallbacks *alloc, + struct vn_buffer **out_buf) +{ + struct vn_android_buffer_create_info local_info; + + create_info = vn_android_fix_buffer_create_info(create_info, &local_info); + return vn_buffer_create(dev, create_info, alloc, out_buf); +} diff --git a/src/virtio/vulkan/vn_android.h b/src/virtio/vulkan/vn_android.h index 587ad83e440..8389b6dd0fc 100644 --- a/src/virtio/vulkan/vn_android.h +++ b/src/virtio/vulkan/vn_android.h @@ -69,6 +69,12 @@ vn_android_release_ahb(struct AHardwareBuffer *ahb); VkFormat vn_android_drm_format_to_vk_format(uint32_t format); +VkResult +vn_android_buffer_from_ahb(struct vn_device *dev, + const VkBufferCreateInfo *create_info, + const VkAllocationCallbacks *alloc, + struct vn_buffer **out_buf); + #else static inline const VkNativeBufferANDROID * @@ -142,6 +148,15 @@ vn_android_drm_format_to_vk_format(UNUSED uint32_t format) return VK_FORMAT_UNDEFINED; } +static inline VkResult +vn_android_buffer_from_ahb(UNUSED struct vn_device *dev, + UNUSED const VkBufferCreateInfo *create_info, + UNUSED const VkAllocationCallbacks *alloc, + UNUSED struct vn_buffer **out_buf) +{ + return VK_ERROR_OUT_OF_HOST_MEMORY; +} + #endif /* ANDROID */ #endif /* VN_ANDROID_H */ diff --git a/src/virtio/vulkan/vn_buffer.c b/src/virtio/vulkan/vn_buffer.c index 547ffb49bf7..cb65c2d29f1 100644 --- a/src/virtio/vulkan/vn_buffer.c +++ b/src/virtio/vulkan/vn_buffer.c @@ -13,6 +13,7 @@ #include "venus-protocol/vn_protocol_driver_buffer.h" #include "venus-protocol/vn_protocol_driver_buffer_view.h" +#include "vn_android.h" #include "vn_device.h" #include "vn_device_memory.h" @@ -77,7 +78,18 @@ vn_CreateBuffer(VkDevice device, struct vn_buffer *buf = NULL; VkResult result; - result = vn_buffer_create(dev, pCreateInfo, alloc, &buf); + const VkExternalMemoryBufferCreateInfo *external_info = + vk_find_struct_const(pCreateInfo->pNext, + EXTERNAL_MEMORY_BUFFER_CREATE_INFO); + const bool ahb_info = + external_info && + external_info->handleTypes == + VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID; + + if (ahb_info) + result = vn_android_buffer_from_ahb(dev, pCreateInfo, alloc, &buf); + else + result = vn_buffer_create(dev, pCreateInfo, alloc, &buf); if (result != VK_SUCCESS) return vn_error(dev->instance, result);