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 */
|
/* Defines */
|
||||||
|
|
||||||
#define STARTING_ALLOCATION_SIZE 67108864 /* 64MiB */
|
#define SMALL_ALLOCATION_THRESHOLD 1048576 /* 1 MiB */
|
||||||
#define MAX_ALLOCATION_SIZE 268435456 /* 256MiB */
|
#define SMALL_ALLOCATION_SIZE 16777216 /* 16 MiB */
|
||||||
#define ALLOCATION_INCREMENT 16777216 /* 16MiB */
|
#define LARGE_ALLOCATION_INCREMENT 67108864 /* 64 MiB */
|
||||||
#define UBO_BUFFER_SIZE 16777216 /* 16MiB */
|
#define UBO_BUFFER_SIZE 16777216 /* 16 MiB */
|
||||||
#define MAX_UBO_SECTION_SIZE 4096 /* 4KiB */
|
#define MAX_UBO_SECTION_SIZE 4096 /* 4 KiB */
|
||||||
#define DESCRIPTOR_POOL_STARTING_SIZE 128
|
#define DESCRIPTOR_POOL_STARTING_SIZE 128
|
||||||
#define MAX_FRAMES_IN_FLIGHT 3
|
#define MAX_FRAMES_IN_FLIGHT 3
|
||||||
#define WINDOW_DATA "Refresh_VulkanWindowData"
|
#define WINDOW_DATA "Refresh_VulkanWindowData"
|
||||||
|
@ -424,7 +424,6 @@ typedef struct VulkanMemoryUsedRegion
|
||||||
typedef struct VulkanMemorySubAllocator
|
typedef struct VulkanMemorySubAllocator
|
||||||
{
|
{
|
||||||
uint32_t memoryTypeIndex;
|
uint32_t memoryTypeIndex;
|
||||||
VkDeviceSize nextAllocationSize;
|
|
||||||
VulkanMemoryAllocation **allocations;
|
VulkanMemoryAllocation **allocations;
|
||||||
uint32_t allocationCount;
|
uint32_t allocationCount;
|
||||||
VulkanMemoryFreeRegion **sortedFreeRegions;
|
VulkanMemoryFreeRegion **sortedFreeRegions;
|
||||||
|
@ -2626,13 +2625,15 @@ static uint8_t VULKAN_INTERNAL_BindResourceMemory(
|
||||||
VulkanMemoryAllocation *allocation;
|
VulkanMemoryAllocation *allocation;
|
||||||
VulkanMemorySubAllocator *allocator;
|
VulkanMemorySubAllocator *allocator;
|
||||||
VulkanMemoryFreeRegion *region;
|
VulkanMemoryFreeRegion *region;
|
||||||
|
VulkanMemoryFreeRegion *selectedRegion;
|
||||||
VulkanMemoryUsedRegion *usedRegion;
|
VulkanMemoryUsedRegion *usedRegion;
|
||||||
|
|
||||||
VkDeviceSize requiredSize, allocationSize;
|
VkDeviceSize requiredSize, allocationSize;
|
||||||
VkDeviceSize alignedOffset;
|
VkDeviceSize alignedOffset;
|
||||||
uint32_t newRegionSize, newRegionOffset;
|
uint32_t newRegionSize, newRegionOffset;
|
||||||
uint8_t shouldAllocDedicated = forceDedicated;
|
uint8_t shouldAllocDedicated = forceDedicated;
|
||||||
uint8_t isHostVisible, allocationResult;
|
uint8_t isHostVisible, smallAllocation, allocationResult;
|
||||||
|
int32_t i;
|
||||||
|
|
||||||
isHostVisible =
|
isHostVisible =
|
||||||
(renderer->memoryProperties.memoryTypes[memoryTypeIndex].propertyFlags &
|
(renderer->memoryProperties.memoryTypes[memoryTypeIndex].propertyFlags &
|
||||||
|
@ -2640,6 +2641,7 @@ static uint8_t VULKAN_INTERNAL_BindResourceMemory(
|
||||||
|
|
||||||
allocator = &renderer->memoryAllocator->subAllocators[memoryTypeIndex];
|
allocator = &renderer->memoryAllocator->subAllocators[memoryTypeIndex];
|
||||||
requiredSize = memoryRequirements->memoryRequirements.size;
|
requiredSize = memoryRequirements->memoryRequirements.size;
|
||||||
|
smallAllocation = requiredSize < SMALL_ALLOCATION_THRESHOLD;
|
||||||
|
|
||||||
if ( (buffer == VK_NULL_HANDLE && image == VK_NULL_HANDLE) ||
|
if ( (buffer == VK_NULL_HANDLE && image == VK_NULL_HANDLE) ||
|
||||||
(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);
|
SDL_LockMutex(renderer->allocatorLock);
|
||||||
|
|
||||||
/* find the largest free region and use it */
|
selectedRegion = NULL;
|
||||||
if (!shouldAllocDedicated && allocator->sortedFreeRegionCount > 0)
|
|
||||||
|
if (!shouldAllocDedicated)
|
||||||
{
|
{
|
||||||
region = allocator->sortedFreeRegions[0];
|
for (i = allocator->sortedFreeRegionCount - 1; i >= 0; i -= 1)
|
||||||
allocation = region->allocation;
|
|
||||||
|
|
||||||
alignedOffset = VULKAN_INTERNAL_NextHighestAlignment(
|
|
||||||
region->offset,
|
|
||||||
memoryRequirements->memoryRequirements.alignment
|
|
||||||
);
|
|
||||||
|
|
||||||
if (alignedOffset + requiredSize <= region->offset + region->size)
|
|
||||||
{
|
{
|
||||||
usedRegion = VULKAN_INTERNAL_NewMemoryUsedRegion(
|
region = allocator->sortedFreeRegions[i];
|
||||||
renderer,
|
|
||||||
allocation,
|
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,
|
region->offset,
|
||||||
requiredSize + (alignedOffset - region->offset),
|
|
||||||
alignedOffset,
|
|
||||||
resourceSize,
|
|
||||||
memoryRequirements->memoryRequirements.alignment
|
memoryRequirements->memoryRequirements.alignment
|
||||||
);
|
);
|
||||||
|
|
||||||
usedRegion->isBuffer = buffer != VK_NULL_HANDLE;
|
if (alignedOffset + requiredSize <= region->offset + region->size)
|
||||||
|
|
||||||
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(
|
selectedRegion = region;
|
||||||
renderer,
|
break;
|
||||||
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 (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 (
|
if (
|
||||||
!shouldAllocDedicated &&
|
!shouldAllocDedicated &&
|
||||||
renderer->allocationsToDefragCount == 0 &&
|
renderer->allocationsToDefragCount == 0 &&
|
||||||
|
@ -2747,15 +2772,15 @@ static uint8_t VULKAN_INTERNAL_BindResourceMemory(
|
||||||
{
|
{
|
||||||
allocationSize = requiredSize;
|
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 =
|
allocationSize =
|
||||||
VULKAN_INTERNAL_NextHighestAlignment(requiredSize, ALLOCATION_INCREMENT);
|
VULKAN_INTERNAL_NextHighestAlignment(requiredSize, LARGE_ALLOCATION_INCREMENT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
allocationSize = allocator->nextAllocationSize;
|
allocationSize = SMALL_ALLOCATION_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
allocationResult = VULKAN_INTERNAL_AllocateMemory(
|
allocationResult = VULKAN_INTERNAL_AllocateMemory(
|
||||||
|
@ -11543,7 +11568,6 @@ static Refresh_Device* VULKAN_CreateDevice(
|
||||||
for (i = 0; i < VK_MAX_MEMORY_TYPES; i += 1)
|
for (i = 0; i < VK_MAX_MEMORY_TYPES; i += 1)
|
||||||
{
|
{
|
||||||
renderer->memoryAllocator->subAllocators[i].memoryTypeIndex = i;
|
renderer->memoryAllocator->subAllocators[i].memoryTypeIndex = i;
|
||||||
renderer->memoryAllocator->subAllocators[i].nextAllocationSize = STARTING_ALLOCATION_SIZE;
|
|
||||||
renderer->memoryAllocator->subAllocators[i].allocations = NULL;
|
renderer->memoryAllocator->subAllocators[i].allocations = NULL;
|
||||||
renderer->memoryAllocator->subAllocators[i].allocationCount = 0;
|
renderer->memoryAllocator->subAllocators[i].allocationCount = 0;
|
||||||
renderer->memoryAllocator->subAllocators[i].sortedFreeRegions = SDL_malloc(
|
renderer->memoryAllocator->subAllocators[i].sortedFreeRegions = SDL_malloc(
|
||||||
|
|
Loading…
Reference in New Issue