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:
@@ -810,6 +810,12 @@ void radv_GetPhysicalDeviceProperties2KHR(
|
|||||||
properties->maxDiscardRectangles = MAX_DISCARD_RECTANGLES;
|
properties->maxDiscardRectangles = MAX_DISCARD_RECTANGLES;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT: {
|
||||||
|
VkPhysicalDeviceExternalMemoryHostPropertiesEXT *properties =
|
||||||
|
(VkPhysicalDeviceExternalMemoryHostPropertiesEXT *) ext;
|
||||||
|
properties->minImportedHostPointerAlignment = 4096;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -923,6 +929,33 @@ void radv_GetPhysicalDeviceMemoryProperties2KHR(
|
|||||||
&pMemoryProperties->memoryProperties);
|
&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
|
static enum radeon_ctx_priority
|
||||||
radv_get_queue_global_priority(const VkDeviceQueueGlobalPriorityCreateInfoEXT *pObj)
|
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);
|
vk_find_struct_const(pAllocateInfo->pNext, MEMORY_DEDICATED_ALLOCATE_INFO_KHR);
|
||||||
const VkExportMemoryAllocateInfoKHR *export_info =
|
const VkExportMemoryAllocateInfoKHR *export_info =
|
||||||
vk_find_struct_const(pAllocateInfo->pNext, EXPORT_MEMORY_ALLOCATE_INFO_KHR);
|
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 =
|
const struct wsi_memory_allocate_info *wsi_info =
|
||||||
vk_find_struct_const(pAllocateInfo->pNext, WSI_MEMORY_ALLOCATE_INFO_MESA);
|
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->buffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mem->user_ptr = NULL;
|
||||||
|
|
||||||
if (import_info) {
|
if (import_info) {
|
||||||
assert(import_info->handleType ==
|
assert(import_info->handleType ==
|
||||||
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR ||
|
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);
|
uint64_t alloc_size = align_u64(pAllocateInfo->allocationSize, 4096);
|
||||||
if (mem_type_index == RADV_MEM_TYPE_GTT_WRITE_COMBINE ||
|
if (mem_type_index == RADV_MEM_TYPE_GTT_WRITE_COMBINE ||
|
||||||
mem_type_index == RADV_MEM_TYPE_GTT_CACHED)
|
mem_type_index == RADV_MEM_TYPE_GTT_CACHED)
|
||||||
@@ -2362,7 +2413,11 @@ VkResult radv_MapMemory(
|
|||||||
return VK_SUCCESS;
|
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) {
|
if (*ppData) {
|
||||||
*ppData += offset;
|
*ppData += offset;
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
@@ -2381,7 +2436,8 @@ void radv_UnmapMemory(
|
|||||||
if (mem == NULL)
|
if (mem == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
device->ws->buffer_unmap(mem->bo);
|
if (mem->user_ptr == NULL)
|
||||||
|
device->ws->buffer_unmap(mem->bo);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkResult radv_FlushMappedMemoryRanges(
|
VkResult radv_FlushMappedMemoryRanges(
|
||||||
|
@@ -85,6 +85,7 @@ EXTENSIONS = [
|
|||||||
Extension('VK_EXT_debug_report', 9, True),
|
Extension('VK_EXT_debug_report', 9, True),
|
||||||
Extension('VK_EXT_discard_rectangles', 1, True),
|
Extension('VK_EXT_discard_rectangles', 1, True),
|
||||||
Extension('VK_EXT_external_memory_dma_buf', 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_EXT_global_priority', 1, 'device->rad_info.has_ctx_priority'),
|
||||||
Extension('VK_AMD_draw_indirect_count', 1, True),
|
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'),
|
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
|
static void
|
||||||
get_external_image_format_properties(const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo,
|
get_external_image_format_properties(const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo,
|
||||||
|
VkExternalMemoryHandleTypeFlagBitsKHR handleType,
|
||||||
VkExternalMemoryPropertiesKHR *external_properties)
|
VkExternalMemoryPropertiesKHR *external_properties)
|
||||||
{
|
{
|
||||||
VkExternalMemoryFeatureFlagBitsKHR flags = 0;
|
VkExternalMemoryFeatureFlagBitsKHR flags = 0;
|
||||||
VkExternalMemoryHandleTypeFlagsKHR export_flags = 0;
|
VkExternalMemoryHandleTypeFlagsKHR export_flags = 0;
|
||||||
VkExternalMemoryHandleTypeFlagsKHR compat_flags = 0;
|
VkExternalMemoryHandleTypeFlagsKHR compat_flags = 0;
|
||||||
switch (pImageFormatInfo->type) {
|
switch (handleType) {
|
||||||
case VK_IMAGE_TYPE_2D:
|
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;
|
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
|
||||||
compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR |
|
switch (pImageFormatInfo->type) {
|
||||||
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -1246,7 +1258,9 @@ VkResult radv_GetPhysicalDeviceImageFormatProperties2KHR(
|
|||||||
switch (external_info->handleType) {
|
switch (external_info->handleType) {
|
||||||
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
|
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
|
||||||
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
/* From the Vulkan 1.0.42 spec:
|
/* 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 |
|
compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR |
|
||||||
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
|
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
|
||||||
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -646,6 +646,7 @@ struct radv_device_memory {
|
|||||||
uint32_t type_index;
|
uint32_t type_index;
|
||||||
VkDeviceSize map_size;
|
VkDeviceSize map_size;
|
||||||
void * map;
|
void * map;
|
||||||
|
void * user_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -200,6 +200,10 @@ struct radeon_winsys {
|
|||||||
void (*buffer_destroy)(struct radeon_winsys_bo *bo);
|
void (*buffer_destroy)(struct radeon_winsys_bo *bo);
|
||||||
void *(*buffer_map)(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,
|
struct radeon_winsys_bo *(*buffer_from_fd)(struct radeon_winsys *ws,
|
||||||
int fd,
|
int fd,
|
||||||
unsigned *stride, unsigned *offset);
|
unsigned *stride, unsigned *offset);
|
||||||
|
@@ -402,6 +402,54 @@ radv_amdgpu_winsys_bo_unmap(struct radeon_winsys_bo *_bo)
|
|||||||
amdgpu_bo_cpu_unmap(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 *
|
static struct radeon_winsys_bo *
|
||||||
radv_amdgpu_winsys_bo_from_fd(struct radeon_winsys *_ws,
|
radv_amdgpu_winsys_bo_from_fd(struct radeon_winsys *_ws,
|
||||||
int fd, unsigned *stride,
|
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_destroy = radv_amdgpu_winsys_bo_destroy;
|
||||||
ws->base.buffer_map = radv_amdgpu_winsys_bo_map;
|
ws->base.buffer_map = radv_amdgpu_winsys_bo_map;
|
||||||
ws->base.buffer_unmap = radv_amdgpu_winsys_bo_unmap;
|
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_from_fd = radv_amdgpu_winsys_bo_from_fd;
|
||||||
ws->base.buffer_get_fd = radv_amdgpu_winsys_get_fd;
|
ws->base.buffer_get_fd = radv_amdgpu_winsys_get_fd;
|
||||||
ws->base.buffer_set_metadata = radv_amdgpu_winsys_bo_set_metadata;
|
ws->base.buffer_set_metadata = radv_amdgpu_winsys_bo_set_metadata;
|
||||||
|
Reference in New Issue
Block a user