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);
return result;
}
+ bo->bo.flags = bo_flags;
+
assert(bo->bo.gem_handle);
pthread_mutex_lock(&cache->mutex);
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);
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);
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);
}
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);
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;
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;
}
}
- 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;
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;
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,
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);
} 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;
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;