Ported from the radeonsi GL_AMD_pinned_memory implementation. Signed-off-by: Fredrik Höglund <fredrik@kde.org> Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>tags/18.1-branchpoint
| @@ -810,6 +810,12 @@ void radv_GetPhysicalDeviceProperties2KHR( | |||
| properties->maxDiscardRectangles = MAX_DISCARD_RECTANGLES; | |||
| break; | |||
| } | |||
| case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT: { | |||
| VkPhysicalDeviceExternalMemoryHostPropertiesEXT *properties = | |||
| (VkPhysicalDeviceExternalMemoryHostPropertiesEXT *) ext; | |||
| properties->minImportedHostPointerAlignment = 4096; | |||
| break; | |||
| } | |||
| default: | |||
| break; | |||
| } | |||
| @@ -923,6 +929,33 @@ void radv_GetPhysicalDeviceMemoryProperties2KHR( | |||
| &pMemoryProperties->memoryProperties); | |||
| } | |||
| VkResult radv_GetMemoryHostPointerPropertiesEXT( | |||
| VkDevice _device, | |||
| VkExternalMemoryHandleTypeFlagBitsKHR handleType, | |||
| const void *pHostPointer, | |||
| VkMemoryHostPointerPropertiesEXT *pMemoryHostPointerProperties) | |||
| { | |||
| RADV_FROM_HANDLE(radv_device, device, _device); | |||
| switch (handleType) | |||
| { | |||
| case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: { | |||
| const struct radv_physical_device *physical_device = device->physical_device; | |||
| uint32_t memoryTypeBits = 0; | |||
| for (int i = 0; i < physical_device->memory_properties.memoryTypeCount; i++) { | |||
| if (physical_device->mem_type_indices[i] == RADV_MEM_TYPE_GTT_CACHED) { | |||
| memoryTypeBits = (1 << i); | |||
| break; | |||
| } | |||
| } | |||
| pMemoryHostPointerProperties->memoryTypeBits = memoryTypeBits; | |||
| return VK_SUCCESS; | |||
| } | |||
| default: | |||
| return VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR; | |||
| } | |||
| } | |||
| static enum radeon_ctx_priority | |||
| radv_get_queue_global_priority(const VkDeviceQueueGlobalPriorityCreateInfoEXT *pObj) | |||
| { | |||
| @@ -2246,6 +2279,8 @@ static VkResult radv_alloc_memory(struct radv_device *device, | |||
| vk_find_struct_const(pAllocateInfo->pNext, MEMORY_DEDICATED_ALLOCATE_INFO_KHR); | |||
| const VkExportMemoryAllocateInfoKHR *export_info = | |||
| vk_find_struct_const(pAllocateInfo->pNext, EXPORT_MEMORY_ALLOCATE_INFO_KHR); | |||
| const VkImportMemoryHostPointerInfoEXT *host_ptr_info = | |||
| vk_find_struct_const(pAllocateInfo->pNext, IMPORT_MEMORY_HOST_POINTER_INFO_EXT); | |||
| const struct wsi_memory_allocate_info *wsi_info = | |||
| vk_find_struct_const(pAllocateInfo->pNext, WSI_MEMORY_ALLOCATE_INFO_MESA); | |||
| @@ -2266,6 +2301,8 @@ static VkResult radv_alloc_memory(struct radv_device *device, | |||
| mem->buffer = NULL; | |||
| } | |||
| mem->user_ptr = NULL; | |||
| if (import_info) { | |||
| assert(import_info->handleType == | |||
| VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR || | |||
| @@ -2282,6 +2319,20 @@ static VkResult radv_alloc_memory(struct radv_device *device, | |||
| } | |||
| } | |||
| if (host_ptr_info) { | |||
| assert(host_ptr_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT); | |||
| assert(mem_type_index == RADV_MEM_TYPE_GTT_CACHED); | |||
| mem->bo = device->ws->buffer_from_ptr(device->ws, host_ptr_info->pHostPointer, | |||
| pAllocateInfo->allocationSize); | |||
| if (!mem->bo) { | |||
| result = VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR; | |||
| goto fail; | |||
| } else { | |||
| mem->user_ptr = host_ptr_info->pHostPointer; | |||
| goto out_success; | |||
| } | |||
| } | |||
| uint64_t alloc_size = align_u64(pAllocateInfo->allocationSize, 4096); | |||
| if (mem_type_index == RADV_MEM_TYPE_GTT_WRITE_COMBINE || | |||
| mem_type_index == RADV_MEM_TYPE_GTT_CACHED) | |||
| @@ -2362,7 +2413,11 @@ VkResult radv_MapMemory( | |||
| return VK_SUCCESS; | |||
| } | |||
| *ppData = device->ws->buffer_map(mem->bo); | |||
| if (mem->user_ptr) | |||
| *ppData = mem->user_ptr; | |||
| else | |||
| *ppData = device->ws->buffer_map(mem->bo); | |||
| if (*ppData) { | |||
| *ppData += offset; | |||
| return VK_SUCCESS; | |||
| @@ -2381,7 +2436,8 @@ void radv_UnmapMemory( | |||
| if (mem == NULL) | |||
| return; | |||
| device->ws->buffer_unmap(mem->bo); | |||
| if (mem->user_ptr == NULL) | |||
| device->ws->buffer_unmap(mem->bo); | |||
| } | |||
| VkResult radv_FlushMappedMemoryRanges( | |||
| @@ -85,6 +85,7 @@ EXTENSIONS = [ | |||
| Extension('VK_EXT_debug_report', 9, True), | |||
| Extension('VK_EXT_discard_rectangles', 1, True), | |||
| Extension('VK_EXT_external_memory_dma_buf', 1, True), | |||
| Extension('VK_EXT_external_memory_host', 1, 'device->rad_info.has_userptr'), | |||
| Extension('VK_EXT_global_priority', 1, 'device->rad_info.has_ctx_priority'), | |||
| Extension('VK_AMD_draw_indirect_count', 1, True), | |||
| Extension('VK_AMD_rasterization_order', 1, 'device->rad_info.chip_class >= VI && device->rad_info.max_se >= 2'), | |||
| @@ -1177,16 +1177,28 @@ VkResult radv_GetPhysicalDeviceImageFormatProperties( | |||
| static void | |||
| get_external_image_format_properties(const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo, | |||
| VkExternalMemoryHandleTypeFlagBitsKHR handleType, | |||
| 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 | | |||
| VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; | |||
| switch (handleType) { | |||
| case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR: | |||
| case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: | |||
| 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 | | |||
| VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; | |||
| break; | |||
| default: | |||
| break; | |||
| } | |||
| break; | |||
| case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: | |||
| flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR; | |||
| compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT; | |||
| break; | |||
| default: | |||
| break; | |||
| @@ -1246,7 +1258,9 @@ VkResult radv_GetPhysicalDeviceImageFormatProperties2KHR( | |||
| switch (external_info->handleType) { | |||
| case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR: | |||
| case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: | |||
| get_external_image_format_properties(base_info, &external_props->externalMemoryProperties); | |||
| case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: | |||
| get_external_image_format_properties(base_info, external_info->handleType, | |||
| &external_props->externalMemoryProperties); | |||
| break; | |||
| default: | |||
| /* From the Vulkan 1.0.42 spec: | |||
| @@ -1320,6 +1334,10 @@ void radv_GetPhysicalDeviceExternalBufferPropertiesKHR( | |||
| compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR | | |||
| VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; | |||
| break; | |||
| case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: | |||
| flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR; | |||
| compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT; | |||
| break; | |||
| default: | |||
| break; | |||
| } | |||
| @@ -646,6 +646,7 @@ struct radv_device_memory { | |||
| uint32_t type_index; | |||
| VkDeviceSize map_size; | |||
| void * map; | |||
| void * user_ptr; | |||
| }; | |||
| @@ -200,6 +200,10 @@ struct radeon_winsys { | |||
| void (*buffer_destroy)(struct radeon_winsys_bo *bo); | |||
| void *(*buffer_map)(struct radeon_winsys_bo *bo); | |||
| struct radeon_winsys_bo *(*buffer_from_ptr)(struct radeon_winsys *ws, | |||
| void *pointer, | |||
| uint64_t size); | |||
| struct radeon_winsys_bo *(*buffer_from_fd)(struct radeon_winsys *ws, | |||
| int fd, | |||
| unsigned *stride, unsigned *offset); | |||
| @@ -402,6 +402,54 @@ radv_amdgpu_winsys_bo_unmap(struct radeon_winsys_bo *_bo) | |||
| amdgpu_bo_cpu_unmap(bo->bo); | |||
| } | |||
| static struct radeon_winsys_bo * | |||
| radv_amdgpu_winsys_bo_from_ptr(struct radeon_winsys *_ws, | |||
| void *pointer, | |||
| uint64_t size) | |||
| { | |||
| struct radv_amdgpu_winsys *ws = radv_amdgpu_winsys(_ws); | |||
| amdgpu_bo_handle buf_handle; | |||
| struct radv_amdgpu_winsys_bo *bo; | |||
| uint64_t va; | |||
| amdgpu_va_handle va_handle; | |||
| bo = CALLOC_STRUCT(radv_amdgpu_winsys_bo); | |||
| if (!bo) | |||
| return NULL; | |||
| if (amdgpu_create_bo_from_user_mem(ws->dev, pointer, size, &buf_handle)) | |||
| goto error; | |||
| if (amdgpu_va_range_alloc(ws->dev, amdgpu_gpu_va_range_general, | |||
| size, 1 << 12, 0, &va, &va_handle, 0)) | |||
| goto error_va_alloc; | |||
| if (amdgpu_bo_va_op(buf_handle, 0, size, va, 0, AMDGPU_VA_OP_MAP)) | |||
| goto error_va_map; | |||
| /* Initialize it */ | |||
| bo->base.va = va; | |||
| bo->va_handle = va_handle; | |||
| bo->size = size; | |||
| bo->ref_count = 1; | |||
| bo->ws = ws; | |||
| bo->bo = buf_handle; | |||
| bo->initial_domain = RADEON_DOMAIN_GTT; | |||
| radv_amdgpu_add_buffer_to_global_list(bo); | |||
| return (struct radeon_winsys_bo *)bo; | |||
| error_va_map: | |||
| amdgpu_va_range_free(va_handle); | |||
| error_va_alloc: | |||
| amdgpu_bo_free(buf_handle); | |||
| error: | |||
| FREE(bo); | |||
| return NULL; | |||
| } | |||
| static struct radeon_winsys_bo * | |||
| radv_amdgpu_winsys_bo_from_fd(struct radeon_winsys *_ws, | |||
| int fd, unsigned *stride, | |||
| @@ -540,6 +588,7 @@ void radv_amdgpu_bo_init_functions(struct radv_amdgpu_winsys *ws) | |||
| ws->base.buffer_destroy = radv_amdgpu_winsys_bo_destroy; | |||
| ws->base.buffer_map = radv_amdgpu_winsys_bo_map; | |||
| ws->base.buffer_unmap = radv_amdgpu_winsys_bo_unmap; | |||
| ws->base.buffer_from_ptr = radv_amdgpu_winsys_bo_from_ptr; | |||
| ws->base.buffer_from_fd = radv_amdgpu_winsys_bo_from_fd; | |||
| ws->base.buffer_get_fd = radv_amdgpu_winsys_get_fd; | |||
| ws->base.buffer_set_metadata = radv_amdgpu_winsys_bo_set_metadata; | |||