From b0d50247a7049350ef30adcefc609039ce86beee Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Wed, 30 May 2018 15:34:25 -0700 Subject: [PATCH] anv/allocator: Set the BO flags in bo_cache_alloc/import It's safer to set them there because we have the opportunity to properly handle combining flags if a BO is imported more than once. Reviewed-by: Scott D Phillips --- src/intel/vulkan/anv_allocator.c | 30 +++++++++++++++++++++++-- src/intel/vulkan/anv_device.c | 38 +++++++++++++++++--------------- src/intel/vulkan/anv_intel.c | 9 ++++---- src/intel/vulkan/anv_private.h | 6 +++-- src/intel/vulkan/anv_queue.c | 5 +++-- 5 files changed, 60 insertions(+), 28 deletions(-) diff --git a/src/intel/vulkan/anv_allocator.c b/src/intel/vulkan/anv_allocator.c index a597280930a..697da5f8c1a 100644 --- a/src/intel/vulkan/anv_allocator.c +++ b/src/intel/vulkan/anv_allocator.c @@ -1237,11 +1237,19 @@ anv_bo_cache_lookup(struct anv_bo_cache *cache, uint32_t gem_handle) return bo ? &bo->bo : NULL; } +#define ANV_BO_CACHE_SUPPORTED_FLAGS \ + (EXEC_OBJECT_WRITE | \ + EXEC_OBJECT_ASYNC | \ + EXEC_OBJECT_SUPPORTS_48B_ADDRESS) + VkResult anv_bo_cache_alloc(struct anv_device *device, struct anv_bo_cache *cache, - uint64_t size, struct anv_bo **bo_out) + uint64_t size, uint64_t bo_flags, + struct anv_bo **bo_out) { + assert(bo_flags == (bo_flags & ANV_BO_CACHE_SUPPORTED_FLAGS)); + struct anv_cached_bo *bo = vk_alloc(&device->alloc, sizeof(struct anv_cached_bo), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); @@ -1259,6 +1267,8 @@ anv_bo_cache_alloc(struct anv_device *device, return result; } + bo->bo.flags = bo_flags; + assert(bo->bo.gem_handle); pthread_mutex_lock(&cache->mutex); @@ -1276,8 +1286,11 @@ anv_bo_cache_alloc(struct anv_device *device, VkResult anv_bo_cache_import(struct anv_device *device, struct anv_bo_cache *cache, - int fd, struct anv_bo **bo_out) + int fd, uint64_t bo_flags, + struct anv_bo **bo_out) { + assert(bo_flags == (bo_flags & ANV_BO_CACHE_SUPPORTED_FLAGS)); + pthread_mutex_lock(&cache->mutex); uint32_t gem_handle = anv_gem_fd_to_handle(device, fd); @@ -1288,6 +1301,18 @@ anv_bo_cache_import(struct anv_device *device, struct anv_cached_bo *bo = anv_bo_cache_lookup_locked(cache, gem_handle); if (bo) { + /* We have to be careful how we combine flags so that it makes sense. + * Really, though, if we get to this case and it actually matters, the + * client has imported a BO twice in different ways and they get what + * they have coming. + */ + uint64_t new_flags = 0; + new_flags |= (bo->bo.flags | bo_flags) & EXEC_OBJECT_WRITE; + new_flags |= (bo->bo.flags & bo_flags) & EXEC_OBJECT_ASYNC; + new_flags |= (bo->bo.flags & bo_flags) & EXEC_OBJECT_SUPPORTS_48B_ADDRESS; + + bo->bo.flags = new_flags; + __sync_fetch_and_add(&bo->refcount, 1); } else { off_t size = lseek(fd, 0, SEEK_END); @@ -1308,6 +1333,7 @@ anv_bo_cache_import(struct anv_device *device, bo->refcount = 1; anv_bo_init(&bo->bo, gem_handle, size); + bo->bo.flags = bo_flags; _mesa_hash_table_insert(cache->bo_map, (void *)(uintptr_t)gem_handle, bo); } diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index 067f4369b76..69de75c7374 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -2033,6 +2033,24 @@ VkResult anv_AllocateMemory( mem->map = NULL; mem->map_size = 0; + uint64_t bo_flags = 0; + + assert(mem->type->heapIndex < pdevice->memory.heap_count); + if (pdevice->memory.heaps[mem->type->heapIndex].supports_48bit_addresses) + bo_flags |= EXEC_OBJECT_SUPPORTS_48B_ADDRESS; + + const struct wsi_memory_allocate_info *wsi_info = + vk_find_struct_const(pAllocateInfo->pNext, WSI_MEMORY_ALLOCATE_INFO_MESA); + if (wsi_info && wsi_info->implicit_sync) { + /* We need to set the WRITE flag on window system buffers so that GEM + * will know we're writing to them and synchronize uses on other rings + * (eg if the display server uses the blitter ring). + */ + bo_flags |= EXEC_OBJECT_WRITE; + } else if (pdevice->has_exec_async) { + bo_flags |= EXEC_OBJECT_ASYNC; + } + const VkImportMemoryFdInfoKHR *fd_info = vk_find_struct_const(pAllocateInfo->pNext, IMPORT_MEMORY_FD_INFO_KHR); @@ -2047,7 +2065,7 @@ VkResult anv_AllocateMemory( VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT); result = anv_bo_cache_import(device, &device->bo_cache, - fd_info->fd, &mem->bo); + fd_info->fd, bo_flags, &mem->bo); if (result != VK_SUCCESS) goto fail; @@ -2085,7 +2103,7 @@ VkResult anv_AllocateMemory( close(fd_info->fd); } else { result = anv_bo_cache_alloc(device, &device->bo_cache, - pAllocateInfo->allocationSize, + pAllocateInfo->allocationSize, bo_flags, &mem->bo); if (result != VK_SUCCESS) goto fail; @@ -2114,22 +2132,6 @@ VkResult anv_AllocateMemory( } } - assert(mem->type->heapIndex < pdevice->memory.heap_count); - if (pdevice->memory.heaps[mem->type->heapIndex].supports_48bit_addresses) - mem->bo->flags |= EXEC_OBJECT_SUPPORTS_48B_ADDRESS; - - const struct wsi_memory_allocate_info *wsi_info = - vk_find_struct_const(pAllocateInfo->pNext, WSI_MEMORY_ALLOCATE_INFO_MESA); - if (wsi_info && wsi_info->implicit_sync) { - /* We need to set the WRITE flag on window system buffers so that GEM - * will know we're writing to them and synchronize uses on other rings - * (eg if the display server uses the blitter ring). - */ - mem->bo->flags |= EXEC_OBJECT_WRITE; - } else if (pdevice->has_exec_async) { - mem->bo->flags |= EXEC_OBJECT_ASYNC; - } - *pMem = anv_device_memory_to_handle(mem); return VK_SUCCESS; diff --git a/src/intel/vulkan/anv_intel.c b/src/intel/vulkan/anv_intel.c index 7ddde70b9c4..431cef5c6ac 100644 --- a/src/intel/vulkan/anv_intel.c +++ b/src/intel/vulkan/anv_intel.c @@ -73,8 +73,12 @@ VkResult anv_CreateDmaBufImageINTEL( image = anv_image_from_handle(image_h); + uint64_t bo_flags = 0; + if (device->instance->physicalDevice.supports_48bit_addresses) + bo_flags |= EXEC_OBJECT_SUPPORTS_48B_ADDRESS; + result = anv_bo_cache_import(device, &device->bo_cache, - pCreateInfo->fd, &mem->bo); + pCreateInfo->fd, bo_flags, &mem->bo); if (result != VK_SUCCESS) goto fail_import; @@ -90,9 +94,6 @@ VkResult anv_CreateDmaBufImageINTEL( goto fail_import; } - if (device->instance->physicalDevice.supports_48bit_addresses) - mem->bo->flags |= EXEC_OBJECT_SUPPORTS_48B_ADDRESS; - image->planes[0].address = (struct anv_address) { .bo = mem->bo, .offset = 0, diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index d89e2dcc378..b47420f89ec 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -795,10 +795,12 @@ VkResult anv_bo_cache_init(struct anv_bo_cache *cache); void anv_bo_cache_finish(struct anv_bo_cache *cache); VkResult anv_bo_cache_alloc(struct anv_device *device, struct anv_bo_cache *cache, - uint64_t size, struct anv_bo **bo); + uint64_t size, uint64_t bo_flags, + struct anv_bo **bo); VkResult anv_bo_cache_import(struct anv_device *device, struct anv_bo_cache *cache, - int fd, struct anv_bo **bo); + int fd, uint64_t bo_flags, + struct anv_bo **bo); VkResult anv_bo_cache_export(struct anv_device *device, struct anv_bo_cache *cache, struct anv_bo *bo_in, int *fd_out); diff --git a/src/intel/vulkan/anv_queue.c b/src/intel/vulkan/anv_queue.c index b9ca189fddc..3790d72214c 100644 --- a/src/intel/vulkan/anv_queue.c +++ b/src/intel/vulkan/anv_queue.c @@ -877,7 +877,8 @@ VkResult anv_CreateSemaphore( } else { semaphore->permanent.type = ANV_SEMAPHORE_TYPE_BO; VkResult result = anv_bo_cache_alloc(device, &device->bo_cache, - 4096, &semaphore->permanent.bo); + 4096, 0, + &semaphore->permanent.bo); if (result != VK_SUCCESS) { vk_free2(&device->alloc, pAllocator, semaphore); return result; @@ -1023,7 +1024,7 @@ VkResult anv_ImportSemaphoreFdKHR( new_impl.type = ANV_SEMAPHORE_TYPE_BO; VkResult result = anv_bo_cache_import(device, &device->bo_cache, - fd, &new_impl.bo); + fd, 0, &new_impl.bo); if (result != VK_SUCCESS) return result;