/* device memory commands */
+static inline VkResult
+vn_device_memory_alloc_simple(struct vn_device *dev,
+ struct vn_device_memory *mem,
+ const VkMemoryAllocateInfo *alloc_info)
+{
+ VkDevice dev_handle = vn_device_to_handle(dev);
+ VkDeviceMemory mem_handle = vn_device_memory_to_handle(mem);
+ return vn_call_vkAllocateMemory(dev->instance, dev_handle, alloc_info,
+ NULL, &mem_handle);
+}
+
+static inline void
+vn_device_memory_free_simple(struct vn_device *dev,
+ struct vn_device_memory *mem)
+{
+ VkDevice dev_handle = vn_device_to_handle(dev);
+ VkDeviceMemory mem_handle = vn_device_memory_to_handle(mem);
+ vn_async_vkFreeMemory(dev->instance, dev_handle, mem_handle, NULL);
+}
+
static VkResult
vn_device_memory_pool_grow_alloc(struct vn_device *dev,
uint32_t mem_type_index,
VkDeviceSize size,
struct vn_device_memory **out_mem)
{
- VkDevice dev_handle = vn_device_to_handle(dev);
const VkAllocationCallbacks *alloc = &dev->base.base.alloc;
- struct vn_device_memory *mem = NULL;
- VkDeviceMemory mem_handle = VK_NULL_HANDLE;
- VkResult result;
-
- mem = vk_zalloc(alloc, sizeof(*mem), VN_DEFAULT_ALIGN,
- VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
+ const VkMemoryAllocateInfo alloc_info = {
+ .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
+ .allocationSize = size,
+ .memoryTypeIndex = mem_type_index,
+ };
+ struct vn_device_memory *mem =
+ vk_zalloc(alloc, sizeof(*mem), VN_DEFAULT_ALIGN,
+ VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
if (!mem)
return VK_ERROR_OUT_OF_HOST_MEMORY;
mem->type =
dev->physical_device->memory_properties.memoryTypes[mem_type_index];
- mem_handle = vn_device_memory_to_handle(mem);
- result = vn_call_vkAllocateMemory(
- dev->instance, dev_handle,
- &(const VkMemoryAllocateInfo){
- .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
- .allocationSize = size,
- .memoryTypeIndex = mem_type_index,
- },
- NULL, &mem_handle);
- if (result != VK_SUCCESS) {
- mem_handle = VK_NULL_HANDLE;
- goto fail;
- }
+ VkResult result = vn_device_memory_alloc_simple(dev, mem, &alloc_info);
+ if (result != VK_SUCCESS)
+ goto obj_fini;
result = vn_renderer_bo_create_from_device_memory(
dev->renderer, mem->size, mem->base.id, mem->type.propertyFlags, 0,
&mem->base_bo);
- if (result != VK_SUCCESS) {
- assert(!mem->base_bo);
- goto fail;
- }
+ if (result != VK_SUCCESS)
+ goto mem_free;
result =
vn_instance_submit_roundtrip(dev->instance, &mem->bo_roundtrip_seqno);
if (result != VK_SUCCESS)
- goto fail;
+ goto bo_unref;
mem->bo_roundtrip_seqno_valid = true;
*out_mem = mem;
return VK_SUCCESS;
-fail:
- if (mem->base_bo)
- vn_renderer_bo_unref(dev->renderer, mem->base_bo);
- if (mem_handle != VK_NULL_HANDLE)
- vn_async_vkFreeMemory(dev->instance, dev_handle, mem_handle, NULL);
+bo_unref:
+ vn_renderer_bo_unref(dev->renderer, mem->base_bo);
+mem_free:
+ vn_device_memory_free_simple(dev, mem);
+obj_fini:
vn_object_base_fini(&mem->base);
vk_free(alloc, mem);
return result;
if (pool_mem->bo_roundtrip_seqno_valid)
vn_instance_wait_roundtrip(dev->instance, pool_mem->bo_roundtrip_seqno);
- vn_async_vkFreeMemory(dev->instance, vn_device_to_handle(dev),
- vn_device_memory_to_handle(pool_mem), NULL);
+ vn_device_memory_free_simple(dev, pool_mem);
vn_object_base_fini(&pool_mem->base);
vk_free(alloc, pool_mem);
}
struct vn_device_memory *mem,
uint32_t mem_type_index)
{
- const VkDeviceSize pool_size = 16 * 1024 * 1024;
+ static const VkDeviceSize pool_size = 16 * 1024 * 1024;
/* TODO fix https://gitlab.freedesktop.org/mesa/mesa/-/issues/9351
* Before that, we use 64K default alignment because some GPUs have 64K
* pages. It is also required by newer Intel GPUs. Meanwhile, use prior 4K
* align on implementations known to fit.
*/
- const VkDeviceSize pool_align =
- dev->physical_device->renderer_driver_id == VK_DRIVER_ID_ARM_PROPRIETARY
- ? 4096
- : 64 * 1024;
+ const bool is_renderer_mali = dev->physical_device->renderer_driver_id ==
+ VK_DRIVER_ID_ARM_PROPRIETARY;
+ const VkDeviceSize pool_align = is_renderer_mali ? 4096 : 64 * 1024;
struct vn_device_memory_pool *pool = &dev->memory_pools[mem_type_index];
assert(mem->size <= pool_size);
bool force_unmappable,
int fd)
{
- VkDevice device = vn_device_to_handle(dev);
- VkDeviceMemory memory = vn_device_memory_to_handle(mem);
- const VkPhysicalDeviceMemoryProperties *mem_props =
- &dev->physical_device->memory_properties;
- VkMemoryPropertyFlags mem_flags =
- mem_props->memoryTypes[alloc_info->memoryTypeIndex].propertyFlags;
- struct vn_renderer_bo *bo;
- VkResult result = VK_SUCCESS;
-
- if (force_unmappable)
- mem_flags &= ~VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
+ const VkMemoryType *mem_type =
+ &dev->physical_device->memory_properties
+ .memoryTypes[alloc_info->memoryTypeIndex];
- result = vn_renderer_bo_create_from_dma_buf(
- dev->renderer, alloc_info->allocationSize, fd, mem_flags, &bo);
+ struct vn_renderer_bo *bo;
+ VkResult result = vn_renderer_bo_create_from_dma_buf(
+ dev->renderer, alloc_info->allocationSize, fd,
+ force_unmappable ? 0 : mem_type->propertyFlags, &bo);
if (result != VK_SUCCESS)
return result;
vn_instance_roundtrip(dev->instance);
- /* XXX fix VkImportMemoryResourceInfoMESA to support memory planes */
const VkImportMemoryResourceInfoMESA import_memory_resource_info = {
.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_RESOURCE_INFO_MESA,
.pNext = alloc_info->pNext,
.allocationSize = alloc_info->allocationSize,
.memoryTypeIndex = alloc_info->memoryTypeIndex,
};
- result = vn_call_vkAllocateMemory(dev->instance, device,
- &memory_allocate_info, NULL, &memory);
+ result = vn_device_memory_alloc_simple(dev, mem, &memory_allocate_info);
if (result != VK_SUCCESS) {
vn_renderer_bo_unref(dev->renderer, bo);
return result;
const VkMemoryAllocateInfo *alloc_info,
VkExternalMemoryHandleTypeFlags external_handles)
{
- VkDevice dev_handle = vn_device_to_handle(dev);
- VkDeviceMemory mem_handle = vn_device_memory_to_handle(mem);
- VkResult result = VK_SUCCESS;
-
- result = vn_renderer_bo_create_from_device_memory(
+ VkResult result = vn_renderer_bo_create_from_device_memory(
dev->renderer, mem->size, 0, mem->type.propertyFlags, external_handles,
&mem->base_bo);
if (result != VK_SUCCESS) {
vn_instance_roundtrip(dev->instance);
- result = vn_call_vkAllocateMemory(
- dev->instance, dev_handle, &memory_allocate_info, NULL, &mem_handle);
+ result = vn_device_memory_alloc_simple(dev, mem, &memory_allocate_info);
if (result != VK_SUCCESS) {
vn_renderer_bo_unref(dev->renderer, mem->base_bo);
return result;
}
static VkResult
-vn_device_memory_alloc_generic(
- struct vn_device *dev,
- struct vn_device_memory *mem,
- const VkMemoryAllocateInfo *alloc_info,
- VkExternalMemoryHandleTypeFlags external_handles)
+vn_device_memory_alloc_export(struct vn_device *dev,
+ struct vn_device_memory *mem,
+ const VkMemoryAllocateInfo *alloc_info,
+ VkExternalMemoryHandleTypeFlags external_handles)
{
- VkDevice dev_handle = vn_device_to_handle(dev);
- VkDeviceMemory mem_handle = vn_device_memory_to_handle(mem);
- VkResult result = VK_SUCCESS;
-
- result = vn_call_vkAllocateMemory(dev->instance, dev_handle, alloc_info,
- NULL, &mem_handle);
- if (result != VK_SUCCESS || !external_handles)
+ VkResult result = vn_device_memory_alloc_simple(dev, mem, alloc_info);
+ if (result != VK_SUCCESS)
return result;
result = vn_renderer_bo_create_from_device_memory(
dev->renderer, mem->size, mem->base.id, mem->type.propertyFlags,
external_handles, &mem->base_bo);
if (result != VK_SUCCESS) {
- vn_async_vkFreeMemory(dev->instance, dev_handle, mem_handle, NULL);
+ vn_device_memory_free_simple(dev, mem);
return result;
}
vn_instance_submit_roundtrip(dev->instance, &mem->bo_roundtrip_seqno);
if (result != VK_SUCCESS) {
vn_renderer_bo_unref(dev->renderer, mem->base_bo);
- vn_async_vkFreeMemory(dev->instance, dev_handle, mem_handle, NULL);
+ vn_device_memory_free_simple(dev, mem);
return result;
}
if (renderer_info->has_guest_vram) {
return vn_device_memory_alloc_guest_vram(dev, mem, alloc_info,
external_handles);
+ } else if (external_handles) {
+ return vn_device_memory_alloc_export(dev, mem, alloc_info,
+ external_handles);
+ } else {
+ return vn_device_memory_alloc_simple(dev, mem, alloc_info);
}
-
- return vn_device_memory_alloc_generic(dev, mem, alloc_info,
- external_handles);
}
static void
if (mem->bo_roundtrip_seqno_valid)
vn_instance_wait_roundtrip(dev->instance, mem->bo_roundtrip_seqno);
- vn_async_vkFreeMemory(dev->instance, device, memory, NULL);
+ vn_device_memory_free_simple(dev, mem);
}
if (mem->ahb)