[Mesa-dev] [PATCH v4 17/23] anv/allocator: Set the BO flags in bo_cache_alloc/import

Jason Ekstrand jason at jlekstrand.net
Thu May 31 15:46:38 UTC 2018


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.
---
 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 a597280..697da5f 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 067f436..69de75c 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 7ddde70..431cef5 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 d89e2dc..b47420f 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 b9ca189..3790d72 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;
 
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list