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:
Fredrik Höglund 2018-01-25 18:12:14 +01:00
parent 5dd385f378
commit 5a38d8f103
6 changed files with 137 additions and 8 deletions

View File

@ -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(

View File

@ -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'),

View File

@ -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;
}

View File

@ -646,6 +646,7 @@ struct radv_device_memory {
uint32_t type_index;
VkDeviceSize map_size;
void * map;
void * user_ptr;
};

View File

@ -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);

View File

@ -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;