swapchain recreate timing fix
	
		
			
	
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
					Details
				
			
		
	
				
					
				
			
				
	
				continuous-integration/drone/push Build is passing
				
					Details
				
			
		
	
							parent
							
								
									83ce2a3619
								
							
						
					
					
						commit
						74c5ac984c
					
				|  | @ -988,6 +988,7 @@ REFRESHAPI void Refresh_QueueDestroyGraphicsPipeline( | |||
|  * 		The area affected by the render pass. | ||||
|  * 		All load, store and resolve operations are restricted | ||||
|  * 		to the given rectangle. | ||||
|  * 		If NULL, a sensible default will be chosen. | ||||
|  * colorAttachmentInfos: | ||||
|  * 		A pointer to an array of Refresh_ColorAttachmentInfo structures | ||||
|  * 		that contains render targets and clear values. May be NULL. | ||||
|  |  | |||
|  | @ -169,13 +169,6 @@ typedef enum VulkanResourceAccessType | |||
| 	RESOURCE_ACCESS_TYPES_COUNT | ||||
| } VulkanResourceAccessType; | ||||
| 
 | ||||
| typedef enum CreateSwapchainResult | ||||
| { | ||||
| 	CREATE_SWAPCHAIN_FAIL, | ||||
| 	CREATE_SWAPCHAIN_SUCCESS, | ||||
| 	CREATE_SWAPCHAIN_SURFACE_ZERO, | ||||
| } CreateSwapchainResult; | ||||
| 
 | ||||
| /* Conversions */ | ||||
| 
 | ||||
| static const uint8_t DEVICE_PRIORITY[] = | ||||
|  | @ -4095,7 +4088,7 @@ static uint8_t VULKAN_INTERNAL_ChooseSwapPresentMode( | |||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | ||||
| static uint8_t VULKAN_INTERNAL_CreateSwapchain( | ||||
| 	VulkanRenderer *renderer, | ||||
| 	void *windowHandle | ||||
| ) { | ||||
|  | @ -4124,7 +4117,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | |||
| 			"SDL_Vulkan_CreateSurface failed: %s", | ||||
| 			SDL_GetError() | ||||
| 		); | ||||
| 		return CREATE_SWAPCHAIN_FAIL; | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!VULKAN_INTERNAL_QuerySwapChainSupport( | ||||
|  | @ -4149,7 +4142,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | |||
| 		} | ||||
| 		SDL_free(swapchainData); | ||||
| 		Refresh_LogError("Device does not support swap chain creation"); | ||||
| 		return CREATE_SWAPCHAIN_FAIL; | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	swapchainData->swapchainFormat = VK_FORMAT_R8G8B8A8_UNORM; | ||||
|  | @ -4191,7 +4184,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | |||
| 			} | ||||
| 			SDL_free(swapchainData); | ||||
| 			Refresh_LogError("Device does not support swap chain format"); | ||||
| 			return CREATE_SWAPCHAIN_FAIL; | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -4216,7 +4209,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | |||
| 		} | ||||
| 		SDL_free(swapchainData); | ||||
| 		Refresh_LogError("Device does not support swap chain present mode"); | ||||
| 		return CREATE_SWAPCHAIN_FAIL; | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	SDL_Vulkan_GetDrawableSize( | ||||
|  | @ -4247,7 +4240,8 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | |||
| 				SDL_free(swapchainSupportDetails.presentModes); | ||||
| 			} | ||||
| 			SDL_free(swapchainData); | ||||
| 			return CREATE_SWAPCHAIN_SURFACE_ZERO; | ||||
| 			/* Not an error, just Windows minimize behavior! */ | ||||
| 			return 0; | ||||
| 		} | ||||
| 
 | ||||
| 		if (swapchainSupportDetails.capabilities.currentExtent.width != UINT32_MAX) | ||||
|  | @ -4280,7 +4274,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | |||
| 			} | ||||
| 			SDL_free(swapchainData); | ||||
| 			Refresh_LogError("No fallback swapchain size available!"); | ||||
| 			return CREATE_SWAPCHAIN_FAIL; | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -4353,7 +4347,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | |||
| 		); | ||||
| 		SDL_free(swapchainData); | ||||
| 		LogVulkanResultAsError("vkCreateSwapchainKHR", vulkanResult); | ||||
| 		return CREATE_SWAPCHAIN_FAIL; | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	renderer->vkGetSwapchainImagesKHR( | ||||
|  | @ -4376,7 +4370,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | |||
| 			NULL | ||||
| 		); | ||||
| 		SDL_free(swapchainData); | ||||
| 		return CREATE_SWAPCHAIN_FAIL; | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	swapchainImages = SDL_stack_alloc(VkImage, swapchainData->imageCount); | ||||
|  | @ -4424,7 +4418,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | |||
| 			SDL_free(swapchainData->textures); | ||||
| 			SDL_free(swapchainData); | ||||
| 			LogVulkanResultAsError("vkCreateImageView", vulkanResult); | ||||
| 			return CREATE_SWAPCHAIN_FAIL; | ||||
| 			return 0; | ||||
| 		} | ||||
| 
 | ||||
