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>
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;
}
&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)
{
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);
mem->buffer = NULL;
}
+ mem->user_ptr = NULL;
+
if (import_info) {
assert(import_info->handleType ==
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR ||
}
}
+ 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)
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;
if (mem == NULL)
return;
- device->ws->buffer_unmap(mem->bo);
+ if (mem->user_ptr == NULL)
+ device->ws->buffer_unmap(mem->bo);
}
VkResult radv_FlushMappedMemoryRanges(
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'),
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;
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:
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;
}
uint32_t type_index;
VkDeviceSize map_size;
void * map;
+ void * user_ptr;
};
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);
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,
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;