new command pool structure

pull/9/head
cosmonaut 2021-01-02 18:02:20 -08:00 committed by thatcosmonaut
parent f8c99c4e18
commit 47c951ec14
1 changed files with 228 additions and 38 deletions

View File

@ -987,6 +987,8 @@ struct BufferDescriptorSetCache
/* Pipeline Caches */ /* Pipeline Caches */
#define NUM_PIPELINE_LAYOUT_BUCKETS 1031
typedef struct GraphicsPipelineLayoutHash typedef struct GraphicsPipelineLayoutHash
{ {
VkDescriptorSetLayout vertexSamplerLayout; VkDescriptorSetLayout vertexSamplerLayout;
@ -1008,8 +1010,6 @@ typedef struct GraphicsPipelineLayoutHashArray
int32_t capacity; int32_t capacity;
} GraphicsPipelineLayoutHashArray; } GraphicsPipelineLayoutHashArray;
#define NUM_PIPELINE_LAYOUT_BUCKETS 1031
typedef struct GraphicsPipelineLayoutHashTable typedef struct GraphicsPipelineLayoutHashTable
{ {
GraphicsPipelineLayoutHashArray buckets[NUM_PIPELINE_LAYOUT_BUCKETS]; GraphicsPipelineLayoutHashArray buckets[NUM_PIPELINE_LAYOUT_BUCKETS];
@ -1142,7 +1142,7 @@ static inline void ComputePipelineLayoutHashArray_Insert(
arr->count += 1; arr->count += 1;
} }
/* Context */ /* Command structures */
typedef struct VulkanCommandPool VulkanCommandPool; typedef struct VulkanCommandPool VulkanCommandPool;
@ -1165,16 +1165,86 @@ typedef struct VulkanCommandBuffer
struct VulkanCommandPool struct VulkanCommandPool
{ {
SDL_threadID threadID; SDL_threadID threadID;
VkCommandPool commandPool; VkCommandPool commandPool;
uint32_t allocatedCommandBufferCount;
VulkanCommandBuffer **inactiveCommandBuffers; VulkanCommandBuffer **inactiveCommandBuffers;
uint32_t inactiveCommandBufferCapacity; uint32_t inactiveCommandBufferCapacity;
uint32_t inactiveCommandBufferCount; uint32_t inactiveCommandBufferCount;
}; };
#define NUM_COMMAND_POOL_BUCKETS 1031
typedef struct CommandPoolHash
{
SDL_threadID threadID;
} CommandPoolHash;
typedef struct CommandPoolHashMap
{
CommandPoolHash key;
VulkanCommandPool *value;
} CommandPoolHashMap;
typedef struct CommandPoolHashArray
{
CommandPoolHashMap *elements;
uint32_t count;
uint32_t capacity;
} CommandPoolHashArray;
typedef struct CommandPoolHashTable
{
CommandPoolHashArray buckets[NUM_COMMAND_POOL_BUCKETS];
} CommandPoolHashTable;
static inline uint64_t CommandPoolHashTable_GetHashCode(CommandPoolHash key)
{
const uint64_t HASH_FACTOR = 97;
uint64_t result = 1;
result = result * HASH_FACTOR + (uint64_t) key.threadID;
return result;
}
static inline VulkanCommandPool* CommandPoolHashTable_Fetch(
CommandPoolHashTable *table,
CommandPoolHash key
) {
uint32_t i;
uint64_t hashcode = CommandPoolHashTable_GetHashCode(key);
CommandPoolHashArray *arr = &table->buckets[hashcode % NUM_COMMAND_POOL_BUCKETS];
for (i = 0; i < arr->count; i += 1)
{
const CommandPoolHash *e = &arr->elements[i].key;
if (key.threadID == e->threadID)
{
return arr->elements[i].value;
}
}
return NULL;
}
static inline void CommandPoolHashTable_Insert(
CommandPoolHashTable *table,
CommandPoolHash key,
VulkanCommandPool *value
) {
uint64_t hashcode = CommandPoolHashTable_GetHashCode(key);
CommandPoolHashArray *arr = &table->buckets[hashcode % NUM_COMMAND_POOL_BUCKETS];
CommandPoolHashMap map;
map.key = key;
map.value = value;
EXPAND_ELEMENTS_IF_NEEDED(arr, 4, CommandPoolHashMap)
arr->elements[arr->count] = map;
arr->count += 1;
}
/* Context */
typedef struct VulkanRenderer typedef struct VulkanRenderer
{ {
VkInstance instance; VkInstance instance;
@ -1225,8 +1295,8 @@ typedef struct VulkanRenderer
uint32_t submittedCommandBufferCount; uint32_t submittedCommandBufferCount;
uint32_t submittedCommandBufferCapacity; uint32_t submittedCommandBufferCapacity;
CommandPoolHashTable commandPoolHashTable;
DescriptorSetLayoutHashTable descriptorSetLayoutHashTable; DescriptorSetLayoutHashTable descriptorSetLayoutHashTable;
GraphicsPipelineLayoutHashTable graphicsPipelineLayoutHashTable; GraphicsPipelineLayoutHashTable graphicsPipelineLayoutHashTable;
ComputePipelineLayoutHashTable computePipelineLayoutHashTable; ComputePipelineLayoutHashTable computePipelineLayoutHashTable;
@ -2236,6 +2306,20 @@ static void VULKAN_INTERNAL_DestroyBuffer(
SDL_free(buffer); SDL_free(buffer);
} }
static void VULKAN_INTERNAL_DestroyCommandPool(
VulkanRenderer *renderer,
VulkanCommandPool *commandPool
) {
renderer->vkResetCommandPool(
renderer->logicalDevice,
commandPool->commandPool,
VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT
);
SDL_free(commandPool->inactiveCommandBuffers);
SDL_free(commandPool);
}
static void VULKAN_INTERNAL_DestroyGraphicsPipeline( static void VULKAN_INTERNAL_DestroyGraphicsPipeline(
VulkanRenderer *renderer, VulkanRenderer *renderer,
VulkanGraphicsPipeline *graphicsPipeline VulkanGraphicsPipeline *graphicsPipeline
@ -3336,6 +3420,7 @@ static void VULKAN_DestroyDevice(
) { ) {
VulkanRenderer* renderer = (VulkanRenderer*) device->driverData; VulkanRenderer* renderer = (VulkanRenderer*) device->driverData;
VkResult waitResult; VkResult waitResult;
CommandPoolHashArray commandPoolHashArray;
GraphicsPipelineLayoutHashArray graphicsPipelineLayoutHashArray; GraphicsPipelineLayoutHashArray graphicsPipelineLayoutHashArray;
ComputePipelineLayoutHashArray computePipelineLayoutHashArray; ComputePipelineLayoutHashArray computePipelineLayoutHashArray;
VulkanMemorySubAllocator *allocator; VulkanMemorySubAllocator *allocator;
@ -3385,7 +3470,22 @@ static void VULKAN_DestroyDevice(
NULL NULL
); );
/* TODO: destroy command pools */ for (i = 0; i < NUM_COMMAND_POOL_BUCKETS; i += 1)
{
commandPoolHashArray = renderer->commandPoolHashTable.buckets[i];
for (j = 0; j < commandPoolHashArray.count; j += 1)
{
VULKAN_INTERNAL_DestroyCommandPool(
renderer,
commandPoolHashArray.elements[j].value
);
}
if (commandPoolHashArray.elements != NULL)
{
SDL_free(commandPoolHashArray.elements);
}
}
for (i = 0; i < NUM_PIPELINE_LAYOUT_BUCKETS; i += 1) for (i = 0; i < NUM_PIPELINE_LAYOUT_BUCKETS; i += 1)
{ {
@ -6843,9 +6943,9 @@ static void VULKAN_GetBufferData(
vulkanResult = renderer->vkMapMemory( vulkanResult = renderer->vkMapMemory(
renderer->logicalDevice, renderer->logicalDevice,
vulkanBuffer->subBuffers[0]->allocation->memory, vulkanBuffer->subBuffers[vulkanBuffer->currentSubBufferIndex]->allocation->memory,
vulkanBuffer->subBuffers[0]->offset, vulkanBuffer->subBuffers[vulkanBuffer->currentSubBufferIndex]->offset,
vulkanBuffer->subBuffers[0]->size, vulkanBuffer->subBuffers[vulkanBuffer->currentSubBufferIndex]->size,
0, 0,
(void**) &mapPointer (void**) &mapPointer
); );
@ -7591,43 +7691,126 @@ static void VULKAN_BindComputeTextures(
); );
} }
static void VULKAN_INTERNAL_AllocateCommandBuffers(
VulkanRenderer *renderer,
VulkanCommandPool *vulkanCommandPool,
uint32_t allocateCount
) {
VkCommandBufferAllocateInfo allocateInfo;
VkResult vulkanResult;
uint32_t i;
VkCommandBuffer *commandBuffers = SDL_stack_alloc(VkCommandBuffer, allocateCount);
VulkanCommandBuffer *currentVulkanCommandBuffer;
vulkanCommandPool->inactiveCommandBufferCapacity += allocateCount;
vulkanCommandPool->inactiveCommandBuffers = SDL_realloc(
vulkanCommandPool->inactiveCommandBuffers,
sizeof(VulkanCommandBuffer*) *
vulkanCommandPool->inactiveCommandBufferCapacity
);
allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
allocateInfo.pNext = NULL;
allocateInfo.commandPool = vulkanCommandPool->commandPool;
allocateInfo.commandBufferCount = allocateCount;
allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
vulkanResult = renderer->vkAllocateCommandBuffers(
renderer->logicalDevice,
&allocateInfo,
commandBuffers
);
if (vulkanResult != VK_SUCCESS)
{
LogVulkanResult("vkAllocateCommandBuffers", vulkanResult);
SDL_stack_free(commandBuffers);
return;
}
for (i = 0; i < allocateCount; i += 1)
{
currentVulkanCommandBuffer = SDL_malloc(sizeof(VulkanCommandBuffer));
currentVulkanCommandBuffer->commandBuffer = commandBuffers[i];
vulkanCommandPool->inactiveCommandBuffers[
vulkanCommandPool->inactiveCommandBufferCount
] = currentVulkanCommandBuffer;
vulkanCommandPool->inactiveCommandBufferCount += 1;
}
SDL_stack_free(commandBuffers);
}
static VulkanCommandPool* VULKAN_INTERNAL_FetchCommandPool(
VulkanRenderer *renderer,
SDL_threadID threadID
) {
VulkanCommandPool *vulkanCommandPool;
VkCommandPoolCreateInfo commandPoolCreateInfo;
VkResult vulkanResult;
CommandPoolHash commandPoolHash;
commandPoolHash.threadID = threadID;
vulkanCommandPool = CommandPoolHashTable_Fetch(
&renderer->commandPoolHashTable,
commandPoolHash
);
if (vulkanCommandPool != NULL)
{
return vulkanCommandPool;
}
commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
commandPoolCreateInfo.pNext = NULL;
commandPoolCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
commandPoolCreateInfo.queueFamilyIndex = renderer->queueFamilyIndices.graphicsFamily;
vulkanResult = renderer->vkCreateCommandPool(
renderer->logicalDevice,
&commandPoolCreateInfo,
NULL,
&vulkanCommandPool->commandPool
);
vulkanCommandPool->threadID = threadID;
vulkanCommandPool->inactiveCommandBufferCapacity = 0;
vulkanCommandPool->inactiveCommandBufferCount = 0;
vulkanCommandPool->inactiveCommandBuffers = NULL;
VULKAN_INTERNAL_AllocateCommandBuffers(
renderer,
vulkanCommandPool,
2
);
CommandPoolHashTable_Insert(
&renderer->commandPoolHashTable,
commandPoolHash,
vulkanCommandPool
);
return vulkanCommandPool;
}
static VulkanCommandBuffer* VULKAN_INTERNAL_GetInactiveCommandBufferFromPool( static VulkanCommandBuffer* VULKAN_INTERNAL_GetInactiveCommandBufferFromPool(
VulkanRenderer *renderer, VulkanRenderer *renderer,
SDL_threadID threadID SDL_threadID threadID
) { ) {
VulkanCommandPool *commandPool = VulkanCommandPool *commandPool =
VULKAN_INTERNAL_GetCommandPool(renderer, threadID); VULKAN_INTERNAL_FetchCommandPool(renderer, threadID);
VulkanCommandBuffer *commandBuffer; VulkanCommandBuffer *commandBuffer;
VkCommandBufferAllocateInfo allocateInfo;
VkResult vulkanResult;
if (commandPool->inactiveCommandBufferCount == 0) if (commandPool->inactiveCommandBufferCount == 0)
{ {
commandPool->inactiveCommandBuffers = SDL_realloc( VULKAN_INTERNAL_AllocateCommandBuffers(
commandPool->inactiveCommandBuffers, renderer,
sizeof(VulkanCommandBuffer*) * commandPool->allocatedCommandBufferCount * 2 commandPool,
commandPool->inactiveCommandBufferCapacity
); );
allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
allocateInfo.pNext = NULL;
allocateInfo.commandPool = commandPool->commandPool;
allocateInfo.commandBufferCount = commandPool->allocatedCommandBufferCount;
allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
vulkanResult = renderer->vkAllocateCommandBuffers(
renderer->logicalDevice,
&allocateInfo,
commandPool->inactiveCommandBuffers
);
if (vulkanResult != VK_SUCCESS)
{
LogVulkanResult("vkAllocateCommandBuffers", vulkanResult);
return NULL;
}
commandPool->inactiveCommandBufferCount = commandPool->allocatedCommandBufferCount;
commandPool->allocatedCommandBufferCount *= 2;
} }
commandBuffer = commandPool->inactiveCommandBuffers[commandPool->inactiveCommandBufferCount]; commandBuffer = commandPool->inactiveCommandBuffers[commandPool->inactiveCommandBufferCount];
@ -9469,6 +9652,13 @@ static REFRESH_Device* VULKAN_CreateDevice(
/* Initialize caches */ /* Initialize caches */
for (i = 0; i < NUM_COMMAND_POOL_BUCKETS; i += 1)
{
renderer->commandPoolHashTable.buckets[i].elements = NULL;
renderer->commandPoolHashTable.buckets[i].count = 0;
renderer->commandPoolHashTable.buckets[i].capacity = 0;
}
for (i = 0; i < NUM_PIPELINE_LAYOUT_BUCKETS; i += 1) for (i = 0; i < NUM_PIPELINE_LAYOUT_BUCKETS; i += 1)
{ {
renderer->graphicsPipelineLayoutHashTable.buckets[i].elements = NULL; renderer->graphicsPipelineLayoutHashTable.buckets[i].elements = NULL;