new command pool structure
							parent
							
								
									f3c0de6447
								
							
						
					
					
						commit
						872187c484
					
				|  | @ -987,6 +987,8 @@ struct BufferDescriptorSetCache | |||
| 
 | ||||
| /* Pipeline Caches */ | ||||
| 
 | ||||
| #define NUM_PIPELINE_LAYOUT_BUCKETS 1031 | ||||
| 
 | ||||
| typedef struct GraphicsPipelineLayoutHash | ||||
| { | ||||
| 	VkDescriptorSetLayout vertexSamplerLayout; | ||||
|  | @ -1008,8 +1010,6 @@ typedef struct GraphicsPipelineLayoutHashArray | |||
| 	int32_t capacity; | ||||
| } GraphicsPipelineLayoutHashArray; | ||||
| 
 | ||||
| #define NUM_PIPELINE_LAYOUT_BUCKETS 1031 | ||||
| 
 | ||||
| typedef struct GraphicsPipelineLayoutHashTable | ||||
| { | ||||
| 	GraphicsPipelineLayoutHashArray buckets[NUM_PIPELINE_LAYOUT_BUCKETS]; | ||||
|  | @ -1142,7 +1142,7 @@ static inline void ComputePipelineLayoutHashArray_Insert( | |||
| 	arr->count += 1; | ||||
| } | ||||
| 
 | ||||
| /* Context */ | ||||
| /* Command structures */ | ||||
| 
 | ||||
| typedef struct VulkanCommandPool VulkanCommandPool; | ||||
| 
 | ||||
|  | @ -1165,16 +1165,86 @@ typedef struct VulkanCommandBuffer | |||
| struct VulkanCommandPool | ||||
| { | ||||
| 	SDL_threadID threadID; | ||||
| 
 | ||||
| 	VkCommandPool commandPool; | ||||
| 
 | ||||
| 	uint32_t allocatedCommandBufferCount; | ||||
| 
 | ||||
| 	VulkanCommandBuffer **inactiveCommandBuffers; | ||||
| 	uint32_t inactiveCommandBufferCapacity; | ||||
| 	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 | ||||
| { | ||||
|     VkInstance instance; | ||||
|  | @ -1225,8 +1295,8 @@ typedef struct VulkanRenderer | |||
| 	uint32_t submittedCommandBufferCount; | ||||
| 	uint32_t submittedCommandBufferCapacity; | ||||
| 
 | ||||
| 	CommandPoolHashTable commandPoolHashTable; | ||||
| 	DescriptorSetLayoutHashTable descriptorSetLayoutHashTable; | ||||
| 
 | ||||
| 	GraphicsPipelineLayoutHashTable graphicsPipelineLayoutHashTable; | ||||
| 	ComputePipelineLayoutHashTable computePipelineLayoutHashTable; | ||||
| 
 | ||||
|  | @ -2236,6 +2306,20 @@ static void VULKAN_INTERNAL_DestroyBuffer( | |||
| 	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( | ||||
| 	VulkanRenderer *renderer, | ||||
| 	VulkanGraphicsPipeline *graphicsPipeline | ||||
|  | @ -3336,6 +3420,7 @@ static void VULKAN_DestroyDevice( | |||
| ) { | ||||
| 	VulkanRenderer* renderer = (VulkanRenderer*) device->driverData; | ||||
| 	VkResult waitResult; | ||||
| 	CommandPoolHashArray commandPoolHashArray; | ||||
| 	GraphicsPipelineLayoutHashArray graphicsPipelineLayoutHashArray; | ||||
| 	ComputePipelineLayoutHashArray computePipelineLayoutHashArray; | ||||
| 	VulkanMemorySubAllocator *allocator; | ||||
|  | @ -3385,7 +3470,22 @@ static void VULKAN_DestroyDevice( | |||
| 		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) | ||||
| 	{ | ||||
|  | @ -6843,9 +6943,9 @@ static void VULKAN_GetBufferData( | |||
| 
 | ||||
| 	vulkanResult = renderer->vkMapMemory( | ||||
| 		renderer->logicalDevice, | ||||
| 		vulkanBuffer->subBuffers[0]->allocation->memory, | ||||
| 		vulkanBuffer->subBuffers[0]->offset, | ||||
| 		vulkanBuffer->subBuffers[0]->size, | ||||
| 		vulkanBuffer->subBuffers[vulkanBuffer->currentSubBufferIndex]->allocation->memory, | ||||
| 		vulkanBuffer->subBuffers[vulkanBuffer->currentSubBufferIndex]->offset, | ||||
| 		vulkanBuffer->subBuffers[vulkanBuffer->currentSubBufferIndex]->size, | ||||
| 		0, | ||||
| 		(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( | ||||
| 	VulkanRenderer *renderer, | ||||
| 	SDL_threadID threadID | ||||
| ) { | ||||
| 	VulkanCommandPool *commandPool = | ||||
| 		VULKAN_INTERNAL_GetCommandPool(renderer, threadID); | ||||
| 		VULKAN_INTERNAL_FetchCommandPool(renderer, threadID); | ||||
| 	VulkanCommandBuffer *commandBuffer; | ||||
| 	VkCommandBufferAllocateInfo allocateInfo; | ||||
| 	VkResult vulkanResult; | ||||
| 
 | ||||
| 	if (commandPool->inactiveCommandBufferCount == 0) | ||||
| 	{ | ||||
| 		commandPool->inactiveCommandBuffers = SDL_realloc( | ||||
| 			commandPool->inactiveCommandBuffers, | ||||
| 			sizeof(VulkanCommandBuffer*) * commandPool->allocatedCommandBufferCount * 2 | ||||
| 		VULKAN_INTERNAL_AllocateCommandBuffers( | ||||
| 			renderer, | ||||
| 			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]; | ||||
|  | @ -9469,6 +9652,13 @@ static REFRESH_Device* VULKAN_CreateDevice( | |||
| 
 | ||||
| 	/* 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) | ||||
| 	{ | ||||
| 		renderer->graphicsPipelineLayoutHashTable.buckets[i].elements = NULL; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue