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 <scott.d.phillips@intel.com>
This commit is contained in:
Jason Ekstrand 2018-05-30 15:34:25 -07:00
parent 27cc68d9e9
commit b0d50247a7
5 changed files with 60 additions and 28 deletions

View file

@ -1237,11 +1237,19 @@ anv_bo_cache_lookup(struct anv_bo_cache *cache, uint32_t gem_handle)
return bo ? &bo->bo : NULL; return bo ? &bo->bo : NULL;
} }
#define ANV_BO_CACHE_SUPPORTED_FLAGS \
(EXEC_OBJECT_WRITE | \
EXEC_OBJECT_ASYNC | \
EXEC_OBJECT_SUPPORTS_48B_ADDRESS)
VkResult VkResult
anv_bo_cache_alloc(struct anv_device *device, anv_bo_cache_alloc(struct anv_device *device,
struct anv_bo_cache *cache, 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 = struct anv_cached_bo *bo =
vk_alloc(&device->alloc, sizeof(struct anv_cached_bo), 8, vk_alloc(&device->alloc, sizeof(struct anv_cached_bo), 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
@ -1259,6 +1267,8 @@ anv_bo_cache_alloc(struct anv_device *device,
return result; return result;
} }
bo->bo.flags = bo_flags;
assert(bo->bo.gem_handle); assert(bo->bo.gem_handle);
pthread_mutex_lock(&cache->mutex); pthread_mutex_lock(&cache->mutex);
@ -1276,8 +1286,11 @@ anv_bo_cache_alloc(struct anv_device *device,
VkResult VkResult
anv_bo_cache_import(struct anv_device *device, anv_bo_cache_import(struct anv_device *device,
struct anv_bo_cache *cache, 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); pthread_mutex_lock(&cache->mutex);
uint32_t gem_handle = anv_gem_fd_to_handle(device, fd); 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); struct anv_cached_bo *bo = anv_bo_cache_lookup_locked(cache, gem_handle);
if (bo) { 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); __sync_fetch_and_add(&bo->refcount, 1);
} else { } else {
off_t size = lseek(fd, 0, SEEK_END); off_t size = lseek(fd, 0, SEEK_END);
@ -1308,6 +1333,7 @@ anv_bo_cache_import(struct anv_device *device,
bo->refcount = 1; bo->refcount = 1;
anv_bo_init(&bo->bo, gem_handle, size); 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); _mesa_hash_table_insert(cache->bo_map, (void *)(uintptr_t)gem_handle, bo);
} }

View file

@ -2033,6 +2033,24 @@ VkResult anv_AllocateMemory(
mem->map = NULL; mem->map = NULL;
mem->map_size = 0; 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 = const VkImportMemoryFdInfoKHR *fd_info =
vk_find_struct_const(pAllocateInfo->pNext, IMPORT_MEMORY_FD_INFO_KHR); 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); VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
result = anv_bo_cache_import(device, &device->bo_cache, 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) if (result != VK_SUCCESS)
goto fail; goto fail;
@ -2085,7 +2103,7 @@ VkResult anv_AllocateMemory(
close(fd_info->fd); close(fd_info->fd);
} else { } else {
result = anv_bo_cache_alloc(device, &device->bo_cache, result = anv_bo_cache_alloc(device, &device->bo_cache,
pAllocateInfo->allocationSize, pAllocateInfo->allocationSize, bo_flags,
&mem->bo); &mem->bo);
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
goto fail; 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); *pMem = anv_device_memory_to_handle(mem);
return VK_SUCCESS; return VK_SUCCESS;

View file

@ -73,8 +73,12 @@ VkResult anv_CreateDmaBufImageINTEL(
image = anv_image_from_handle(image_h); 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, result = anv_bo_cache_import(device, &device->bo_cache,
pCreateInfo->fd, &mem->bo); pCreateInfo->fd, bo_flags, &mem->bo);
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
goto fail_import; goto fail_import;
@ -90,9 +94,6 @@ VkResult anv_CreateDmaBufImageINTEL(
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) { image->planes[0].address = (struct anv_address) {
.bo = mem->bo, .bo = mem->bo,
.offset = 0, .offset = 0,

View file

@ -795,10 +795,12 @@ VkResult anv_bo_cache_init(struct anv_bo_cache *cache);
void anv_bo_cache_finish(struct anv_bo_cache *cache); void anv_bo_cache_finish(struct anv_bo_cache *cache);
VkResult anv_bo_cache_alloc(struct anv_device *device, VkResult anv_bo_cache_alloc(struct anv_device *device,
struct anv_bo_cache *cache, 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, VkResult anv_bo_cache_import(struct anv_device *device,
struct anv_bo_cache *cache, 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, VkResult anv_bo_cache_export(struct anv_device *device,
struct anv_bo_cache *cache, struct anv_bo_cache *cache,
struct anv_bo *bo_in, int *fd_out); struct anv_bo *bo_in, int *fd_out);

View file

@ -877,7 +877,8 @@ VkResult anv_CreateSemaphore(
} else { } else {
semaphore->permanent.type = ANV_SEMAPHORE_TYPE_BO; semaphore->permanent.type = ANV_SEMAPHORE_TYPE_BO;
VkResult result = anv_bo_cache_alloc(device, &device->bo_cache, VkResult result = anv_bo_cache_alloc(device, &device->bo_cache,
4096, &semaphore->permanent.bo); 4096, 0,
&semaphore->permanent.bo);
if (result != VK_SUCCESS) { if (result != VK_SUCCESS) {
vk_free2(&device->alloc, pAllocator, semaphore); vk_free2(&device->alloc, pAllocator, semaphore);
return result; return result;
@ -1023,7 +1024,7 @@ VkResult anv_ImportSemaphoreFdKHR(
new_impl.type = ANV_SEMAPHORE_TYPE_BO; new_impl.type = ANV_SEMAPHORE_TYPE_BO;
VkResult result = anv_bo_cache_import(device, &device->bo_cache, VkResult result = anv_bo_cache_import(device, &device->bo_cache,
fd, &new_impl.bo); fd, 0, &new_impl.bo);
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
return result; return result;