fixed-size transfer pool
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
45b71bd63d
commit
994f5dc0b9
|
@ -75,6 +75,7 @@ static uint32_t deviceExtensionCount = SDL_arraysize(deviceExtensionNames);
|
|||
#define MAX_ALLOCATION_SIZE 256000000 /* 256MB */
|
||||
#define ALLOCATION_INCREMENT 16000000 /* 16MB */
|
||||
#define TRANSFER_BUFFER_STARTING_SIZE 8000000 /* 8MB */
|
||||
#define POOLED_TRANSFER_BUFFER_SIZE 16000000 /* 16MB */
|
||||
#define UBO_BUFFER_SIZE 16000 /* 16KB */
|
||||
#define DESCRIPTOR_POOL_STARTING_SIZE 128
|
||||
#define WINDOW_DATA "Refresh_VulkanWindowData"
|
||||
|
@ -1516,8 +1517,18 @@ typedef struct VulkanTransferBuffer
|
|||
{
|
||||
VulkanBuffer* buffer;
|
||||
VkDeviceSize offset;
|
||||
uint8_t fromPool;
|
||||
} VulkanTransferBuffer;
|
||||
|
||||
typedef struct VulkanTransferBufferPool
|
||||
{
|
||||
SDL_mutex *lock;
|
||||
|
||||
VulkanTransferBuffer **availableBuffers;
|
||||
uint32_t availableBufferCount;
|
||||
uint32_t availableBufferCapacity;
|
||||
} VulkanTransferBufferPool;
|
||||
|
||||
typedef struct VulkanCommandPool VulkanCommandPool;
|
||||
|
||||
typedef struct VulkanCommandBuffer
|
||||
|
@ -1723,6 +1734,8 @@ typedef struct VulkanRenderer
|
|||
uint32_t submittedCommandBufferCount;
|
||||
uint32_t submittedCommandBufferCapacity;
|
||||
|
||||
VulkanTransferBufferPool transferBufferPool;
|
||||
|
||||
CommandPoolHashTable commandPoolHashTable;
|
||||
DescriptorSetLayoutHashTable descriptorSetLayoutHashTable;
|
||||
GraphicsPipelineLayoutHashTable graphicsPipelineLayoutHashTable;
|
||||
|
@ -5151,6 +5164,15 @@ static void VULKAN_DestroyDevice(
|
|||
SDL_free(renderer->dummyFragmentUniformBuffer);
|
||||
SDL_free(renderer->dummyComputeUniformBuffer);
|
||||
|
||||
for (i = 0; i < renderer->transferBufferPool.availableBufferCount; i += 1)
|
||||
{
|
||||
VULKAN_INTERNAL_DestroyBuffer(renderer, renderer->transferBufferPool.availableBuffers[i]->buffer);
|
||||
SDL_free(renderer->transferBufferPool.availableBuffers[i]);
|
||||
}
|
||||
|
||||
SDL_free(renderer->transferBufferPool.availableBuffers);
|
||||
SDL_DestroyMutex(renderer->transferBufferPool.lock);
|
||||
|
||||
for (i = 0; i < NUM_COMMAND_POOL_BUCKETS; i += 1)
|
||||
{
|
||||
commandPoolHashArray = renderer->commandPoolHashTable.buckets[i];
|
||||
|
@ -7099,6 +7121,40 @@ static VulkanTransferBuffer* VULKAN_INTERNAL_AcquireTransferBuffer(
|
|||
}
|
||||
}
|
||||
|
||||
/* Nothing fits, can we get a transfer buffer from the pool? */
|
||||
|
||||
SDL_LockMutex(renderer->transferBufferPool.lock);
|
||||
|
||||
for (i = 0; i < renderer->transferBufferPool.availableBufferCount; i += 1)
|
||||
{
|
||||
transferBuffer = renderer->transferBufferPool.availableBuffers[i];
|
||||
offset = transferBuffer->offset + alignment - (transferBuffer->offset % alignment);
|
||||
|
||||
if (offset + requiredSize <= transferBuffer->buffer->size)
|
||||
{
|
||||
if (commandBuffer->transferBufferCount == commandBuffer->transferBufferCapacity)
|
||||
{
|
||||
commandBuffer->transferBufferCapacity *= 2;
|
||||
commandBuffer->transferBuffers = SDL_realloc(
|
||||
commandBuffer->transferBuffers,
|
||||
commandBuffer->transferBufferCapacity * sizeof(VulkanTransferBuffer*)
|
||||
);
|
||||
}
|
||||
|
||||
commandBuffer->transferBuffers[commandBuffer->transferBufferCount] = transferBuffer;
|
||||
commandBuffer->transferBufferCount += 1;
|
||||
|
||||
renderer->transferBufferPool.availableBuffers[i] = renderer->transferBufferPool.availableBuffers[renderer->transferBufferPool.availableBufferCount - 1];
|
||||
renderer->transferBufferPool.availableBufferCount -= 1;
|
||||
SDL_UnlockMutex(renderer->transferBufferPool.lock);
|
||||
|
||||
transferBuffer->offset = offset;
|
||||
return transferBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_UnlockMutex(renderer->transferBufferPool.lock);
|
||||
|
||||
/* Nothing fits, so let's create a new transfer buffer */
|
||||
|
||||
size = TRANSFER_BUFFER_STARTING_SIZE;
|
||||
|
@ -7118,10 +7174,12 @@ static VulkanTransferBuffer* VULKAN_INTERNAL_AcquireTransferBuffer(
|
|||
1,
|
||||
1
|
||||
);
|
||||
transferBuffer->fromPool = 0;
|
||||
|
||||
if (transferBuffer->buffer == NULL)
|
||||
{
|
||||
Refresh_LogError("Failed to allocate transfer buffer!");
|
||||
SDL_free(transferBuffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -10039,11 +10097,24 @@ static void VULKAN_INTERNAL_CleanCommandBuffer(
|
|||
commandBuffer->boundUniformBufferCount = 0;
|
||||
|
||||
for (i = 0; i < commandBuffer->transferBufferCount; i += 1)
|
||||
{
|
||||
if (commandBuffer->transferBuffers[i]->fromPool)
|
||||
{
|
||||
SDL_LockMutex(renderer->transferBufferPool.lock);
|
||||
|
||||
commandBuffer->transferBuffers[i]->offset = 0;
|
||||
renderer->transferBufferPool.availableBuffers[renderer->transferBufferPool.availableBufferCount] = commandBuffer->transferBuffers[i];
|
||||
renderer->transferBufferPool.availableBufferCount += 1;
|
||||
|
||||
SDL_UnlockMutex(renderer->transferBufferPool.lock);
|
||||
}
|
||||
else
|
||||
{
|
||||
VULKAN_INTERNAL_QueueDestroyBuffer(renderer, commandBuffer->transferBuffers[i]->buffer);
|
||||
SDL_free(commandBuffer->transferBuffers[i]);
|
||||
commandBuffer->transferBuffers[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
commandBuffer->transferBufferCount = 0;
|
||||
|
||||
|
@ -11392,6 +11463,9 @@ static Refresh_Device* VULKAN_CreateDevice(
|
|||
/* Variables: Image Format Detection */
|
||||
VkImageFormatProperties imageFormatProperties;
|
||||
|
||||
/* Variables: Transfer buffer init */
|
||||
VulkanTransferBuffer *transferBuffer;
|
||||
|
||||
SDL_memset(renderer, '\0', sizeof(VulkanRenderer));
|
||||
renderer->debugMode = debugMode;
|
||||
|
||||
|
@ -11774,6 +11848,40 @@ static Refresh_Device* VULKAN_CreateDevice(
|
|||
renderer->renderTargetHashArray.count = 0;
|
||||
renderer->renderTargetHashArray.capacity = 0;
|
||||
|
||||
/* Initialize transfer buffer pool */
|
||||
|
||||
renderer->transferBufferPool.lock = SDL_CreateMutex();
|
||||
|
||||
renderer->transferBufferPool.availableBufferCapacity = 4;
|
||||
renderer->transferBufferPool.availableBufferCount = 0;
|
||||
renderer->transferBufferPool.availableBuffers = SDL_malloc(
|
||||
renderer->transferBufferPool.availableBufferCapacity * sizeof(VulkanTransferBuffer*)
|
||||
);
|
||||
|
||||
for (i = 0; i < renderer->transferBufferPool.availableBufferCapacity; i += 1)
|
||||
{
|
||||
transferBuffer = SDL_malloc(sizeof(VulkanTransferBuffer));
|
||||
transferBuffer->offset = 0;
|
||||
transferBuffer->fromPool = 1;
|
||||
transferBuffer->buffer = VULKAN_INTERNAL_CreateBuffer(
|
||||
renderer,
|
||||
POOLED_TRANSFER_BUFFER_SIZE,
|
||||
RESOURCE_ACCESS_TRANSFER_READ_WRITE,
|
||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
1,
|
||||
1
|
||||
);
|
||||
|
||||
if (transferBuffer->buffer == NULL)
|
||||
{
|
||||
Refresh_LogError("Failed to allocate transfer buffer!");
|
||||
SDL_free(transferBuffer);
|
||||
}
|
||||
|
||||
renderer->transferBufferPool.availableBuffers[i] = transferBuffer;
|
||||
renderer->transferBufferPool.availableBufferCount += 1;
|
||||
}
|
||||
|
||||
/* Some drivers don't support D16, so we have to fall back to D32. */
|
||||
|
||||
vulkanResult = renderer->vkGetPhysicalDeviceImageFormatProperties(
|
||||
|
|
Loading…
Reference in New Issue