restructure allocation strategy for small allocations
	
		
			
	
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
					Details
				
			
		
	
				
					
				
			
				
	
				continuous-integration/drone/push Build is passing
				
					Details
				
			
		
	
							parent
							
								
									0994ac152e
								
							
						
					
					
						commit
						2c77bf96d9
					
				|  | @ -74,11 +74,11 @@ typedef struct VulkanExtensions | |||
| 
 | ||||
| /* Defines */ | ||||
| 
 | ||||
| #define STARTING_ALLOCATION_SIZE 67108864 	    /* 64MiB */ | ||||
| #define MAX_ALLOCATION_SIZE 268435456 		    /* 256MiB */ | ||||
| #define ALLOCATION_INCREMENT 16777216           /* 16MiB */ | ||||
| #define UBO_BUFFER_SIZE 16777216 				/* 16MiB */ | ||||
| #define MAX_UBO_SECTION_SIZE 4096 			        /* 4KiB */ | ||||
| #define SMALL_ALLOCATION_THRESHOLD 1048576      /* 1   MiB */ | ||||
| #define SMALL_ALLOCATION_SIZE 16777216          /* 16  MiB */ | ||||
| #define LARGE_ALLOCATION_INCREMENT 67108864     /* 64  MiB */ | ||||
| #define UBO_BUFFER_SIZE 16777216                /* 16  MiB */ | ||||
| #define MAX_UBO_SECTION_SIZE 4096               /* 4   KiB */ | ||||
| #define DESCRIPTOR_POOL_STARTING_SIZE 128 | ||||
| #define MAX_FRAMES_IN_FLIGHT 3 | ||||
| #define WINDOW_DATA "Refresh_VulkanWindowData" | ||||
|  | @ -424,7 +424,6 @@ typedef struct VulkanMemoryUsedRegion | |||
| typedef struct VulkanMemorySubAllocator | ||||
| { | ||||
| 	uint32_t memoryTypeIndex; | ||||
| 	VkDeviceSize nextAllocationSize; | ||||
| 	VulkanMemoryAllocation **allocations; | ||||
| 	uint32_t allocationCount; | ||||
| 	VulkanMemoryFreeRegion **sortedFreeRegions; | ||||
|  | @ -2626,13 +2625,15 @@ static uint8_t VULKAN_INTERNAL_BindResourceMemory( | |||
| 	VulkanMemoryAllocation *allocation; | ||||
| 	VulkanMemorySubAllocator *allocator; | ||||
| 	VulkanMemoryFreeRegion *region; | ||||
| 	VulkanMemoryFreeRegion *selectedRegion; | ||||
| 	VulkanMemoryUsedRegion *usedRegion; | ||||
| 
 | ||||
| 	VkDeviceSize requiredSize, allocationSize; | ||||
| 	VkDeviceSize alignedOffset; | ||||
| 	uint32_t newRegionSize, newRegionOffset; | ||||
| 	uint8_t shouldAllocDedicated = forceDedicated; | ||||
| 	uint8_t isHostVisible, allocationResult; | ||||
| 	uint8_t isHostVisible, smallAllocation, allocationResult; | ||||
| 	int32_t i; | ||||
| 
 | ||||
| 	isHostVisible = | ||||
| 		(renderer->memoryProperties.memoryTypes[memoryTypeIndex].propertyFlags & | ||||
|  | @ -2640,6 +2641,7 @@ static uint8_t VULKAN_INTERNAL_BindResourceMemory( | |||
| 
 | ||||
| 	allocator = &renderer->memoryAllocator->subAllocators[memoryTypeIndex]; | ||||
| 	requiredSize = memoryRequirements->memoryRequirements.size; | ||||
| 	smallAllocation = requiredSize < SMALL_ALLOCATION_THRESHOLD; | ||||
| 
 | ||||
| 	if (	(buffer == VK_NULL_HANDLE && image == VK_NULL_HANDLE) || | ||||
| 		(buffer != VK_NULL_HANDLE && image != VK_NULL_HANDLE)	) | ||||
|  | @ -2650,90 +2652,113 @@ static uint8_t VULKAN_INTERNAL_BindResourceMemory( | |||
| 
 | ||||
| 	SDL_LockMutex(renderer->allocatorLock); | ||||
| 
 | ||||
| 	/* find the largest free region and use it */ | ||||
| 	if (!shouldAllocDedicated && allocator->sortedFreeRegionCount > 0) | ||||
| 	selectedRegion = NULL; | ||||
| 
 | ||||
| 	if (!shouldAllocDedicated) | ||||
| 	{ | ||||
| 		region = allocator->sortedFreeRegions[0]; | ||||
| 		allocation = region->allocation; | ||||
| 
 | ||||
| 		alignedOffset = VULKAN_INTERNAL_NextHighestAlignment( | ||||
| 			region->offset, | ||||
| 			memoryRequirements->memoryRequirements.alignment | ||||
| 		); | ||||
| 
 | ||||
| 		if (alignedOffset + requiredSize <= region->offset + region->size) | ||||
| 		for (i = allocator->sortedFreeRegionCount - 1; i >= 0; i -= 1) | ||||
| 		{ | ||||
| 			usedRegion = VULKAN_INTERNAL_NewMemoryUsedRegion( | ||||
| 				renderer, | ||||
| 				allocation, | ||||
| 			region = allocator->sortedFreeRegions[i]; | ||||
| 
 | ||||
| 			if (smallAllocation && region->allocation->size != SMALL_ALLOCATION_SIZE) | ||||
| 			{ | ||||
| 				/* region is not in a small allocation */ | ||||
| 				continue; | ||||
| 			} | ||||
| 
 | ||||
| 			if (!smallAllocation && region->allocation->size == SMALL_ALLOCATION_SIZE) | ||||
| 			{ | ||||
| 				/* allocation is not small and current region is in a small allocation */ | ||||
| 				continue; | ||||
| 			} | ||||
| 
 | ||||
| 			alignedOffset = VULKAN_INTERNAL_NextHighestAlignment( | ||||
| 				region->offset, | ||||
| 				requiredSize + (alignedOffset - region->offset), | ||||
| 				alignedOffset, | ||||
| 				resourceSize, | ||||
| 				memoryRequirements->memoryRequirements.alignment | ||||
| 			); | ||||
| 
 | ||||
| 			usedRegion->isBuffer = buffer != VK_NULL_HANDLE; | ||||
| 
 | ||||
| 			newRegionSize = region->size - ((alignedOffset - region->offset) + requiredSize); | ||||
| 			newRegionOffset = alignedOffset + requiredSize; | ||||
| 
 | ||||
| 			/* remove and add modified region to re-sort */ | ||||
| 			VULKAN_INTERNAL_RemoveMemoryFreeRegion(renderer, region); | ||||
| 
 | ||||
| 			/* if size is 0, no need to re-insert */ | ||||
| 			if (newRegionSize != 0) | ||||
| 			if (alignedOffset + requiredSize <= region->offset + region->size) | ||||
| 			{ | ||||
| 				VULKAN_INTERNAL_NewMemoryFreeRegion( | ||||
| 					renderer, | ||||
| 					allocation, | ||||
| 					newRegionOffset, | ||||
| 					newRegionSize | ||||
| 				); | ||||
| 				selectedRegion = region; | ||||
| 				break; | ||||
| 			} | ||||
| 
 | ||||
| 			SDL_UnlockMutex(renderer->allocatorLock); | ||||
| 
 | ||||
| 			if (buffer != VK_NULL_HANDLE) | ||||
| 			{ | ||||
| 				if (!VULKAN_INTERNAL_BindBufferMemory( | ||||
| 					renderer, | ||||
| 					usedRegion, | ||||
| 					alignedOffset, | ||||
| 					buffer | ||||
| 				)) { | ||||
| 					VULKAN_INTERNAL_RemoveMemoryUsedRegion( | ||||
| 						renderer, | ||||
| 						usedRegion | ||||
| 					); | ||||
| 
 | ||||
| 					return 0; | ||||
| 				} | ||||
| 			} | ||||
| 			else if (image != VK_NULL_HANDLE) | ||||
| 			{ | ||||
| 				if (!VULKAN_INTERNAL_BindImageMemory( | ||||
| 					renderer, | ||||
| 					usedRegion, | ||||
| 					alignedOffset, | ||||
| 					image | ||||
| 				)) { | ||||
| 					VULKAN_INTERNAL_RemoveMemoryUsedRegion( | ||||
| 						renderer, | ||||
| 						usedRegion | ||||
| 					); | ||||
| 
 | ||||
| 					return 0; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			*pMemoryUsedRegion = usedRegion; | ||||
| 			return 1; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* No suitable free regions exist, allocate a new memory region */ | ||||
| 	if (selectedRegion != NULL) | ||||
| 	{ | ||||
| 		region = selectedRegion; | ||||
| 		allocation = region->allocation; | ||||
| 
 | ||||
| 		usedRegion = VULKAN_INTERNAL_NewMemoryUsedRegion( | ||||
| 			renderer, | ||||
| 			allocation, | ||||
| 			region->offset, | ||||
| 			requiredSize + (alignedOffset - region->offset), | ||||
| 			alignedOffset, | ||||
| 			resourceSize, | ||||
| 			memoryRequirements->memoryRequirements.alignment | ||||
| 		); | ||||
| 
 | ||||
| 		usedRegion->isBuffer = buffer != VK_NULL_HANDLE; | ||||
| 
 | ||||
| 		newRegionSize = region->size - ((alignedOffset - region->offset) + requiredSize); | ||||
| 		newRegionOffset = alignedOffset + requiredSize; | ||||
| 
 | ||||
| 		/* remove and add modified region to re-sort */ | ||||
| 		VULKAN_INTERNAL_RemoveMemoryFreeRegion(renderer, region); | ||||
| 
 | ||||
| 		/* if size is 0, no need to re-insert */ | ||||
| 		if (newRegionSize != 0) | ||||
| 		{ | ||||
| 			VULKAN_INTERNAL_NewMemoryFreeRegion( | ||||
| 				renderer, | ||||
| 				allocation, | ||||
| 				newRegionOffset, | ||||
| 				newRegionSize | ||||
| 			); | ||||
| 		} | ||||
| 
 | ||||
| 		SDL_UnlockMutex(renderer->allocatorLock); | ||||
| 
 | ||||
| 		if (buffer != VK_NULL_HANDLE) | ||||
| 		{ | ||||
| 			if (!VULKAN_INTERNAL_BindBufferMemory( | ||||
| 				renderer, | ||||
| 				usedRegion, | ||||
| 				alignedOffset, | ||||
| 				buffer | ||||
| 			)) { | ||||
| 				VULKAN_INTERNAL_RemoveMemoryUsedRegion( | ||||
| 					renderer, | ||||
| 					usedRegion | ||||
| 				); | ||||
| 
 | ||||
| 				return 0; | ||||
| 			} | ||||
| 		} | ||||
| 		else if (image != VK_NULL_HANDLE) | ||||
| 		{ | ||||
| 			if (!VULKAN_INTERNAL_BindImageMemory( | ||||
| 				renderer, | ||||
| 				usedRegion, | ||||
| 				alignedOffset, | ||||
| 				image | ||||
| 			)) { | ||||
| 				VULKAN_INTERNAL_RemoveMemoryUsedRegion( | ||||
| 					renderer, | ||||
| 					usedRegion | ||||
| 				); | ||||
| 
 | ||||
| 				return 0; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		*pMemoryUsedRegion = usedRegion; | ||||
| 		return 1; | ||||
| 	} | ||||
| 
 | ||||
| 	/* No suitable free regions exist, allocate a new memory region */ | ||||
| 	if ( | ||||
| 		!shouldAllocDedicated && | ||||
| 		renderer->allocationsToDefragCount == 0 && | ||||
|  | @ -2747,15 +2772,15 @@ static uint8_t VULKAN_INTERNAL_BindResourceMemory( | |||
| 	{ | ||||
| 		allocationSize = requiredSize; | ||||
| 	} | ||||
| 	else if (requiredSize > allocator->nextAllocationSize) | ||||
| 	else if (requiredSize > SMALL_ALLOCATION_THRESHOLD) | ||||
| 	{ | ||||
| 		/* allocate a page of required size aligned to ALLOCATION_INCREMENT increments */ | ||||
| 		/* allocate a page of required size aligned to LARGE_ALLOCATION_INCREMENT increments */ | ||||
| 		allocationSize = | ||||
| 			VULKAN_INTERNAL_NextHighestAlignment(requiredSize, ALLOCATION_INCREMENT); | ||||
| 			VULKAN_INTERNAL_NextHighestAlignment(requiredSize, LARGE_ALLOCATION_INCREMENT); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		allocationSize = allocator->nextAllocationSize; | ||||
| 		allocationSize = SMALL_ALLOCATION_SIZE; | ||||
| 	} | ||||
| 
 | ||||
| 	allocationResult = VULKAN_INTERNAL_AllocateMemory( | ||||
|  | @ -11543,7 +11568,6 @@ static Refresh_Device* VULKAN_CreateDevice( | |||
| 	for (i = 0; i < VK_MAX_MEMORY_TYPES; i += 1) | ||||
| 	{ | ||||
| 		renderer->memoryAllocator->subAllocators[i].memoryTypeIndex = i; | ||||
| 		renderer->memoryAllocator->subAllocators[i].nextAllocationSize = STARTING_ALLOCATION_SIZE; | ||||
| 		renderer->memoryAllocator->subAllocators[i].allocations = NULL; | ||||
| 		renderer->memoryAllocator->subAllocators[i].allocationCount = 0; | ||||
| 		renderer->memoryAllocator->subAllocators[i].sortedFreeRegions = SDL_malloc( | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue