revise fence usage
							parent
							
								
									4ad948aba4
								
							
						
					
					
						commit
						5df612f7b1
					
				|  | @ -1352,11 +1352,18 @@ typedef struct VulkanRenderer | ||||||
| 	VkQueue computeQueue; | 	VkQueue computeQueue; | ||||||
| 	VkQueue transferQueue; | 	VkQueue transferQueue; | ||||||
| 
 | 
 | ||||||
| 	VkFence inFlightFence; |  | ||||||
| 	VkSemaphore transferFinishedSemaphore; | 	VkSemaphore transferFinishedSemaphore; | ||||||
| 	VkSemaphore imageAvailableSemaphore; | 	VkSemaphore imageAvailableSemaphore; | ||||||
| 	VkSemaphore renderFinishedSemaphore; | 	VkSemaphore renderFinishedSemaphore; | ||||||
| 
 | 
 | ||||||
|  | 	VkFence *availableFences; | ||||||
|  | 	uint32_t availableFenceCount; | ||||||
|  | 	uint32_t availableFenceCapacity; | ||||||
|  | 
 | ||||||
|  | 	VkFence *usedFences; | ||||||
|  | 	uint32_t usedFenceCount; | ||||||
|  | 	uint32_t usedFenceCapacity; | ||||||
|  | 
 | ||||||
| 	VulkanCommandBuffer **submittedCommandBuffers; | 	VulkanCommandBuffer **submittedCommandBuffers; | ||||||
| 	uint32_t submittedCommandBufferCount; | 	uint32_t submittedCommandBufferCount; | ||||||
| 	uint32_t submittedCommandBufferCapacity; | 	uint32_t submittedCommandBufferCapacity; | ||||||
|  | @ -1403,6 +1410,7 @@ typedef struct VulkanRenderer | ||||||
| 	SDL_mutex *allocatorLock; | 	SDL_mutex *allocatorLock; | ||||||
| 	SDL_mutex *disposeLock; | 	SDL_mutex *disposeLock; | ||||||
| 	SDL_mutex *boundBufferLock; | 	SDL_mutex *boundBufferLock; | ||||||
|  | 	SDL_mutex *submitLock; | ||||||
| 
 | 
 | ||||||
| 	/* Deferred destroy storage */ | 	/* Deferred destroy storage */ | ||||||
| 
 | 
 | ||||||
