[Mesa-dev] [PATCH 3/3] radv: Implement VK_KHR_external_memory
Jason Ekstrand
jason at jlekstrand.net
Sat Jul 15 04:50:51 UTC 2017
On Fri, Jul 14, 2017 at 5:08 PM, Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
wrote:
> From: Jason Ekstrand <jason at jlekstrand.net>
>
> This effectively reverts commit 43a171878bb4b5aedb36a. Technically,
> VK_KHR_get_memory_requirements2 and VK_KHR_dedicated_allocation are
> required for the KHR version but this at least restores the removed
> functionality. This patch builds but has received zero testing.
>
> Cc: Dave Airlie <airlied at redhat.com>
> (Bas: added plumbing for the dedicated allocation)
>
Those bits look good to me for what it's worth.
> ---
> src/amd/vulkan/radv_device.c | 74 +++++++++++++++++++++-
> src/amd/vulkan/radv_entrypoints_gen.py | 3 +
> src/amd/vulkan/radv_formats.c | 112
> +++++++++++++++++++++++++++++++++
> src/amd/vulkan/radv_image.c | 11 +++-
> src/amd/vulkan/radv_private.h | 2 +
> 5 files changed, 199 insertions(+), 3 deletions(-)
>
> diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
> index 59c4ea8448e..630f35ff7a8 100644
> --- a/src/amd/vulkan/radv_device.c
> +++ b/src/amd/vulkan/radv_device.c
> @@ -98,6 +98,10 @@ static const VkExtensionProperties
> instance_extensions[] = {
> .extensionName = VK_KHR_GET_PHYSICAL_DEVICE_
> PROPERTIES_2_EXTENSION_NAME,
> .specVersion = 1,
> },
> + {
> + .extensionName = VK_KHR_EXTERNAL_MEMORY_
> CAPABILITIES_EXTENSION_NAME,
> + .specVersion = 1,
> + },
> };
>
> static const VkExtensionProperties common_device_extensions[] = {
> @@ -145,6 +149,14 @@ static const VkExtensionProperties
> common_device_extensions[] = {
> .extensionName = VK_KHR_DEDICATED_ALLOCATION_
> EXTENSION_NAME,
> .specVersion = 1,
> },
> + {
> + .extensionName = VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
> + .specVersion = 1,
> + },
> + {
> + .extensionName = VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
> + .specVersion = 1,
> + },
> };
>
> static VkResult
> @@ -731,6 +743,7 @@ void radv_GetPhysicalDeviceProperties2KHR(
> VkPhysicalDevice physicalDevice,
> VkPhysicalDeviceProperties2KHR *pProperties)
> {
> + RADV_FROM_HANDLE(radv_physical_device, pdevice, physicalDevice);
> radv_GetPhysicalDeviceProperties(physicalDevice,
> &pProperties->properties);
>
> vk_foreach_struct(ext, pProperties->pNext) {
> @@ -741,6 +754,13 @@ void radv_GetPhysicalDeviceProperties2KHR(
> properties->maxPushDescriptors =
> MAX_PUSH_DESCRIPTORS;
> break;
> }
> + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR:
> {
> + VkPhysicalDeviceIDPropertiesKHR *properties = (
> VkPhysicalDeviceIDPropertiesKHR*)ext;
> + radv_device_get_cache_uuid(0,
> properties->driverUUID);
> + memcpy(properties->deviceUUID,
> pdevice->device_uuid, VK_UUID_SIZE);
> + properties->deviceLUIDValid = false;
> + break;
> + }
> default:
> break;
> }
> @@ -2076,6 +2096,9 @@ VkResult radv_AllocateMemory(
> *pMem = VK_NULL_HANDLE;
> return VK_SUCCESS;
> }
> +
> + const VkImportMemoryFdInfoKHR *import_info =
> + vk_find_struct_const(pAllocateInfo->pNext,
> IMPORT_MEMORY_FD_INFO_KHR);
> const VkMemoryDedicatedAllocateInfoKHR *dedicate_info =
> vk_find_struct_const(pAllocateInfo->pNext,
> MEMORY_DEDICATED_ALLOCATE_INFO_KHR);
>
> @@ -2092,6 +2115,18 @@ VkResult radv_AllocateMemory(
> mem->buffer = NULL;
> }
>
> + if (import_info) {
> + assert(import_info->handleType ==
> + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR);
> + mem->bo = device->ws->buffer_from_fd(device->ws,
> import_info->fd,
> + NULL, NULL);
> + if (!mem->bo) {
> + result = VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR;
> + goto fail;
> + } else
> + goto out_success;
> + }
> +
> uint64_t alloc_size = align_u64(pAllocateInfo->allocationSize,
> 4096);
> if (pAllocateInfo->memoryTypeIndex == RADV_MEM_TYPE_GTT_WRITE_COMBINE
> ||
> pAllocateInfo->memoryTypeIndex == RADV_MEM_TYPE_GTT_CACHED)
> @@ -2115,7 +2150,7 @@ VkResult radv_AllocateMemory(
> goto fail;
> }
> mem->type_index = pAllocateInfo->memoryTypeIndex;
> -
> +out_success:
> *pMem = radv_device_memory_to_handle(mem);
>
> return VK_SUCCESS;
> @@ -2258,12 +2293,14 @@ void radv_GetImageMemoryRequirements2KHR(
> radv_GetImageMemoryRequirements(device, pInfo->image,
> &pMemoryRequirements->
> memoryRequirements);
>
> + RADV_FROM_HANDLE(radv_image, image, pInfo->image);
> +
> vk_foreach_struct(ext, pMemoryRequirements->pNext) {
> switch (ext->sType) {
> case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR:
> {
> VkMemoryDedicatedRequirementsKHR *req =
> (VkMemoryDedicatedRequirementsKHR
> *) ext;
> - req->requiresDedicatedAllocation = false;
> + req->requiresDedicatedAllocation =
> image->shareable;
> req->prefersDedicatedAllocation = req->
> requiresDedicatedAllocation;
> break;
> }
> @@ -3318,3 +3355,36 @@ vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t
> *pSupportedVersion)
> *pSupportedVersion = MIN2(*pSupportedVersion, 3u);
> return VK_SUCCESS;
> }
> +
> +VkResult radv_GetMemoryFdKHR(VkDevice _device,
> + const VkMemoryGetFdInfoKHR *pGetFdInfo,
> + int *pFD)
> +{
> + RADV_FROM_HANDLE(radv_device, device, _device);
> + RADV_FROM_HANDLE(radv_device_memory, memory, pGetFdInfo->memory);
> +
> + assert(pGetFdInfo->sType == VK_STRUCTURE_TYPE_MEMORY_GET_
> FD_INFO_KHR);
> +
> + /* We support only one handle type. */
> + assert(pGetFdInfo->handleType ==
> + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR);
> +
> + bool ret = radv_get_memory_fd(device, memory, pFD);
> + if (ret == false)
> + return VK_ERROR_OUT_OF_DEVICE_MEMORY;
> + return VK_SUCCESS;
> +}
> +
> +VkResult radv_GetMemoryFdPropertiesKHR(VkDevice _device,
> + VkExternalMemoryHandleTypeFlagBitsKHR
> handleType,
> + int fd,
> + VkMemoryFdPropertiesKHR
> *pMemoryFdProperties)
> +{
> + /* The valid usage section for this function says:
> + *
> + * "handleType must not be one of the handle types defined as
> opaque."
> + *
> + * Since we only handle opaque handles for now, there are no FD
> properties.
> + */
> + return VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR;
> +}
> diff --git a/src/amd/vulkan/radv_entrypoints_gen.py b/src/amd/vulkan/radv_
> entrypoints_gen.py
> index d305a07e7d7..22068a5b02d 100644
> --- a/src/amd/vulkan/radv_entrypoints_gen.py
> +++ b/src/amd/vulkan/radv_entrypoints_gen.py
> @@ -44,6 +44,9 @@ supported_extensions = [
> 'VK_KHR_xlib_surface',
> 'VK_KHR_get_memory_requirements2',
> 'VK_KHR_dedicated_allocation',
> + 'VK_KHR_external_memory_capabilities',
> + 'VK_KHR_external_memory',
> + 'VK_KHR_external_memory_fd',
> ]
>
> # We generate a static hash table for entry point lookup
> diff --git a/src/amd/vulkan/radv_formats.c b/src/amd/vulkan/radv_formats.c
> index b740a1a5d9b..4d0aca1490d 100644
> --- a/src/amd/vulkan/radv_formats.c
> +++ b/src/amd/vulkan/radv_formats.c
> @@ -1142,12 +1142,37 @@ VkResult radv_GetPhysicalDeviceImageFormatPr
> operties(
> pImageFormatProperties);
> }
>
> +static void
> +get_external_image_format_properties(const VkPhysicalDeviceImageFormatInfo2KHR
> *pImageFormatInfo,
> + VkExternalMemoryPropertiesKHR
> *external_properties)
> +{
> + VkExternalMemoryFeatureFlagBitsKHR flags = 0;
> + VkExternalMemoryHandleTypeFlagsKHR export_flags = 0;
> + VkExternalMemoryHandleTypeFlagsKHR compat_flags = 0;
> + switch (pImageFormatInfo->type) {
> + case VK_IMAGE_TYPE_2D:
> + flags = VK_EXTERNAL_MEMORY_FEATURE_
> DEDICATED_ONLY_BIT_KHR|VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR|VK_
> EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR;
> + compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_
> TYPE_OPAQUE_FD_BIT_KHR;
> + break;
> + default:
> + break;
> + }
> +
> + *external_properties = (VkExternalMemoryPropertiesKHR) {
> + .externalMemoryFeatures = flags,
> + .exportFromImportedHandleTypes = export_flags,
> + .compatibleHandleTypes = compat_flags,
> + };
> +}
> +
> VkResult radv_GetPhysicalDeviceImageFormatProperties2KHR(
> VkPhysicalDevice physicalDevice,
> const VkPhysicalDeviceImageFormatInfo2KHR *base_info,
> VkImageFormatProperties2KHR *base_props)
> {
> RADV_FROM_HANDLE(radv_physical_device, physical_device,
> physicalDevice);
> + const VkPhysicalDeviceExternalImageFormatInfoKHR *external_info =
> NULL;
> + VkExternalImageFormatPropertiesKHR *external_props = NULL;
> VkResult result;
>
> result = radv_get_image_format_properties(physical_device,
> base_info,
> @@ -1155,7 +1180,69 @@ VkResult radv_GetPhysicalDeviceImageFormatPr
> operties2KHR(
> if (result != VK_SUCCESS)
> return result;
>
> + /* Extract input structs */
> + vk_foreach_struct_const(s, base_info->pNext) {
> + switch (s->sType) {
> + case VK_STRUCTURE_TYPE_PHYSICAL_
> DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR:
> + external_info = (const void *) s;
> + break;
> + default:
> + break;
> + }
> + }
> +
> + /* Extract output structs */
> + vk_foreach_struct(s, base_props->pNext) {
> + switch (s->sType) {
> + case VK_STRUCTURE_TYPE_EXTERNAL_
> IMAGE_FORMAT_PROPERTIES_KHR:
> + external_props = (void *) s;
> + break;
> + default:
> + break;
> + }
> + }
> +
> + /* From the Vulkan 1.0.42 spec:
> + *
> + * If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2KHR
> will
> + * behave as if VkPhysicalDeviceExternalImageFormatInfoKHR was
> not
> + * present and VkExternalImageFormatPropertiesKHR will be
> ignored.
> + */
> + if (external_info && external_info->handleType != 0) {
> + switch (external_info->handleType) {
> + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
> + get_external_image_format_properties(base_info,
> &external_props->externalMemoryProperties);
> + break;
> + default:
> + /* From the Vulkan 1.0.42 spec:
> + *
> + * If handleType is not compatible with the
> [parameters] specified
> + * in VkPhysicalDeviceImageFormatInfo2KHR, then
> + * vkGetPhysicalDeviceImageFormatProperties2KHR
> returns
> + * VK_ERROR_FORMAT_NOT_SUPPORTED.
> + */
> + result = vk_errorf(VK_ERROR_FORMAT_NOT_SUPPORTED,
> + "unsupported
> VkExternalMemoryTypeFlagBitsKHR 0x%x",
> + external_info->handleType);
> + goto fail;
> + }
> + }
> +
> return VK_SUCCESS;
> +
> +fail:
> + if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) {
> + /* From the Vulkan 1.0.42 spec:
> + *
> + * If the combination of parameters to
> + * vkGetPhysicalDeviceImageFormatProperties2KHR is not
> supported by
> + * the implementation for use in vkCreateImage, then
> all members of
> + * imageFormatProperties will be filled with zero.
> + */
> + base_props->imageFormatProperties =
> (VkImageFormatProperties) {0};
> + }
> +
> + return result;
> }
>
> void radv_GetPhysicalDeviceSparseImageFormatProperties(
> @@ -1181,3 +1268,28 @@ void radv_GetPhysicalDeviceSparseImageFo
> rmatProperties2KHR(
> /* Sparse images are not yet supported. */
> *pPropertyCount = 0;
> }
> +
> +void radv_GetPhysicalDeviceExternalBufferPropertiesKHR(
> + VkPhysicalDevice physicalDevice,
> + const VkPhysicalDeviceExternalBufferInfoKHR *pExternalBufferInfo,
> + VkExternalBufferPropertiesKHR
> *pExternalBufferProperties)
> +{
> + VkExternalMemoryFeatureFlagBitsKHR flags = 0;
> + VkExternalMemoryHandleTypeFlagsKHR export_flags = 0;
> + VkExternalMemoryHandleTypeFlagsKHR compat_flags = 0;
> + switch(pExternalBufferInfo->handleType) {
> + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
> + flags = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR
> |
> + VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR |
> + VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR;
> + compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_
> TYPE_OPAQUE_FD_BIT_KHR;
> + break;
> + default:
> + break;
> + }
> + pExternalBufferProperties->externalMemoryProperties = (VkExternalMemoryPropertiesKHR)
> {
> + .externalMemoryFeatures = flags,
> + .exportFromImportedHandleTypes = export_flags,
> + .compatibleHandleTypes = compat_flags,
> + };
> +}
> diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c
> index fc00d019d1d..17ee74b5f5b 100644
> --- a/src/amd/vulkan/radv_image.c
> +++ b/src/amd/vulkan/radv_image.c
> @@ -27,6 +27,7 @@
>
> #include "radv_private.h"
> #include "vk_format.h"
> +#include "vk_util.h"
> #include "radv_radeon_winsys.h"
> #include "sid.h"
> #include "gfx9d.h"
> @@ -783,9 +784,15 @@ radv_image_create(VkDevice _device,
> image->exclusive = pCreateInfo->sharingMode ==
> VK_SHARING_MODE_EXCLUSIVE;
> if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
> for (uint32_t i = 0; i < pCreateInfo->queueFamilyIndexCount;
> ++i)
> - image->queue_family_mask |= 1u << pCreateInfo->
> pQueueFamilyIndices[i];
> + if (pCreateInfo->pQueueFamilyIndices[i] ==
> VK_QUEUE_FAMILY_EXTERNAL_KHR)
> + image->queue_family_mask |= (1u <<
> RADV_MAX_QUEUE_FAMILIES) - 1u;
> + else
> + image->queue_family_mask |= 1u <<
> pCreateInfo->pQueueFamilyIndices[i];
> }
>
> + image->shareable = vk_find_struct_const(pCreateInfo->pNext,
> +
> EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR) != NULL;
> +
> radv_init_surface(device, &image->surface, create_info);
>
> device->ws->surface_init(device->ws, &image->info,
> &image->surface);
> @@ -962,6 +969,8 @@ unsigned radv_image_queue_family_mask(const struct
> radv_image *image, uint32_t f
> {
> if (!image->exclusive)
> return image->queue_family_mask;
> + if (family == VK_QUEUE_FAMILY_EXTERNAL_KHR)
> + return (1u << RADV_MAX_QUEUE_FAMILIES) - 1u;
> if (family == VK_QUEUE_FAMILY_IGNORED)
> return 1u << queue_family;
> return 1u << family;
> diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
> index a8bc5c96586..2f633b4dbd9 100644
> --- a/src/amd/vulkan/radv_private.h
> +++ b/src/amd/vulkan/radv_private.h
> @@ -1205,6 +1205,8 @@ struct radv_image {
> bool exclusive;
> unsigned queue_family_mask;
>
> + bool shareable;
> +
> /* Set when bound */
> struct radeon_winsys_bo *bo;
> VkDeviceSize offset;
> --
> 2.13.2
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20170714/6b31327c/attachment-0001.html>
More information about the mesa-dev
mailing list