1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2019 Google LLC 3bf215546Sopenharmony_ci * SPDX-License-Identifier: MIT 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * based in part on anv and radv which are: 6bf215546Sopenharmony_ci * Copyright © 2015 Intel Corporation 7bf215546Sopenharmony_ci * Copyright © 2016 Red Hat. 8bf215546Sopenharmony_ci * Copyright © 2016 Bas Nieuwenhuizen 9bf215546Sopenharmony_ci */ 10bf215546Sopenharmony_ci 11bf215546Sopenharmony_ci#include "vn_device_memory.h" 12bf215546Sopenharmony_ci 13bf215546Sopenharmony_ci#include "venus-protocol/vn_protocol_driver_device_memory.h" 14bf215546Sopenharmony_ci#include "venus-protocol/vn_protocol_driver_transport.h" 15bf215546Sopenharmony_ci 16bf215546Sopenharmony_ci#include "vn_android.h" 17bf215546Sopenharmony_ci#include "vn_buffer.h" 18bf215546Sopenharmony_ci#include "vn_device.h" 19bf215546Sopenharmony_ci#include "vn_image.h" 20bf215546Sopenharmony_ci#include "vn_physical_device.h" 21bf215546Sopenharmony_ci 22bf215546Sopenharmony_ci/* device memory commands */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_cistatic VkResult 25bf215546Sopenharmony_civn_device_memory_pool_grow_alloc(struct vn_device *dev, 26bf215546Sopenharmony_ci uint32_t mem_type_index, 27bf215546Sopenharmony_ci VkDeviceSize size, 28bf215546Sopenharmony_ci struct vn_device_memory **out_mem) 29bf215546Sopenharmony_ci{ 30bf215546Sopenharmony_ci VkDevice dev_handle = vn_device_to_handle(dev); 31bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = &dev->base.base.alloc; 32bf215546Sopenharmony_ci const VkPhysicalDeviceMemoryProperties *mem_props = 33bf215546Sopenharmony_ci &dev->physical_device->memory_properties.memoryProperties; 34bf215546Sopenharmony_ci const VkMemoryPropertyFlags mem_flags = 35bf215546Sopenharmony_ci mem_props->memoryTypes[mem_type_index].propertyFlags; 36bf215546Sopenharmony_ci struct vn_device_memory *mem = NULL; 37bf215546Sopenharmony_ci VkDeviceMemory mem_handle = VK_NULL_HANDLE; 38bf215546Sopenharmony_ci VkResult result; 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci mem = vk_zalloc(alloc, sizeof(*mem), VN_DEFAULT_ALIGN, 41bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); 42bf215546Sopenharmony_ci if (!mem) 43bf215546Sopenharmony_ci return VK_ERROR_OUT_OF_HOST_MEMORY; 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci vn_object_base_init(&mem->base, VK_OBJECT_TYPE_DEVICE_MEMORY, &dev->base); 46bf215546Sopenharmony_ci mem->size = size; 47bf215546Sopenharmony_ci mem->flags = mem_flags; 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci mem_handle = vn_device_memory_to_handle(mem); 50bf215546Sopenharmony_ci result = vn_call_vkAllocateMemory( 51bf215546Sopenharmony_ci dev->instance, dev_handle, 52bf215546Sopenharmony_ci &(const VkMemoryAllocateInfo){ 53bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, 54bf215546Sopenharmony_ci .allocationSize = size, 55bf215546Sopenharmony_ci .memoryTypeIndex = mem_type_index, 56bf215546Sopenharmony_ci }, 57bf215546Sopenharmony_ci NULL, &mem_handle); 58bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 59bf215546Sopenharmony_ci mem_handle = VK_NULL_HANDLE; 60bf215546Sopenharmony_ci goto fail; 61bf215546Sopenharmony_ci } 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci result = vn_renderer_bo_create_from_device_memory( 64bf215546Sopenharmony_ci dev->renderer, mem->size, mem->base.id, mem->flags, 0, &mem->base_bo); 65bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 66bf215546Sopenharmony_ci assert(!mem->base_bo); 67bf215546Sopenharmony_ci goto fail; 68bf215546Sopenharmony_ci } 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci result = 71bf215546Sopenharmony_ci vn_instance_submit_roundtrip(dev->instance, &mem->bo_roundtrip_seqno); 72bf215546Sopenharmony_ci if (result != VK_SUCCESS) 73bf215546Sopenharmony_ci goto fail; 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci mem->bo_roundtrip_seqno_valid = true; 76bf215546Sopenharmony_ci *out_mem = mem; 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_ci return VK_SUCCESS; 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_cifail: 81bf215546Sopenharmony_ci if (mem->base_bo) 82bf215546Sopenharmony_ci vn_renderer_bo_unref(dev->renderer, mem->base_bo); 83bf215546Sopenharmony_ci if (mem_handle != VK_NULL_HANDLE) 84bf215546Sopenharmony_ci vn_async_vkFreeMemory(dev->instance, dev_handle, mem_handle, NULL); 85bf215546Sopenharmony_ci vn_object_base_fini(&mem->base); 86bf215546Sopenharmony_ci vk_free(alloc, mem); 87bf215546Sopenharmony_ci return result; 88bf215546Sopenharmony_ci} 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_cistatic struct vn_device_memory * 91bf215546Sopenharmony_civn_device_memory_pool_ref(struct vn_device *dev, 92bf215546Sopenharmony_ci struct vn_device_memory *pool_mem) 93bf215546Sopenharmony_ci{ 94bf215546Sopenharmony_ci assert(pool_mem->base_bo); 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci vn_renderer_bo_ref(dev->renderer, pool_mem->base_bo); 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci return pool_mem; 99bf215546Sopenharmony_ci} 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_cistatic void 102bf215546Sopenharmony_civn_device_memory_pool_unref(struct vn_device *dev, 103bf215546Sopenharmony_ci struct vn_device_memory *pool_mem) 104bf215546Sopenharmony_ci{ 105bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = &dev->base.base.alloc; 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci assert(pool_mem->base_bo); 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci if (!vn_renderer_bo_unref(dev->renderer, pool_mem->base_bo)) 110bf215546Sopenharmony_ci return; 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_ci /* wait on valid bo_roundtrip_seqno before vkFreeMemory */ 113bf215546Sopenharmony_ci if (pool_mem->bo_roundtrip_seqno_valid) 114bf215546Sopenharmony_ci vn_instance_wait_roundtrip(dev->instance, pool_mem->bo_roundtrip_seqno); 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_ci vn_async_vkFreeMemory(dev->instance, vn_device_to_handle(dev), 117bf215546Sopenharmony_ci vn_device_memory_to_handle(pool_mem), NULL); 118bf215546Sopenharmony_ci vn_object_base_fini(&pool_mem->base); 119bf215546Sopenharmony_ci vk_free(alloc, pool_mem); 120bf215546Sopenharmony_ci} 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_civoid 123bf215546Sopenharmony_civn_device_memory_pool_fini(struct vn_device *dev, uint32_t mem_type_index) 124bf215546Sopenharmony_ci{ 125bf215546Sopenharmony_ci struct vn_device_memory_pool *pool = &dev->memory_pools[mem_type_index]; 126bf215546Sopenharmony_ci if (pool->memory) 127bf215546Sopenharmony_ci vn_device_memory_pool_unref(dev, pool->memory); 128bf215546Sopenharmony_ci mtx_destroy(&pool->mutex); 129bf215546Sopenharmony_ci} 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_cistatic VkResult 132bf215546Sopenharmony_civn_device_memory_pool_grow_locked(struct vn_device *dev, 133bf215546Sopenharmony_ci uint32_t mem_type_index, 134bf215546Sopenharmony_ci VkDeviceSize size) 135bf215546Sopenharmony_ci{ 136bf215546Sopenharmony_ci struct vn_device_memory *mem; 137bf215546Sopenharmony_ci VkResult result = 138bf215546Sopenharmony_ci vn_device_memory_pool_grow_alloc(dev, mem_type_index, size, &mem); 139bf215546Sopenharmony_ci if (result != VK_SUCCESS) 140bf215546Sopenharmony_ci return result; 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci struct vn_device_memory_pool *pool = &dev->memory_pools[mem_type_index]; 143bf215546Sopenharmony_ci if (pool->memory) 144bf215546Sopenharmony_ci vn_device_memory_pool_unref(dev, pool->memory); 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_ci pool->memory = mem; 147bf215546Sopenharmony_ci pool->used = 0; 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci return VK_SUCCESS; 150bf215546Sopenharmony_ci} 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_cistatic VkResult 153bf215546Sopenharmony_civn_device_memory_pool_suballocate(struct vn_device *dev, 154bf215546Sopenharmony_ci struct vn_device_memory *mem, 155bf215546Sopenharmony_ci uint32_t mem_type_index) 156bf215546Sopenharmony_ci{ 157bf215546Sopenharmony_ci const VkDeviceSize pool_size = 16 * 1024 * 1024; 158bf215546Sopenharmony_ci /* XXX We don't know the alignment requirement. Use 64K because some GPUs 159bf215546Sopenharmony_ci * have 64K pages. It is also required by newer Intel GPUs. But really we 160bf215546Sopenharmony_ci * should require kernel 5.12+, where there is no KVM memslot limit, and 161bf215546Sopenharmony_ci * remove this whole thing. 162bf215546Sopenharmony_ci */ 163bf215546Sopenharmony_ci const VkDeviceSize pool_align = 64 * 1024; 164bf215546Sopenharmony_ci struct vn_device_memory_pool *pool = &dev->memory_pools[mem_type_index]; 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci assert(mem->size <= pool_size); 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci mtx_lock(&pool->mutex); 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci if (!pool->memory || pool->used + mem->size > pool_size) { 171bf215546Sopenharmony_ci VkResult result = 172bf215546Sopenharmony_ci vn_device_memory_pool_grow_locked(dev, mem_type_index, pool_size); 173bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 174bf215546Sopenharmony_ci mtx_unlock(&pool->mutex); 175bf215546Sopenharmony_ci return result; 176bf215546Sopenharmony_ci } 177bf215546Sopenharmony_ci } 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci mem->base_memory = vn_device_memory_pool_ref(dev, pool->memory); 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci /* point mem->base_bo at pool base_bo and assign base_offset accordingly */ 182bf215546Sopenharmony_ci mem->base_bo = pool->memory->base_bo; 183bf215546Sopenharmony_ci mem->base_offset = pool->used; 184bf215546Sopenharmony_ci pool->used += align64(mem->size, pool_align); 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_ci mtx_unlock(&pool->mutex); 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci return VK_SUCCESS; 189bf215546Sopenharmony_ci} 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_cistatic bool 192bf215546Sopenharmony_civn_device_memory_should_suballocate(const struct vn_device *dev, 193bf215546Sopenharmony_ci const VkMemoryAllocateInfo *alloc_info, 194bf215546Sopenharmony_ci const VkMemoryPropertyFlags flags) 195bf215546Sopenharmony_ci{ 196bf215546Sopenharmony_ci const struct vn_instance *instance = dev->physical_device->instance; 197bf215546Sopenharmony_ci const struct vn_renderer_info *renderer = &instance->renderer->info; 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_ci if (renderer->has_guest_vram) 200bf215546Sopenharmony_ci return false; 201bf215546Sopenharmony_ci 202bf215546Sopenharmony_ci /* We should not support suballocations because apps can do better. But 203bf215546Sopenharmony_ci * each BO takes up a KVM memslot currently and some CTS tests exhausts 204bf215546Sopenharmony_ci * them. This might not be needed on newer (host) kernels where there are 205bf215546Sopenharmony_ci * many more KVM memslots. 206bf215546Sopenharmony_ci */ 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_ci /* consider host-visible memory only */ 209bf215546Sopenharmony_ci if (!(flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) 210bf215546Sopenharmony_ci return false; 211bf215546Sopenharmony_ci 212bf215546Sopenharmony_ci /* reject larger allocations */ 213bf215546Sopenharmony_ci if (alloc_info->allocationSize > 64 * 1024) 214bf215546Sopenharmony_ci return false; 215bf215546Sopenharmony_ci 216bf215546Sopenharmony_ci /* reject if there is any pnext struct other than 217bf215546Sopenharmony_ci * VkMemoryDedicatedAllocateInfo, or if dedicated allocation is required 218bf215546Sopenharmony_ci */ 219bf215546Sopenharmony_ci if (alloc_info->pNext) { 220bf215546Sopenharmony_ci const VkMemoryDedicatedAllocateInfo *dedicated = alloc_info->pNext; 221bf215546Sopenharmony_ci if (dedicated->sType != 222bf215546Sopenharmony_ci VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO || 223bf215546Sopenharmony_ci dedicated->pNext) 224bf215546Sopenharmony_ci return false; 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci const struct vn_image *img = vn_image_from_handle(dedicated->image); 227bf215546Sopenharmony_ci if (img) { 228bf215546Sopenharmony_ci for (uint32_t i = 0; i < ARRAY_SIZE(img->requirements); i++) { 229bf215546Sopenharmony_ci if (img->requirements[i].dedicated.requiresDedicatedAllocation) 230bf215546Sopenharmony_ci return false; 231bf215546Sopenharmony_ci } 232bf215546Sopenharmony_ci } 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci const struct vn_buffer *buf = vn_buffer_from_handle(dedicated->buffer); 235bf215546Sopenharmony_ci if (buf && buf->requirements.dedicated.requiresDedicatedAllocation) 236bf215546Sopenharmony_ci return false; 237bf215546Sopenharmony_ci } 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci return true; 240bf215546Sopenharmony_ci} 241bf215546Sopenharmony_ci 242bf215546Sopenharmony_ciVkResult 243bf215546Sopenharmony_civn_device_memory_import_dma_buf(struct vn_device *dev, 244bf215546Sopenharmony_ci struct vn_device_memory *mem, 245bf215546Sopenharmony_ci const VkMemoryAllocateInfo *alloc_info, 246bf215546Sopenharmony_ci bool force_unmappable, 247bf215546Sopenharmony_ci int fd) 248bf215546Sopenharmony_ci{ 249bf215546Sopenharmony_ci VkDevice device = vn_device_to_handle(dev); 250bf215546Sopenharmony_ci VkDeviceMemory memory = vn_device_memory_to_handle(mem); 251bf215546Sopenharmony_ci const VkPhysicalDeviceMemoryProperties *mem_props = 252bf215546Sopenharmony_ci &dev->physical_device->memory_properties.memoryProperties; 253bf215546Sopenharmony_ci VkMemoryPropertyFlags mem_flags = 254bf215546Sopenharmony_ci mem_props->memoryTypes[alloc_info->memoryTypeIndex].propertyFlags; 255bf215546Sopenharmony_ci struct vn_renderer_bo *bo; 256bf215546Sopenharmony_ci VkResult result = VK_SUCCESS; 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_ci if (force_unmappable) 259bf215546Sopenharmony_ci mem_flags &= ~VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; 260bf215546Sopenharmony_ci 261bf215546Sopenharmony_ci result = vn_renderer_bo_create_from_dma_buf( 262bf215546Sopenharmony_ci dev->renderer, alloc_info->allocationSize, fd, mem_flags, &bo); 263bf215546Sopenharmony_ci if (result != VK_SUCCESS) 264bf215546Sopenharmony_ci return result; 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ci vn_instance_roundtrip(dev->instance); 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci /* XXX fix VkImportMemoryResourceInfoMESA to support memory planes */ 269bf215546Sopenharmony_ci const VkImportMemoryResourceInfoMESA import_memory_resource_info = { 270bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_RESOURCE_INFO_MESA, 271bf215546Sopenharmony_ci .pNext = alloc_info->pNext, 272bf215546Sopenharmony_ci .resourceId = bo->res_id, 273bf215546Sopenharmony_ci }; 274bf215546Sopenharmony_ci const VkMemoryAllocateInfo memory_allocate_info = { 275bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, 276bf215546Sopenharmony_ci .pNext = &import_memory_resource_info, 277bf215546Sopenharmony_ci .allocationSize = alloc_info->allocationSize, 278bf215546Sopenharmony_ci .memoryTypeIndex = alloc_info->memoryTypeIndex, 279bf215546Sopenharmony_ci }; 280bf215546Sopenharmony_ci result = vn_call_vkAllocateMemory(dev->instance, device, 281bf215546Sopenharmony_ci &memory_allocate_info, NULL, &memory); 282bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 283bf215546Sopenharmony_ci vn_renderer_bo_unref(dev->renderer, bo); 284bf215546Sopenharmony_ci return result; 285bf215546Sopenharmony_ci } 286bf215546Sopenharmony_ci 287bf215546Sopenharmony_ci /* need to close import fd on success to avoid fd leak */ 288bf215546Sopenharmony_ci close(fd); 289bf215546Sopenharmony_ci mem->base_bo = bo; 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ci return VK_SUCCESS; 292bf215546Sopenharmony_ci} 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_cistatic VkResult 295bf215546Sopenharmony_civn_device_memory_alloc_guest_vram( 296bf215546Sopenharmony_ci struct vn_device *dev, 297bf215546Sopenharmony_ci struct vn_device_memory *mem, 298bf215546Sopenharmony_ci const VkMemoryAllocateInfo *alloc_info, 299bf215546Sopenharmony_ci VkExternalMemoryHandleTypeFlags external_handles) 300bf215546Sopenharmony_ci{ 301bf215546Sopenharmony_ci VkDevice dev_handle = vn_device_to_handle(dev); 302bf215546Sopenharmony_ci VkDeviceMemory mem_handle = vn_device_memory_to_handle(mem); 303bf215546Sopenharmony_ci VkResult result = VK_SUCCESS; 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci result = vn_renderer_bo_create_from_device_memory( 306bf215546Sopenharmony_ci dev->renderer, mem->size, 0, mem->flags, external_handles, 307bf215546Sopenharmony_ci &mem->base_bo); 308bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 309bf215546Sopenharmony_ci return result; 310bf215546Sopenharmony_ci } 311bf215546Sopenharmony_ci 312bf215546Sopenharmony_ci const VkImportMemoryResourceInfoMESA import_memory_resource_info = { 313bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_RESOURCE_INFO_MESA, 314bf215546Sopenharmony_ci .pNext = alloc_info->pNext, 315bf215546Sopenharmony_ci .resourceId = mem->base_bo->res_id, 316bf215546Sopenharmony_ci }; 317bf215546Sopenharmony_ci 318bf215546Sopenharmony_ci const VkMemoryAllocateInfo memory_allocate_info = { 319bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, 320bf215546Sopenharmony_ci .pNext = &import_memory_resource_info, 321bf215546Sopenharmony_ci .allocationSize = alloc_info->allocationSize, 322bf215546Sopenharmony_ci .memoryTypeIndex = alloc_info->memoryTypeIndex, 323bf215546Sopenharmony_ci }; 324bf215546Sopenharmony_ci 325bf215546Sopenharmony_ci vn_instance_roundtrip(dev->instance); 326bf215546Sopenharmony_ci 327bf215546Sopenharmony_ci result = vn_call_vkAllocateMemory( 328bf215546Sopenharmony_ci dev->instance, dev_handle, &memory_allocate_info, NULL, &mem_handle); 329bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 330bf215546Sopenharmony_ci vn_renderer_bo_unref(dev->renderer, mem->base_bo); 331bf215546Sopenharmony_ci return result; 332bf215546Sopenharmony_ci } 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci result = 335bf215546Sopenharmony_ci vn_instance_submit_roundtrip(dev->instance, &mem->bo_roundtrip_seqno); 336bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 337bf215546Sopenharmony_ci vn_renderer_bo_unref(dev->renderer, mem->base_bo); 338bf215546Sopenharmony_ci vn_async_vkFreeMemory(dev->instance, dev_handle, mem_handle, NULL); 339bf215546Sopenharmony_ci return result; 340bf215546Sopenharmony_ci } 341bf215546Sopenharmony_ci 342bf215546Sopenharmony_ci mem->bo_roundtrip_seqno_valid = true; 343bf215546Sopenharmony_ci 344bf215546Sopenharmony_ci return VK_SUCCESS; 345bf215546Sopenharmony_ci} 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_cistatic VkResult 348bf215546Sopenharmony_civn_device_memory_alloc_generic( 349bf215546Sopenharmony_ci struct vn_device *dev, 350bf215546Sopenharmony_ci struct vn_device_memory *mem, 351bf215546Sopenharmony_ci const VkMemoryAllocateInfo *alloc_info, 352bf215546Sopenharmony_ci VkExternalMemoryHandleTypeFlags external_handles) 353bf215546Sopenharmony_ci{ 354bf215546Sopenharmony_ci VkDevice dev_handle = vn_device_to_handle(dev); 355bf215546Sopenharmony_ci VkDeviceMemory mem_handle = vn_device_memory_to_handle(mem); 356bf215546Sopenharmony_ci VkResult result = VK_SUCCESS; 357bf215546Sopenharmony_ci 358bf215546Sopenharmony_ci result = vn_call_vkAllocateMemory(dev->instance, dev_handle, alloc_info, 359bf215546Sopenharmony_ci NULL, &mem_handle); 360bf215546Sopenharmony_ci if (result != VK_SUCCESS || !external_handles) 361bf215546Sopenharmony_ci return result; 362bf215546Sopenharmony_ci 363bf215546Sopenharmony_ci result = vn_renderer_bo_create_from_device_memory( 364bf215546Sopenharmony_ci dev->renderer, mem->size, mem->base.id, mem->flags, external_handles, 365bf215546Sopenharmony_ci &mem->base_bo); 366bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 367bf215546Sopenharmony_ci vn_async_vkFreeMemory(dev->instance, dev_handle, mem_handle, NULL); 368bf215546Sopenharmony_ci return result; 369bf215546Sopenharmony_ci } 370bf215546Sopenharmony_ci 371bf215546Sopenharmony_ci result = 372bf215546Sopenharmony_ci vn_instance_submit_roundtrip(dev->instance, &mem->bo_roundtrip_seqno); 373bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 374bf215546Sopenharmony_ci vn_renderer_bo_unref(dev->renderer, mem->base_bo); 375bf215546Sopenharmony_ci vn_async_vkFreeMemory(dev->instance, dev_handle, mem_handle, NULL); 376bf215546Sopenharmony_ci return result; 377bf215546Sopenharmony_ci } 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_ci mem->bo_roundtrip_seqno_valid = true; 380bf215546Sopenharmony_ci 381bf215546Sopenharmony_ci return VK_SUCCESS; 382bf215546Sopenharmony_ci} 383bf215546Sopenharmony_ci 384bf215546Sopenharmony_cistatic VkResult 385bf215546Sopenharmony_civn_device_memory_alloc(struct vn_device *dev, 386bf215546Sopenharmony_ci struct vn_device_memory *mem, 387bf215546Sopenharmony_ci const VkMemoryAllocateInfo *alloc_info, 388bf215546Sopenharmony_ci VkExternalMemoryHandleTypeFlags external_handles) 389bf215546Sopenharmony_ci{ 390bf215546Sopenharmony_ci const struct vn_instance *instance = dev->physical_device->instance; 391bf215546Sopenharmony_ci const struct vn_renderer_info *renderer_info = &instance->renderer->info; 392bf215546Sopenharmony_ci 393bf215546Sopenharmony_ci if (renderer_info->has_guest_vram) { 394bf215546Sopenharmony_ci return vn_device_memory_alloc_guest_vram(dev, mem, alloc_info, 395bf215546Sopenharmony_ci external_handles); 396bf215546Sopenharmony_ci } 397bf215546Sopenharmony_ci 398bf215546Sopenharmony_ci return vn_device_memory_alloc_generic(dev, mem, alloc_info, 399bf215546Sopenharmony_ci external_handles); 400bf215546Sopenharmony_ci} 401bf215546Sopenharmony_ci 402bf215546Sopenharmony_ciVkResult 403bf215546Sopenharmony_civn_AllocateMemory(VkDevice device, 404bf215546Sopenharmony_ci const VkMemoryAllocateInfo *pAllocateInfo, 405bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 406bf215546Sopenharmony_ci VkDeviceMemory *pMemory) 407bf215546Sopenharmony_ci{ 408bf215546Sopenharmony_ci VN_TRACE_FUNC(); 409bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 410bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 411bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 412bf215546Sopenharmony_ci 413bf215546Sopenharmony_ci const VkPhysicalDeviceMemoryProperties *mem_props = 414bf215546Sopenharmony_ci &dev->physical_device->memory_properties.memoryProperties; 415bf215546Sopenharmony_ci const VkMemoryPropertyFlags mem_flags = 416bf215546Sopenharmony_ci mem_props->memoryTypes[pAllocateInfo->memoryTypeIndex].propertyFlags; 417bf215546Sopenharmony_ci 418bf215546Sopenharmony_ci const VkExportMemoryAllocateInfo *export_info = NULL; 419bf215546Sopenharmony_ci const VkImportAndroidHardwareBufferInfoANDROID *import_ahb_info = NULL; 420bf215546Sopenharmony_ci const VkImportMemoryFdInfoKHR *import_fd_info = NULL; 421bf215546Sopenharmony_ci bool export_ahb = false; 422bf215546Sopenharmony_ci 423bf215546Sopenharmony_ci vk_foreach_struct_const(pnext, pAllocateInfo->pNext) { 424bf215546Sopenharmony_ci switch (pnext->sType) { 425bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO: 426bf215546Sopenharmony_ci export_info = (void *)pnext; 427bf215546Sopenharmony_ci if (export_info->handleTypes & 428bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) 429bf215546Sopenharmony_ci export_ahb = true; 430bf215546Sopenharmony_ci else if (!export_info->handleTypes) 431bf215546Sopenharmony_ci export_info = NULL; 432bf215546Sopenharmony_ci break; 433bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID: 434bf215546Sopenharmony_ci import_ahb_info = (void *)pnext; 435bf215546Sopenharmony_ci break; 436bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR: 437bf215546Sopenharmony_ci import_fd_info = (void *)pnext; 438bf215546Sopenharmony_ci break; 439bf215546Sopenharmony_ci default: 440bf215546Sopenharmony_ci break; 441bf215546Sopenharmony_ci } 442bf215546Sopenharmony_ci } 443bf215546Sopenharmony_ci 444bf215546Sopenharmony_ci struct vn_device_memory *mem = 445bf215546Sopenharmony_ci vk_zalloc(alloc, sizeof(*mem), VN_DEFAULT_ALIGN, 446bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 447bf215546Sopenharmony_ci if (!mem) 448bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 449bf215546Sopenharmony_ci 450bf215546Sopenharmony_ci vn_object_base_init(&mem->base, VK_OBJECT_TYPE_DEVICE_MEMORY, &dev->base); 451bf215546Sopenharmony_ci mem->size = pAllocateInfo->allocationSize; 452bf215546Sopenharmony_ci mem->flags = mem_flags; 453bf215546Sopenharmony_ci 454bf215546Sopenharmony_ci VkDeviceMemory mem_handle = vn_device_memory_to_handle(mem); 455bf215546Sopenharmony_ci VkResult result; 456bf215546Sopenharmony_ci if (import_ahb_info) { 457bf215546Sopenharmony_ci result = vn_android_device_import_ahb(dev, mem, pAllocateInfo, alloc, 458bf215546Sopenharmony_ci import_ahb_info->buffer, false); 459bf215546Sopenharmony_ci } else if (export_ahb) { 460bf215546Sopenharmony_ci result = vn_android_device_allocate_ahb(dev, mem, pAllocateInfo, alloc); 461bf215546Sopenharmony_ci } else if (import_fd_info) { 462bf215546Sopenharmony_ci result = vn_device_memory_import_dma_buf(dev, mem, pAllocateInfo, false, 463bf215546Sopenharmony_ci import_fd_info->fd); 464bf215546Sopenharmony_ci } else if (export_info) { 465bf215546Sopenharmony_ci result = vn_device_memory_alloc(dev, mem, pAllocateInfo, 466bf215546Sopenharmony_ci export_info->handleTypes); 467bf215546Sopenharmony_ci } else if (vn_device_memory_should_suballocate(dev, pAllocateInfo, 468bf215546Sopenharmony_ci mem_flags)) { 469bf215546Sopenharmony_ci result = vn_device_memory_pool_suballocate( 470bf215546Sopenharmony_ci dev, mem, pAllocateInfo->memoryTypeIndex); 471bf215546Sopenharmony_ci } else { 472bf215546Sopenharmony_ci result = vn_device_memory_alloc(dev, mem, pAllocateInfo, 0); 473bf215546Sopenharmony_ci } 474bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 475bf215546Sopenharmony_ci vn_object_base_fini(&mem->base); 476bf215546Sopenharmony_ci vk_free(alloc, mem); 477bf215546Sopenharmony_ci return vn_error(dev->instance, result); 478bf215546Sopenharmony_ci } 479bf215546Sopenharmony_ci 480bf215546Sopenharmony_ci *pMemory = mem_handle; 481bf215546Sopenharmony_ci 482bf215546Sopenharmony_ci return VK_SUCCESS; 483bf215546Sopenharmony_ci} 484bf215546Sopenharmony_ci 485bf215546Sopenharmony_civoid 486bf215546Sopenharmony_civn_FreeMemory(VkDevice device, 487bf215546Sopenharmony_ci VkDeviceMemory memory, 488bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 489bf215546Sopenharmony_ci{ 490bf215546Sopenharmony_ci VN_TRACE_FUNC(); 491bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 492bf215546Sopenharmony_ci struct vn_device_memory *mem = vn_device_memory_from_handle(memory); 493bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 494bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_ci if (!mem) 497bf215546Sopenharmony_ci return; 498bf215546Sopenharmony_ci 499bf215546Sopenharmony_ci if (mem->base_memory) { 500bf215546Sopenharmony_ci vn_device_memory_pool_unref(dev, mem->base_memory); 501bf215546Sopenharmony_ci } else { 502bf215546Sopenharmony_ci if (mem->base_bo) 503bf215546Sopenharmony_ci vn_renderer_bo_unref(dev->renderer, mem->base_bo); 504bf215546Sopenharmony_ci 505bf215546Sopenharmony_ci if (mem->bo_roundtrip_seqno_valid) 506bf215546Sopenharmony_ci vn_instance_wait_roundtrip(dev->instance, mem->bo_roundtrip_seqno); 507bf215546Sopenharmony_ci 508bf215546Sopenharmony_ci vn_async_vkFreeMemory(dev->instance, device, memory, NULL); 509bf215546Sopenharmony_ci } 510bf215546Sopenharmony_ci 511bf215546Sopenharmony_ci if (mem->ahb) 512bf215546Sopenharmony_ci vn_android_release_ahb(mem->ahb); 513bf215546Sopenharmony_ci 514bf215546Sopenharmony_ci vn_object_base_fini(&mem->base); 515bf215546Sopenharmony_ci vk_free(alloc, mem); 516bf215546Sopenharmony_ci} 517bf215546Sopenharmony_ci 518bf215546Sopenharmony_ciuint64_t 519bf215546Sopenharmony_civn_GetDeviceMemoryOpaqueCaptureAddress( 520bf215546Sopenharmony_ci VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo *pInfo) 521bf215546Sopenharmony_ci{ 522bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 523bf215546Sopenharmony_ci ASSERTED struct vn_device_memory *mem = 524bf215546Sopenharmony_ci vn_device_memory_from_handle(pInfo->memory); 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_ci assert(!mem->base_memory); 527bf215546Sopenharmony_ci return vn_call_vkGetDeviceMemoryOpaqueCaptureAddress(dev->instance, device, 528bf215546Sopenharmony_ci pInfo); 529bf215546Sopenharmony_ci} 530bf215546Sopenharmony_ci 531bf215546Sopenharmony_ciVkResult 532bf215546Sopenharmony_civn_MapMemory(VkDevice device, 533bf215546Sopenharmony_ci VkDeviceMemory memory, 534bf215546Sopenharmony_ci VkDeviceSize offset, 535bf215546Sopenharmony_ci VkDeviceSize size, 536bf215546Sopenharmony_ci VkMemoryMapFlags flags, 537bf215546Sopenharmony_ci void **ppData) 538bf215546Sopenharmony_ci{ 539bf215546Sopenharmony_ci VN_TRACE_FUNC(); 540bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 541bf215546Sopenharmony_ci struct vn_device_memory *mem = vn_device_memory_from_handle(memory); 542bf215546Sopenharmony_ci const bool need_bo = !mem->base_bo; 543bf215546Sopenharmony_ci void *ptr = NULL; 544bf215546Sopenharmony_ci VkResult result; 545bf215546Sopenharmony_ci 546bf215546Sopenharmony_ci assert(mem->flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); 547bf215546Sopenharmony_ci 548bf215546Sopenharmony_ci /* We don't want to blindly create a bo for each HOST_VISIBLE memory as 549bf215546Sopenharmony_ci * that has a cost. By deferring bo creation until now, we can avoid the 550bf215546Sopenharmony_ci * cost unless a bo is really needed. However, that means 551bf215546Sopenharmony_ci * vn_renderer_bo_map will block until the renderer creates the resource 552bf215546Sopenharmony_ci * and injects the pages into the guest. 553bf215546Sopenharmony_ci */ 554bf215546Sopenharmony_ci if (need_bo) { 555bf215546Sopenharmony_ci result = vn_renderer_bo_create_from_device_memory( 556bf215546Sopenharmony_ci dev->renderer, mem->size, mem->base.id, mem->flags, 0, 557bf215546Sopenharmony_ci &mem->base_bo); 558bf215546Sopenharmony_ci if (result != VK_SUCCESS) 559bf215546Sopenharmony_ci return vn_error(dev->instance, result); 560bf215546Sopenharmony_ci } 561bf215546Sopenharmony_ci 562bf215546Sopenharmony_ci ptr = vn_renderer_bo_map(dev->renderer, mem->base_bo); 563bf215546Sopenharmony_ci if (!ptr) { 564bf215546Sopenharmony_ci /* vn_renderer_bo_map implies a roundtrip on success, but not here. */ 565bf215546Sopenharmony_ci if (need_bo) { 566bf215546Sopenharmony_ci result = vn_instance_submit_roundtrip(dev->instance, 567bf215546Sopenharmony_ci &mem->bo_roundtrip_seqno); 568bf215546Sopenharmony_ci if (result != VK_SUCCESS) 569bf215546Sopenharmony_ci return vn_error(dev->instance, result); 570bf215546Sopenharmony_ci 571bf215546Sopenharmony_ci mem->bo_roundtrip_seqno_valid = true; 572bf215546Sopenharmony_ci } 573bf215546Sopenharmony_ci 574bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_MEMORY_MAP_FAILED); 575bf215546Sopenharmony_ci } 576bf215546Sopenharmony_ci 577bf215546Sopenharmony_ci mem->map_end = size == VK_WHOLE_SIZE ? mem->size : offset + size; 578bf215546Sopenharmony_ci 579bf215546Sopenharmony_ci *ppData = ptr + mem->base_offset + offset; 580bf215546Sopenharmony_ci 581bf215546Sopenharmony_ci return VK_SUCCESS; 582bf215546Sopenharmony_ci} 583bf215546Sopenharmony_ci 584bf215546Sopenharmony_civoid 585bf215546Sopenharmony_civn_UnmapMemory(VkDevice device, VkDeviceMemory memory) 586bf215546Sopenharmony_ci{ 587bf215546Sopenharmony_ci VN_TRACE_FUNC(); 588bf215546Sopenharmony_ci} 589bf215546Sopenharmony_ci 590bf215546Sopenharmony_ciVkResult 591bf215546Sopenharmony_civn_FlushMappedMemoryRanges(VkDevice device, 592bf215546Sopenharmony_ci uint32_t memoryRangeCount, 593bf215546Sopenharmony_ci const VkMappedMemoryRange *pMemoryRanges) 594bf215546Sopenharmony_ci{ 595bf215546Sopenharmony_ci VN_TRACE_FUNC(); 596bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 597bf215546Sopenharmony_ci 598bf215546Sopenharmony_ci for (uint32_t i = 0; i < memoryRangeCount; i++) { 599bf215546Sopenharmony_ci const VkMappedMemoryRange *range = &pMemoryRanges[i]; 600bf215546Sopenharmony_ci struct vn_device_memory *mem = 601bf215546Sopenharmony_ci vn_device_memory_from_handle(range->memory); 602bf215546Sopenharmony_ci 603bf215546Sopenharmony_ci const VkDeviceSize size = range->size == VK_WHOLE_SIZE 604bf215546Sopenharmony_ci ? mem->map_end - range->offset 605bf215546Sopenharmony_ci : range->size; 606bf215546Sopenharmony_ci vn_renderer_bo_flush(dev->renderer, mem->base_bo, 607bf215546Sopenharmony_ci mem->base_offset + range->offset, size); 608bf215546Sopenharmony_ci } 609bf215546Sopenharmony_ci 610bf215546Sopenharmony_ci return VK_SUCCESS; 611bf215546Sopenharmony_ci} 612bf215546Sopenharmony_ci 613bf215546Sopenharmony_ciVkResult 614bf215546Sopenharmony_civn_InvalidateMappedMemoryRanges(VkDevice device, 615bf215546Sopenharmony_ci uint32_t memoryRangeCount, 616bf215546Sopenharmony_ci const VkMappedMemoryRange *pMemoryRanges) 617bf215546Sopenharmony_ci{ 618bf215546Sopenharmony_ci VN_TRACE_FUNC(); 619bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 620bf215546Sopenharmony_ci 621bf215546Sopenharmony_ci for (uint32_t i = 0; i < memoryRangeCount; i++) { 622bf215546Sopenharmony_ci const VkMappedMemoryRange *range = &pMemoryRanges[i]; 623bf215546Sopenharmony_ci struct vn_device_memory *mem = 624bf215546Sopenharmony_ci vn_device_memory_from_handle(range->memory); 625bf215546Sopenharmony_ci 626bf215546Sopenharmony_ci const VkDeviceSize size = range->size == VK_WHOLE_SIZE 627bf215546Sopenharmony_ci ? mem->map_end - range->offset 628bf215546Sopenharmony_ci : range->size; 629bf215546Sopenharmony_ci vn_renderer_bo_invalidate(dev->renderer, mem->base_bo, 630bf215546Sopenharmony_ci mem->base_offset + range->offset, size); 631bf215546Sopenharmony_ci } 632bf215546Sopenharmony_ci 633bf215546Sopenharmony_ci return VK_SUCCESS; 634bf215546Sopenharmony_ci} 635bf215546Sopenharmony_ci 636bf215546Sopenharmony_civoid 637bf215546Sopenharmony_civn_GetDeviceMemoryCommitment(VkDevice device, 638bf215546Sopenharmony_ci VkDeviceMemory memory, 639bf215546Sopenharmony_ci VkDeviceSize *pCommittedMemoryInBytes) 640bf215546Sopenharmony_ci{ 641bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 642bf215546Sopenharmony_ci ASSERTED struct vn_device_memory *mem = 643bf215546Sopenharmony_ci vn_device_memory_from_handle(memory); 644bf215546Sopenharmony_ci 645bf215546Sopenharmony_ci assert(!mem->base_memory); 646bf215546Sopenharmony_ci vn_call_vkGetDeviceMemoryCommitment(dev->instance, device, memory, 647bf215546Sopenharmony_ci pCommittedMemoryInBytes); 648bf215546Sopenharmony_ci} 649bf215546Sopenharmony_ci 650bf215546Sopenharmony_ciVkResult 651bf215546Sopenharmony_civn_GetMemoryFdKHR(VkDevice device, 652bf215546Sopenharmony_ci const VkMemoryGetFdInfoKHR *pGetFdInfo, 653bf215546Sopenharmony_ci int *pFd) 654bf215546Sopenharmony_ci{ 655bf215546Sopenharmony_ci VN_TRACE_FUNC(); 656bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 657bf215546Sopenharmony_ci struct vn_device_memory *mem = 658bf215546Sopenharmony_ci vn_device_memory_from_handle(pGetFdInfo->memory); 659bf215546Sopenharmony_ci 660bf215546Sopenharmony_ci /* At the moment, we support only the below handle types. */ 661bf215546Sopenharmony_ci assert(pGetFdInfo->handleType & 662bf215546Sopenharmony_ci (VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT | 663bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT)); 664bf215546Sopenharmony_ci assert(!mem->base_memory && mem->base_bo); 665bf215546Sopenharmony_ci *pFd = vn_renderer_bo_export_dma_buf(dev->renderer, mem->base_bo); 666bf215546Sopenharmony_ci if (*pFd < 0) 667bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_TOO_MANY_OBJECTS); 668bf215546Sopenharmony_ci 669bf215546Sopenharmony_ci return VK_SUCCESS; 670bf215546Sopenharmony_ci} 671bf215546Sopenharmony_ci 672bf215546Sopenharmony_ciVkResult 673bf215546Sopenharmony_civn_get_memory_dma_buf_properties(struct vn_device *dev, 674bf215546Sopenharmony_ci int fd, 675bf215546Sopenharmony_ci uint64_t *out_alloc_size, 676bf215546Sopenharmony_ci uint32_t *out_mem_type_bits) 677bf215546Sopenharmony_ci{ 678bf215546Sopenharmony_ci VkDevice device = vn_device_to_handle(dev); 679bf215546Sopenharmony_ci struct vn_renderer_bo *bo = NULL; 680bf215546Sopenharmony_ci VkResult result = VK_SUCCESS; 681bf215546Sopenharmony_ci 682bf215546Sopenharmony_ci result = vn_renderer_bo_create_from_dma_buf(dev->renderer, 0 /* size */, 683bf215546Sopenharmony_ci fd, 0 /* flags */, &bo); 684bf215546Sopenharmony_ci if (result != VK_SUCCESS) 685bf215546Sopenharmony_ci return result; 686bf215546Sopenharmony_ci 687bf215546Sopenharmony_ci vn_instance_roundtrip(dev->instance); 688bf215546Sopenharmony_ci 689bf215546Sopenharmony_ci VkMemoryResourceAllocationSizeProperties100000MESA alloc_size_props = { 690bf215546Sopenharmony_ci .sType = 691bf215546Sopenharmony_ci VK_STRUCTURE_TYPE_MEMORY_RESOURCE_ALLOCATION_SIZE_PROPERTIES_100000_MESA, 692bf215546Sopenharmony_ci .pNext = NULL, 693bf215546Sopenharmony_ci .allocationSize = 0, 694bf215546Sopenharmony_ci }; 695bf215546Sopenharmony_ci VkMemoryResourcePropertiesMESA props = { 696bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_MEMORY_RESOURCE_PROPERTIES_MESA, 697bf215546Sopenharmony_ci .pNext = 698bf215546Sopenharmony_ci dev->instance->experimental.memoryResourceAllocationSize == VK_TRUE 699bf215546Sopenharmony_ci ? &alloc_size_props 700bf215546Sopenharmony_ci : NULL, 701bf215546Sopenharmony_ci .memoryTypeBits = 0, 702bf215546Sopenharmony_ci }; 703bf215546Sopenharmony_ci result = vn_call_vkGetMemoryResourcePropertiesMESA(dev->instance, device, 704bf215546Sopenharmony_ci bo->res_id, &props); 705bf215546Sopenharmony_ci vn_renderer_bo_unref(dev->renderer, bo); 706bf215546Sopenharmony_ci if (result != VK_SUCCESS) 707bf215546Sopenharmony_ci return result; 708bf215546Sopenharmony_ci 709bf215546Sopenharmony_ci *out_alloc_size = alloc_size_props.allocationSize; 710bf215546Sopenharmony_ci *out_mem_type_bits = props.memoryTypeBits; 711bf215546Sopenharmony_ci 712bf215546Sopenharmony_ci return VK_SUCCESS; 713bf215546Sopenharmony_ci} 714bf215546Sopenharmony_ci 715bf215546Sopenharmony_ciVkResult 716bf215546Sopenharmony_civn_GetMemoryFdPropertiesKHR(VkDevice device, 717bf215546Sopenharmony_ci VkExternalMemoryHandleTypeFlagBits handleType, 718bf215546Sopenharmony_ci int fd, 719bf215546Sopenharmony_ci VkMemoryFdPropertiesKHR *pMemoryFdProperties) 720bf215546Sopenharmony_ci{ 721bf215546Sopenharmony_ci VN_TRACE_FUNC(); 722bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 723bf215546Sopenharmony_ci uint64_t alloc_size = 0; 724bf215546Sopenharmony_ci uint32_t mem_type_bits = 0; 725bf215546Sopenharmony_ci VkResult result = VK_SUCCESS; 726bf215546Sopenharmony_ci 727bf215546Sopenharmony_ci if (handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT) 728bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE); 729bf215546Sopenharmony_ci 730bf215546Sopenharmony_ci result = 731bf215546Sopenharmony_ci vn_get_memory_dma_buf_properties(dev, fd, &alloc_size, &mem_type_bits); 732bf215546Sopenharmony_ci if (result != VK_SUCCESS) 733bf215546Sopenharmony_ci return vn_error(dev->instance, result); 734bf215546Sopenharmony_ci 735bf215546Sopenharmony_ci pMemoryFdProperties->memoryTypeBits = mem_type_bits; 736bf215546Sopenharmony_ci 737bf215546Sopenharmony_ci return VK_SUCCESS; 738bf215546Sopenharmony_ci} 739