|  | @ -4522,11 +4530,23 @@ static void VULKAN_DestroyDevice( | ||||||
| 		NULL | 		NULL | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 	renderer->vkDestroyFence( | 	for (i = 0; i < renderer->availableFenceCount; i += 1) | ||||||
| 		renderer->logicalDevice, | 	{ | ||||||
| 		renderer->inFlightFence, | 		renderer->vkDestroyFence( | ||||||
| 		NULL | 			renderer->logicalDevice, | ||||||
| 	); | 			renderer->availableFences[i], | ||||||
|  | 			NULL | ||||||
|  | 		); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < renderer->usedFenceCount; i += 1) | ||||||
|  | 	{ | ||||||
|  | 		renderer->vkDestroyFence( | ||||||
|  | 			renderer->logicalDevice, | ||||||
|  | 			renderer->usedFences[i], | ||||||
|  | 			NULL | ||||||
|  | 		); | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	for (i = 0; i < NUM_COMMAND_POOL_BUCKETS; i += 1) | 	for (i = 0; i < NUM_COMMAND_POOL_BUCKETS; i += 1) | ||||||
| 	{ | 	{ | ||||||
|  | @ -4707,6 +4727,7 @@ static void VULKAN_DestroyDevice( | ||||||
| 	SDL_DestroyMutex(renderer->allocatorLock); | 	SDL_DestroyMutex(renderer->allocatorLock); | ||||||
| 	SDL_DestroyMutex(renderer->disposeLock); | 	SDL_DestroyMutex(renderer->disposeLock); | ||||||
| 	SDL_DestroyMutex(renderer->boundBufferLock); | 	SDL_DestroyMutex(renderer->boundBufferLock); | ||||||
|  | 	SDL_DestroyMutex(renderer->submitLock); | ||||||
| 
 | 
 | ||||||
| 	SDL_free(renderer->buffersInUse); | 	SDL_free(renderer->buffersInUse); | ||||||
| 
 | 
 | ||||||
|  | @ -8436,6 +8457,103 @@ static void VULKAN_INTERNAL_ResetCommandBuffer( | ||||||
| 	commandPool->inactiveCommandBufferCount += 1; | 	commandPool->inactiveCommandBufferCount += 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /* Fence management */ | ||||||
|  | 
 | ||||||
|  | static VkFence VULKAN_INTERNAL_AcquireFence( | ||||||
|  | 	VulkanRenderer *renderer | ||||||
|  | ) { | ||||||
|  | 	VkFenceCreateInfo fenceCreateInfo; | ||||||
|  | 	VkFence fence; | ||||||
|  | 	VkResult fenceCreateResult; | ||||||
|  | 
 | ||||||
|  | 	if (renderer->availableFenceCount == 0) | ||||||
|  | 	{ | ||||||
|  | 		fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; | ||||||
|  | 		fenceCreateInfo.pNext = NULL; | ||||||
|  | 		fenceCreateInfo.flags = 0; | ||||||
|  | 
 | ||||||
|  | 		fenceCreateResult = renderer->vkCreateFence( | ||||||
|  | 			renderer->logicalDevice, | ||||||
|  | 			&fenceCreateInfo, | ||||||
|  | 			NULL, | ||||||
|  | 			&renderer->availableFences[0] | ||||||
|  | 		); | ||||||
|  | 
 | ||||||
|  | 		if (fenceCreateResult != VK_SUCCESS) | ||||||
|  | 		{ | ||||||
|  | 			LogVulkanResultAsError("vkCreateFence", fenceCreateResult); | ||||||
|  | 			return VK_NULL_HANDLE; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		renderer->availableFenceCount += 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fence = renderer->availableFences[renderer->availableFenceCount - 1]; | ||||||
|  | 	renderer->availableFenceCount -= 1; | ||||||
|  | 
 | ||||||
|  | 	if (renderer->usedFenceCount >= renderer->usedFenceCapacity) | ||||||
|  | 	{ | ||||||
|  | 		renderer->usedFenceCapacity *= 2; | ||||||
|  | 		renderer->usedFences = SDL_realloc( | ||||||
|  | 			renderer->usedFences, | ||||||
|  | 			renderer->usedFenceCapacity * sizeof(VkFence) | ||||||
|  | 		); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	renderer->usedFences[renderer->usedFenceCount] = fence; | ||||||
|  | 	renderer->usedFenceCount += 1; | ||||||
|  | 
 | ||||||
|  | 	return fence; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void VULKAN_INTERNAL_ResetUsedFences( | ||||||
|  | 	VulkanRenderer *renderer | ||||||
|  | ) { | ||||||
|  | 	uint32_t i; | ||||||
|  | 
 | ||||||
|  | 	/* Prepare the command buffer fence for submission */ | ||||||
|  | 	renderer->vkResetFences( | ||||||
|  | 		renderer->logicalDevice, | ||||||
|  | 		renderer->usedFenceCount, | ||||||
|  | 		renderer->usedFences | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	/* Used fences are now available */ | ||||||
|  | 	if (renderer->usedFenceCount + renderer->availableFenceCount >= renderer->availableFenceCapacity) | ||||||
|  | 	{ | ||||||
|  | 		renderer->availableFenceCapacity = renderer->usedFenceCount + renderer->availableFenceCount; | ||||||
|  | 		renderer->availableFences = SDL_realloc( | ||||||
|  | 			renderer->availableFences, | ||||||
|  | 			renderer->availableFenceCapacity * sizeof(VkFence) | ||||||
|  | 		); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < renderer->usedFenceCount; i += 1) | ||||||
|  | 	{ | ||||||
|  | 		renderer->availableFences[renderer->availableFenceCount] = renderer->usedFences[i]; | ||||||
|  | 		renderer->availableFenceCount += 1; | ||||||
|  | 	} | ||||||
|  | 	renderer->usedFenceCount = 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Submission structure */ | ||||||
|  | 
 | ||||||
|  | static void VULKAN_Wait( | ||||||
|  |     Refresh_Renderer *driverData | ||||||
|  | ) { | ||||||
|  | 	VulkanRenderer *renderer = (VulkanRenderer*) driverData; | ||||||
|  | 
 | ||||||
|  | 	renderer->vkWaitForFences( | ||||||
|  | 		renderer->logicalDevice, | ||||||
|  | 		renderer->usedFenceCount, | ||||||
|  | 		renderer->usedFences, | ||||||
|  | 		VK_TRUE, | ||||||
|  | 		UINT64_MAX | ||||||
|  | 	); | ||||||
|  | 
 | ||||||
|  | 	VULKAN_INTERNAL_ResetUsedFences(renderer); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void VULKAN_Submit( | static void VULKAN_Submit( | ||||||
|     Refresh_Renderer *driverData, |     Refresh_Renderer *driverData, | ||||||
| 	uint32_t commandBufferCount, | 	uint32_t commandBufferCount, | ||||||
|  | @ -8448,12 +8566,15 @@ static void VULKAN_Submit( | ||||||
| 	VkCommandBuffer *commandBuffers; | 	VkCommandBuffer *commandBuffers; | ||||||
| 	uint32_t i; | 	uint32_t i; | ||||||
| 	uint8_t present = 0; | 	uint8_t present = 0; | ||||||
|  | 	VkFence fence; | ||||||
| 
 | 
 | ||||||
| 	VkPipelineStageFlags waitStages[2]; | 	VkPipelineStageFlags waitStages[2]; | ||||||
| 	VkSemaphore waitSemaphores[2]; | 	VkSemaphore waitSemaphores[2]; | ||||||
| 	uint32_t waitSemaphoreCount = 0; | 	uint32_t waitSemaphoreCount = 0; | ||||||
| 	VkPresentInfoKHR presentInfo; | 	VkPresentInfoKHR presentInfo; | ||||||
| 
 | 
 | ||||||
|  | 	SDL_LockMutex(renderer->submitLock); | ||||||
|  | 
 | ||||||
| 	commandBuffers = SDL_stack_alloc(VkCommandBuffer, commandBufferCount); | 	commandBuffers = SDL_stack_alloc(VkCommandBuffer, commandBufferCount); | ||||||
| 
 | 
 | ||||||
| 	for (i = 0; i < commandBufferCount; i += 1) | 	for (i = 0; i < commandBufferCount; i += 1) | ||||||
|  | @ -8496,8 +8617,8 @@ static void VULKAN_Submit( | ||||||
| 		/* Wait for the previous submission to complete */ | 		/* Wait for the previous submission to complete */ | ||||||
| 		vulkanResult = renderer->vkWaitForFences( | 		vulkanResult = renderer->vkWaitForFences( | ||||||
| 			renderer->logicalDevice, | 			renderer->logicalDevice, | ||||||
| 			1, | 			renderer->usedFenceCount, | ||||||
| 			&renderer->inFlightFence, | 			renderer->usedFences, | ||||||
| 			VK_TRUE, | 			VK_TRUE, | ||||||
| 			UINT64_MAX | 			UINT64_MAX | ||||||
| 		); | 		); | ||||||
|  | @ -8523,12 +8644,16 @@ static void VULKAN_Submit( | ||||||
| 		} | 		} | ||||||
| 		renderer->submittedCommandBufferCount = 0; | 		renderer->submittedCommandBufferCount = 0; | ||||||
| 
 | 
 | ||||||
| 		/* Prepare the command buffer fence for submission */ | 		VULKAN_INTERNAL_ResetUsedFences(renderer); | ||||||
| 		renderer->vkResetFences( | 	} | ||||||
| 			renderer->logicalDevice, | 
 | ||||||
| 			1, | 	/* Acquire a fence */ | ||||||
| 			&renderer->inFlightFence | 	fence = VULKAN_INTERNAL_AcquireFence(renderer); | ||||||
| 		); | 
 | ||||||
|  | 	if (fence == VK_NULL_HANDLE) | ||||||
|  | 	{ | ||||||
|  | 		Refresh_LogError("Failed to acquire fence!"); | ||||||
|  | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* Submit the commands, finally. */ | 	/* Submit the commands, finally. */ | ||||||
|  | @ -8536,7 +8661,7 @@ static void VULKAN_Submit( | ||||||
| 		renderer->graphicsQueue, | 		renderer->graphicsQueue, | ||||||
| 		1, | 		1, | ||||||
| 		&submitInfo, | 		&submitInfo, | ||||||
| 		present ? renderer->inFlightFence : VK_NULL_HANDLE | 		fence | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 	if (vulkanResult != VK_SUCCESS) | 	if (vulkanResult != VK_SUCCESS) | ||||||
|  | @ -8590,20 +8715,8 @@ static void VULKAN_Submit( | ||||||
| 	renderer->swapChainImageAcquired = 0; | 	renderer->swapChainImageAcquired = 0; | ||||||
| 
 | 
 | ||||||
| 	SDL_stack_free(commandBuffers); | 	SDL_stack_free(commandBuffers); | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| static void VULKAN_Wait( | 	SDL_UnlockMutex(renderer->submitLock); | ||||||
|     Refresh_Renderer *driverData |  | ||||||
| ) { |  | ||||||
| 	VulkanRenderer *renderer = (VulkanRenderer*) driverData; |  | ||||||
| 
 |  | ||||||
| 	renderer->vkWaitForFences( |  | ||||||
| 		renderer->logicalDevice, |  | ||||||
| 		1, |  | ||||||
| 		&renderer->inFlightFence, |  | ||||||
| 		VK_TRUE, |  | ||||||
| 		UINT64_MAX |  | ||||||
| 	); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* External interop */ | /* External interop */ | ||||||
|  | @ -9291,8 +9404,7 @@ static Refresh_Device* VULKAN_INTERNAL_CreateDevice( | ||||||
|     VkResult vulkanResult; |     VkResult vulkanResult; | ||||||
| 	uint32_t i; | 	uint32_t i; | ||||||
| 
 | 
 | ||||||
|     /* Variables: Create fence and semaphores */ |     /* Variables: Create semaphores */ | ||||||
| 	VkFenceCreateInfo fenceInfo; |  | ||||||
| 	VkSemaphoreCreateInfo semaphoreInfo; | 	VkSemaphoreCreateInfo semaphoreInfo; | ||||||
| 
 | 
 | ||||||
| 	/* Variables: Descriptor set layouts */ | 	/* Variables: Descriptor set layouts */ | ||||||
|  | @ -9333,13 +9445,9 @@ static Refresh_Device* VULKAN_INTERNAL_CreateDevice( | ||||||
| 	renderer->swapChainImageAcquired = 0; | 	renderer->swapChainImageAcquired = 0; | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Create fence and semaphores | 	 * Create semaphores | ||||||
| 	 */ | 	 */ | ||||||
| 
 | 
 | ||||||
| 	fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; |  | ||||||
| 	fenceInfo.pNext = NULL; |  | ||||||
| 	fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; |  | ||||||
| 
 |  | ||||||
| 	semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; | 	semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; | ||||||
| 	semaphoreInfo.pNext = NULL; | 	semaphoreInfo.pNext = NULL; | ||||||
| 	semaphoreInfo.flags = 0; | 	semaphoreInfo.flags = 0; | ||||||
|  | @ -9383,24 +9491,22 @@ static Refresh_Device* VULKAN_INTERNAL_CreateDevice( | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	vulkanResult = renderer->vkCreateFence( |  | ||||||
| 		renderer->logicalDevice, |  | ||||||
| 		&fenceInfo, |  | ||||||
| 		NULL, |  | ||||||
| 		&renderer->inFlightFence |  | ||||||
| 	); |  | ||||||
| 
 |  | ||||||
| 	if (vulkanResult != VK_SUCCESS) |  | ||||||
| 	{ |  | ||||||
| 		LogVulkanResultAsError("vkCreateFence", vulkanResult); |  | ||||||
| 		return NULL; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* Threading */ | 	/* Threading */ | ||||||
| 
 | 
 | ||||||
| 	renderer->allocatorLock = SDL_CreateMutex(); | 	renderer->allocatorLock = SDL_CreateMutex(); | ||||||
| 	renderer->disposeLock = SDL_CreateMutex(); | 	renderer->disposeLock = SDL_CreateMutex(); | ||||||
| 	renderer->boundBufferLock = SDL_CreateMutex(); | 	renderer->boundBufferLock = SDL_CreateMutex(); | ||||||
|  | 	renderer->submitLock = SDL_CreateMutex(); | ||||||
|  | 
 | ||||||
|  | 	/* Create fence lists */ | ||||||
|  | 
 | ||||||
|  | 	renderer->availableFenceCount = 0; | ||||||
|  | 	renderer->availableFenceCapacity = 4; | ||||||
|  | 	renderer->availableFences = SDL_malloc(renderer->availableFenceCapacity * sizeof(VkFence)); | ||||||
|  | 
 | ||||||
|  | 	renderer->usedFenceCount = 0; | ||||||
|  | 	renderer->usedFenceCapacity = 4; | ||||||
|  | 	renderer->usedFences = SDL_malloc(renderer->usedFenceCapacity * sizeof(VkFence)); | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Create submitted command buffer list | 	 * Create submitted command buffer list | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue