forked from MoonsideGames/Refresh
new command pool structure
parent
f8c99c4e18
commit
47c951ec14
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue