Previously, the heap size of a physical device was kind of useless because it was not enforced. Now, we keep track of allocation sizes so that the sum of all allocations can never exceed the heap size advertised by anv_GetPhysicalDeviceMemoryProperties. --- src/intel/vulkan/anv_device.c | 42 +++++++++++++++++++++++++++++++++--------- src/intel/vulkan/anv_private.h | 8 ++++++++ 2 files changed, 41 insertions(+), 9 deletions(-)
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index fecb850..162e372 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -190,6 +190,18 @@ anv_physical_device_init(struct anv_physical_device *device, /* XXX: Actually detect bit6 swizzling */ isl_device_init(&device->isl_dev, device->info, swizzled); + /* Reserve some wiggle room for the driver by exposing only 75% of the + * aperture to the heap. + */ + device->heap_size = 3 * device->aperture_size / 4; + device->used_heap_space = 0; + int ret = pthread_mutex_init(&device->mutex, NULL); + if (ret != 0) { + result = vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + ralloc_free(device->compiler); + goto fail; + } + return VK_SUCCESS; fail: @@ -202,6 +214,7 @@ anv_physical_device_finish(struct anv_physical_device *device) { anv_finish_wsi(device); ralloc_free(device->compiler); + pthread_mutex_destroy(&device->mutex); } static const VkExtensionProperties global_extensions[] = { @@ -638,12 +651,6 @@ void anv_GetPhysicalDeviceMemoryProperties( VkPhysicalDeviceMemoryProperties* pMemoryProperties) { ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice); - VkDeviceSize heap_size; - - /* Reserve some wiggle room for the driver by exposing only 75% of the - * aperture to the heap. - */ - heap_size = 3 * physical_device->aperture_size / 4; if (physical_device->info->has_llc) { /* Big core GPUs share LLC with the CPU and thus one memory type can be @@ -680,7 +687,7 @@ void anv_GetPhysicalDeviceMemoryProperties( pMemoryProperties->memoryHeapCount = 1; pMemoryProperties->memoryHeaps[0] = (VkMemoryHeap) { - .size = heap_size, + .size = physical_device->heap_size, .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT, }; } @@ -1172,6 +1179,8 @@ VkResult anv_AllocateMemory( VkDeviceMemory* pMem) { ANV_FROM_HANDLE(anv_device, device, _device); + struct anv_physical_device *physical_device = + &device->instance->physicalDevice; struct anv_device_memory *mem; VkResult result; @@ -1187,20 +1196,28 @@ VkResult anv_AllocateMemory( assert(pAllocateInfo->memoryTypeIndex == 0 || (!device->info.has_llc && pAllocateInfo->memoryTypeIndex < 2)); - /* FINISHME: Fail if allocation request exceeds heap size. */ - mem = anv_alloc2(&device->alloc, pAllocator, sizeof(*mem), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); if (mem == NULL) return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + pthread_mutex_lock(&physical_device->mutex); + /* The kernel is going to give us whole pages anyway */ uint64_t alloc_size = align_u64(pAllocateInfo->allocationSize, 4096); + if (alloc_size + physical_device->used_heap_space > physical_device->heap_size) { + result = vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY); + goto fail; + } + result = anv_bo_init_new(&mem->bo, device, alloc_size); if (result != VK_SUCCESS) goto fail; + physical_device->used_heap_space += alloc_size; + pthread_mutex_unlock(&physical_device->mutex); + mem->type_index = pAllocateInfo->memoryTypeIndex; *pMem = anv_device_memory_to_handle(mem); @@ -1208,6 +1225,7 @@ VkResult anv_AllocateMemory( return VK_SUCCESS; fail: + pthread_mutex_unlock(&physical_device->mutex); anv_free2(&device->alloc, pAllocator, mem); return result; @@ -1220,6 +1238,8 @@ void anv_FreeMemory( { ANV_FROM_HANDLE(anv_device, device, _device); ANV_FROM_HANDLE(anv_device_memory, mem, _mem); + struct anv_physical_device *physical_device = + &device->instance->physicalDevice; if (mem == NULL) return; @@ -1230,6 +1250,10 @@ void anv_FreeMemory( if (mem->bo.gem_handle != 0) anv_gem_close(device, mem->bo.gem_handle); + pthread_mutex_lock(&physical_device->mutex); + physical_device->used_heap_space -= mem->bo.size; + pthread_mutex_unlock(&physical_device->mutex); + anv_free2(&device->alloc, pAllocator, mem); } diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index f578a9d..ec888a6 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -574,6 +574,14 @@ struct anv_physical_device { uint32_t subslice_total; /** + * Variables used to track the memory occupied by allocations from + * anv_AllocateMemory. + */ + uint64_t heap_size; + uint64_t used_heap_space; + pthread_mutex_t mutex; + + /** * Platform specific constants containing the maximum number of threads * for each pipeline stage. */ -- 2.10.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev