From c198adf718192674a8200f25b97665e48e777a0c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 11 Aug 2021 05:18:10 +1000 Subject: [PATCH] lavapipe: add host ptr support. This actually doesn't need any backend support. Reviewed-By: Mike Blumenkrantz Part-of: --- src/gallium/frontends/lavapipe/lvp_device.c | 44 +++++++++++++++++--- src/gallium/frontends/lavapipe/lvp_formats.c | 36 +++++++++++++--- src/gallium/frontends/lavapipe/lvp_private.h | 1 + 3 files changed, 70 insertions(+), 11 deletions(-) diff --git a/src/gallium/frontends/lavapipe/lvp_device.c b/src/gallium/frontends/lavapipe/lvp_device.c index 0a987311967..6883501ce81 100644 --- a/src/gallium/frontends/lavapipe/lvp_device.c +++ b/src/gallium/frontends/lavapipe/lvp_device.c @@ -130,6 +130,7 @@ static const struct vk_device_extension_table lvp_device_extensions_supported = .EXT_conditional_rendering = true, .EXT_extended_dynamic_state = true, .EXT_extended_dynamic_state2 = true, + .EXT_external_memory_host = true, .EXT_host_query_reset = true, .EXT_index_type_uint8 = true, .EXT_multi_draw = true, @@ -980,6 +981,12 @@ VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceProperties2( properties->lineSubPixelPrecisionBits = 4; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT: { + VkPhysicalDeviceExternalMemoryHostPropertiesEXT *properties = + (VkPhysicalDeviceExternalMemoryHostPropertiesEXT *)ext; + properties->minImportedHostPointerAlignment = 4096; + break; + } case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES: { VkPhysicalDeviceSubgroupProperties *properties = (VkPhysicalDeviceSubgroupProperties*)ext; @@ -1088,6 +1095,23 @@ VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceMemoryProperties2( &pMemoryProperties->memoryProperties); } +VkResult +lvp_GetMemoryHostPointerPropertiesEXT( + VkDevice _device, + VkExternalMemoryHandleTypeFlagBits handleType, + const void *pHostPointer, + VkMemoryHostPointerPropertiesEXT *pMemoryHostPointerProperties) +{ + switch (handleType) { + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: { + pMemoryHostPointerProperties->memoryTypeBits = 1; + return VK_SUCCESS; + } + default: + return VK_ERROR_INVALID_EXTERNAL_HANDLE; + } +} + VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL lvp_GetInstanceProcAddr( VkInstance _instance, const char* pName) @@ -1657,6 +1681,8 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_AllocateMemory( LVP_FROM_HANDLE(lvp_device, device, _device); struct lvp_device_memory *mem; assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO); + const VkImportMemoryHostPointerInfoEXT *host_ptr_info = + vk_find_struct_const(pAllocateInfo->pNext, IMPORT_MEMORY_HOST_POINTER_INFO_EXT); if (pAllocateInfo->allocationSize == 0) { /* Apparently, this is allowed */ @@ -1671,10 +1697,17 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_AllocateMemory( vk_object_base_init(&device->vk, &mem->base, VK_OBJECT_TYPE_DEVICE_MEMORY); - mem->pmem = device->pscreen->allocate_memory(device->pscreen, pAllocateInfo->allocationSize); - if (!mem->pmem) { - vk_free2(&device->vk.alloc, pAllocator, mem); - return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); + + if (!host_ptr_info) { + mem->pmem = device->pscreen->allocate_memory(device->pscreen, pAllocateInfo->allocationSize); + if (!mem->pmem) { + vk_free2(&device->vk.alloc, pAllocator, mem); + return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); + } + mem->is_user_ptr = false; + } else { + mem->is_user_ptr = true; + mem->pmem = host_ptr_info->pHostPointer; } mem->type_index = pAllocateInfo->memoryTypeIndex; @@ -1695,7 +1728,8 @@ VKAPI_ATTR void VKAPI_CALL lvp_FreeMemory( if (mem == NULL) return; - device->pscreen->free_memory(device->pscreen, mem->pmem); + if (!mem->is_user_ptr) + device->pscreen->free_memory(device->pscreen, mem->pmem); vk_object_base_finish(&mem->base); vk_free2(&device->vk.alloc, pAllocator, mem); diff --git a/src/gallium/frontends/lavapipe/lvp_formats.c b/src/gallium/frontends/lavapipe/lvp_formats.c index ac2ba4b67e4..69e1808daba 100644 --- a/src/gallium/frontends/lavapipe/lvp_formats.c +++ b/src/gallium/frontends/lavapipe/lvp_formats.c @@ -335,10 +335,22 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_GetPhysicalDeviceImageFormatProperties2( } if (external_info && external_info->handleType != 0) { + VkExternalMemoryFeatureFlagBits flags = 0; + VkExternalMemoryHandleTypeFlags export_flags = 0; + VkExternalMemoryHandleTypeFlags compat_flags = 0; + + switch (external_info->handleType) { + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: + flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT; + compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT; + break; + default: + break; + } external_props->externalMemoryProperties = (VkExternalMemoryProperties) { - .externalMemoryFeatures = 0, - .exportFromImportedHandleTypes = 0, - .compatibleHandleTypes = 0, + .externalMemoryFeatures = flags, + .exportFromImportedHandleTypes = export_flags, + .compatibleHandleTypes = compat_flags, }; } if (ycbcr_props) @@ -375,9 +387,21 @@ VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceExternalBufferProperties( const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo, VkExternalBufferProperties *pExternalBufferProperties) { + VkExternalMemoryFeatureFlagBits flags = 0; + VkExternalMemoryHandleTypeFlags export_flags = 0; + VkExternalMemoryHandleTypeFlags compat_flags = 0; + switch (pExternalBufferInfo->handleType) { + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: + flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT; + compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT; + break; + default: + break; + } + pExternalBufferProperties->externalMemoryProperties = (VkExternalMemoryProperties) { - .externalMemoryFeatures = 0, - .exportFromImportedHandleTypes = 0, - .compatibleHandleTypes = 0, + .externalMemoryFeatures = flags, + .exportFromImportedHandleTypes = export_flags, + .compatibleHandleTypes = compat_flags, }; } diff --git a/src/gallium/frontends/lavapipe/lvp_private.h b/src/gallium/frontends/lavapipe/lvp_private.h index b035a236990..5ad0bc94916 100644 --- a/src/gallium/frontends/lavapipe/lvp_private.h +++ b/src/gallium/frontends/lavapipe/lvp_private.h @@ -219,6 +219,7 @@ struct lvp_device_memory { uint32_t type_index; VkDeviceSize map_size; void * map; + bool is_user_ptr; }; struct lvp_image {