| 		swapchainData->textures[i].resourceAccessType = RESOURCE_ACCESS_NONE; | ||||
|  | @ -4480,26 +4474,16 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | |||
| 	renderer->swapchainDatas[renderer->swapchainDataCount] = swapchainData; | ||||
| 	renderer->swapchainDataCount += 1; | ||||
| 
 | ||||
| 	return CREATE_SWAPCHAIN_SUCCESS; | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| static void VULKAN_INTERNAL_RecreateSwapchain( | ||||
| 	VulkanRenderer* renderer, | ||||
| 	void *windowHandle | ||||
| ) { | ||||
| 	CreateSwapchainResult createSwapchainResult; | ||||
| 
 | ||||
| 	VULKAN_Wait((Refresh_Renderer*)renderer); | ||||
| 
 | ||||
| 	VULKAN_Wait((Refresh_Renderer*) renderer); | ||||
| 	VULKAN_INTERNAL_DestroySwapchain(renderer, windowHandle); | ||||
| 	createSwapchainResult = VULKAN_INTERNAL_CreateSwapchain(renderer, windowHandle); | ||||
| 
 | ||||
| 	if (createSwapchainResult == CREATE_SWAPCHAIN_FAIL) | ||||
| 	{ | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	VULKAN_Wait((Refresh_Renderer*)renderer); | ||||
| 	VULKAN_INTERNAL_CreateSwapchain(renderer, windowHandle); | ||||
| } | ||||
| 
 | ||||
| /* Command Buffers */ | ||||
|  | @ -8233,13 +8217,24 @@ static void VULKAN_BeginRenderPass( | |||
| 	renderPassBeginInfo.pNext = NULL; | ||||
| 	renderPassBeginInfo.renderPass = renderPass; | ||||
| 	renderPassBeginInfo.framebuffer = framebuffer->framebuffer; | ||||
| 	renderPassBeginInfo.renderArea.extent.width = renderArea->w; | ||||
| 	renderPassBeginInfo.renderArea.extent.height = renderArea->h; | ||||
| 	renderPassBeginInfo.renderArea.offset.x = renderArea->x; | ||||
| 	renderPassBeginInfo.renderArea.offset.y = renderArea->y; | ||||
| 	renderPassBeginInfo.pClearValues = clearValues; | ||||
| 	renderPassBeginInfo.clearValueCount = clearCount; | ||||
| 
 | ||||
| 	if (renderArea != NULL) | ||||
| 	{ | ||||
| 		renderPassBeginInfo.renderArea.extent.width = renderArea->w; | ||||
| 		renderPassBeginInfo.renderArea.extent.height = renderArea->h; | ||||
| 		renderPassBeginInfo.renderArea.offset.x = renderArea->x; | ||||
| 		renderPassBeginInfo.renderArea.offset.y = renderArea->y; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		renderPassBeginInfo.renderArea.extent.width = framebufferWidth; | ||||
| 		renderPassBeginInfo.renderArea.extent.height = framebufferHeight; | ||||
| 		renderPassBeginInfo.renderArea.offset.x = 0; | ||||
| 		renderPassBeginInfo.renderArea.offset.y = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	renderer->vkCmdBeginRenderPass( | ||||
| 		vulkanCommandBuffer->commandBuffer, | ||||
| 		&renderPassBeginInfo, | ||||
|  | @ -8935,6 +8930,25 @@ static Refresh_CommandBuffer* VULKAN_AcquireCommandBuffer( | |||
| 	return (Refresh_CommandBuffer*) commandBuffer; | ||||
| } | ||||
| 
 | ||||
| static VulkanSwapchainData* VULKAN_INTERNAL_FetchSwapchainData( | ||||
| 	VulkanRenderer *renderer, | ||||
| 	void *windowHandle | ||||
| ) { | ||||
| 	VulkanSwapchainData *swapchainData = NULL; | ||||
| 
 | ||||
| 	swapchainData = (VulkanSwapchainData*) SDL_GetWindowData(windowHandle, WINDOW_SWAPCHAIN_DATA); | ||||
| 
 | ||||
| 	if (swapchainData == NULL) | ||||
| 	{ | ||||
| 		if (VULKAN_INTERNAL_CreateSwapchain(renderer, windowHandle)) | ||||
| 		{ | ||||
| 			swapchainData = (VulkanSwapchainData*) SDL_GetWindowData(windowHandle, WINDOW_SWAPCHAIN_DATA); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return swapchainData; | ||||
| } | ||||
| 
 | ||||
| static Refresh_Texture* VULKAN_AcquireSwapchainTexture( | ||||
| 	Refresh_Renderer *driverData, | ||||
| 	Refresh_CommandBuffer *commandBuffer, | ||||
|  | @ -8943,35 +8957,39 @@ static Refresh_Texture* VULKAN_AcquireSwapchainTexture( | |||
| 	VulkanRenderer *renderer = (VulkanRenderer*) driverData; | ||||
| 	VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; | ||||
| 	uint32_t swapchainImageIndex; | ||||
| 	VulkanSwapchainData *swapchainData = NULL; | ||||
| 	CreateSwapchainResult createSwapchainResult = 0; | ||||
| 	uint8_t validSwapchainExists = 1; | ||||
| 	VulkanSwapchainData *swapchainData; | ||||
| 	VkResult acquireResult = VK_SUCCESS; | ||||
| 	VulkanTexture *swapchainTexture = NULL; | ||||
| 	VulkanPresentData *presentData; | ||||
| 
 | ||||
| 	swapchainData = (VulkanSwapchainData*) SDL_GetWindowData(windowHandle, WINDOW_SWAPCHAIN_DATA); | ||||
| 	swapchainData = VULKAN_INTERNAL_FetchSwapchainData(renderer, windowHandle); | ||||
| 
 | ||||
| 	if (swapchainData == NULL) | ||||
| 	{ | ||||
| 		createSwapchainResult = VULKAN_INTERNAL_CreateSwapchain(renderer, windowHandle); | ||||
| 
 | ||||
| 		if (createSwapchainResult == CREATE_SWAPCHAIN_FAIL) | ||||
| 		{ | ||||
| 			validSwapchainExists = 0; | ||||
| 		} | ||||
| 		else if (createSwapchainResult == CREATE_SWAPCHAIN_SURFACE_ZERO) | ||||
| 		{ | ||||
| 			validSwapchainExists = 0; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			swapchainData = (VulkanSwapchainData*) SDL_GetWindowData(windowHandle, WINDOW_SWAPCHAIN_DATA); | ||||
| 		} | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	if (validSwapchainExists) | ||||
| 	acquireResult = renderer->vkAcquireNextImageKHR( | ||||
| 		renderer->logicalDevice, | ||||
| 		swapchainData->swapchain, | ||||
| 		UINT64_MAX, | ||||
| 		swapchainData->imageAvailableSemaphore, | ||||
| 		VK_NULL_HANDLE, | ||||
| 		&swapchainImageIndex | ||||
| 	); | ||||
| 
 | ||||
| 	/* Swapchain is suboptimal, let's try to recreate */ | ||||
| 	if (acquireResult == VK_SUBOPTIMAL_KHR) | ||||
| 	{ | ||||
| 		VULKAN_INTERNAL_RecreateSwapchain(renderer, windowHandle); | ||||
| 
 | ||||
| 		swapchainData = VULKAN_INTERNAL_FetchSwapchainData(renderer, windowHandle); | ||||
| 
 | ||||
| 		if (swapchainData == NULL) | ||||
| 		{ | ||||
| 			return NULL; | ||||
| 		} | ||||
| 
 | ||||
| 		acquireResult = renderer->vkAcquireNextImageKHR( | ||||
| 			renderer->logicalDevice, | ||||
| 			swapchainData->swapchain, | ||||
|  | @ -8981,84 +8999,71 @@ static Refresh_Texture* VULKAN_AcquireSwapchainTexture( | |||
| 			&swapchainImageIndex | ||||
| 		); | ||||
| 
 | ||||
| 		/* Swapchain is suboptimal, let's try to recreate */ | ||||
| 		if (acquireResult == VK_SUBOPTIMAL_KHR) | ||||
| 		if (acquireResult != VK_SUCCESS) | ||||
| 		{ | ||||
| 			VULKAN_INTERNAL_RecreateSwapchain(renderer, windowHandle); | ||||
| 
 | ||||
| 			acquireResult = renderer->vkAcquireNextImageKHR( | ||||
| 				renderer->logicalDevice, | ||||
| 				swapchainData->swapchain, | ||||
| 				UINT64_MAX, | ||||
| 				swapchainData->imageAvailableSemaphore, | ||||
| 				VK_NULL_HANDLE, | ||||
| 				&swapchainImageIndex | ||||
| 			); | ||||
| 		} | ||||
| 
 | ||||
| 		if (acquireResult == VK_SUCCESS) | ||||
| 		{ | ||||
| 			swapchainTexture = &swapchainData->textures[swapchainImageIndex]; | ||||
| 
 | ||||
| 			VULKAN_INTERNAL_ImageMemoryBarrier( | ||||
| 				renderer, | ||||
| 				vulkanCommandBuffer->commandBuffer, | ||||
| 				RESOURCE_ACCESS_COLOR_ATTACHMENT_WRITE, | ||||
| 				VK_IMAGE_ASPECT_COLOR_BIT, | ||||
| 				0, | ||||
| 				1, | ||||
| 				0, | ||||
| 				1, | ||||
| 				0, | ||||
| 				swapchainTexture->image, | ||||
| 				&swapchainTexture->resourceAccessType | ||||
| 			); | ||||
| 
 | ||||
| 			/* Set up present struct */ | ||||
| 
 | ||||
| 			if (vulkanCommandBuffer->presentDataCount == vulkanCommandBuffer->presentDataCapacity) | ||||
| 			{ | ||||
| 				vulkanCommandBuffer->presentDataCapacity += 1; | ||||
| 				vulkanCommandBuffer->presentDatas = SDL_realloc( | ||||
| 					vulkanCommandBuffer->presentDatas, | ||||
| 					vulkanCommandBuffer->presentDataCapacity * sizeof(VkPresentInfoKHR) | ||||
| 				); | ||||
| 			} | ||||
| 
 | ||||
| 			presentData = &vulkanCommandBuffer->presentDatas[vulkanCommandBuffer->presentDataCount]; | ||||
| 			vulkanCommandBuffer->presentDataCount += 1; | ||||
| 
 | ||||
| 			presentData->swapchainData = swapchainData; | ||||
| 			presentData->swapchainImageIndex = swapchainImageIndex; | ||||
| 
 | ||||
| 			/* Set up present semaphores */ | ||||
| 
 | ||||
| 			if (vulkanCommandBuffer->waitSemaphoreCount == vulkanCommandBuffer->waitSemaphoreCapacity) | ||||
| 			{ | ||||
| 				vulkanCommandBuffer->waitSemaphoreCapacity += 1; | ||||
| 				vulkanCommandBuffer->waitSemaphores = SDL_realloc( | ||||
| 					vulkanCommandBuffer->waitSemaphores, | ||||
| 					vulkanCommandBuffer->waitSemaphoreCapacity * sizeof(VkSemaphore) | ||||
| 				); | ||||
| 			} | ||||
| 
 | ||||
| 			vulkanCommandBuffer->waitSemaphores[vulkanCommandBuffer->waitSemaphoreCount] = swapchainData->imageAvailableSemaphore; | ||||
| 			vulkanCommandBuffer->waitSemaphoreCount += 1; | ||||
| 
 | ||||
| 			if (vulkanCommandBuffer->signalSemaphoreCount == vulkanCommandBuffer->signalSemaphoreCapacity) | ||||
| 			{ | ||||
| 				vulkanCommandBuffer->signalSemaphoreCapacity += 1; | ||||
| 				vulkanCommandBuffer->signalSemaphores = SDL_realloc( | ||||
| 					vulkanCommandBuffer->signalSemaphores, | ||||
| 					vulkanCommandBuffer->signalSemaphoreCapacity * sizeof(VkSemaphore) | ||||
| 				); | ||||
| 			} | ||||
| 
 | ||||
| 			vulkanCommandBuffer->signalSemaphores[vulkanCommandBuffer->signalSemaphoreCount] = swapchainData->renderFinishedSemaphore; | ||||
| 			vulkanCommandBuffer->signalSemaphoreCount += 1; | ||||
| 			return NULL; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	swapchainTexture = &swapchainData->textures[swapchainImageIndex]; | ||||
| 
 | ||||
| 	VULKAN_INTERNAL_ImageMemoryBarrier( | ||||
| 		renderer, | ||||
| 		vulkanCommandBuffer->commandBuffer, | ||||
| 		RESOURCE_ACCESS_COLOR_ATTACHMENT_WRITE, | ||||
| 		VK_IMAGE_ASPECT_COLOR_BIT, | ||||
| 		0, | ||||
| 		1, | ||||
| 		0, | ||||
| 		1, | ||||
| 		0, | ||||
| 		swapchainTexture->image, | ||||
| 		&swapchainTexture->resourceAccessType | ||||
| 	); | ||||
| 
 | ||||
| 	/* Set up present struct */ | ||||
| 
 | ||||
| 	if (vulkanCommandBuffer->presentDataCount == vulkanCommandBuffer->presentDataCapacity) | ||||
| 	{ | ||||
| 		vulkanCommandBuffer->presentDataCapacity += 1; | ||||
| 		vulkanCommandBuffer->presentDatas = SDL_realloc( | ||||
| 			vulkanCommandBuffer->presentDatas, | ||||
| 			vulkanCommandBuffer->presentDataCapacity * sizeof(VkPresentInfoKHR) | ||||
| 		); | ||||
| 	} | ||||
| 
 | ||||
| 	presentData = &vulkanCommandBuffer->presentDatas[vulkanCommandBuffer->presentDataCount]; | ||||
| 	vulkanCommandBuffer->presentDataCount += 1; | ||||
| 
 | ||||
| 	presentData->swapchainData = swapchainData; | ||||
| 	presentData->swapchainImageIndex = swapchainImageIndex; | ||||
| 
 | ||||
| 	/* Set up present semaphores */ | ||||
| 
 | ||||
| 	if (vulkanCommandBuffer->waitSemaphoreCount == vulkanCommandBuffer->waitSemaphoreCapacity) | ||||
| 	{ | ||||
| 		vulkanCommandBuffer->waitSemaphoreCapacity += 1; | ||||
| 		vulkanCommandBuffer->waitSemaphores = SDL_realloc( | ||||
| 			vulkanCommandBuffer->waitSemaphores, | ||||
| 			vulkanCommandBuffer->waitSemaphoreCapacity * sizeof(VkSemaphore) | ||||
| 		); | ||||
| 	} | ||||
| 
 | ||||
| 	vulkanCommandBuffer->waitSemaphores[vulkanCommandBuffer->waitSemaphoreCount] = swapchainData->imageAvailableSemaphore; | ||||
| 	vulkanCommandBuffer->waitSemaphoreCount += 1; | ||||
| 
 | ||||
| 	if (vulkanCommandBuffer->signalSemaphoreCount == vulkanCommandBuffer->signalSemaphoreCapacity) | ||||
| 	{ | ||||
| 		vulkanCommandBuffer->signalSemaphoreCapacity += 1; | ||||
| 		vulkanCommandBuffer->signalSemaphores = SDL_realloc( | ||||
| 			vulkanCommandBuffer->signalSemaphores, | ||||
| 			vulkanCommandBuffer->signalSemaphoreCapacity * sizeof(VkSemaphore) | ||||
| 		); | ||||
| 	} | ||||
| 
 | ||||
| 	vulkanCommandBuffer->signalSemaphores[vulkanCommandBuffer->signalSemaphoreCount] = swapchainData->renderFinishedSemaphore; | ||||
| 	vulkanCommandBuffer->signalSemaphoreCount += 1; | ||||
| 
 | ||||
| 	return (Refresh_Texture*) swapchainTexture; | ||||
| } | ||||
| 
 | ||||
|  | @ -10337,7 +10342,7 @@ static Refresh_Device* VULKAN_CreateDevice( | |||
| 		renderer->swapchainDataCapacity * sizeof(VulkanSwapchainData*) | ||||
| 	); | ||||
| 
 | ||||
| 	if (VULKAN_INTERNAL_CreateSwapchain(renderer, presentationParameters->deviceWindowHandle) != CREATE_SWAPCHAIN_SUCCESS) | ||||
| 	if (!VULKAN_INTERNAL_CreateSwapchain(renderer, presentationParameters->deviceWindowHandle)) | ||||
| 	{ | ||||
| 		Refresh_LogError("Failed to create swapchain"); | ||||
| 		return NULL; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue