radv: implement VK_EXT_external_memory_host
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>
This commit is contained in:
parent
5dd385f378
commit
5a38d8f103
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue