Swapchain resize fixes #18
			
				
			
		
		
		
	|  | @ -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[] = | ||||
|  | @ -751,6 +744,12 @@ typedef struct VulkanRenderTarget | |||
| 	VkSampleCountFlags multisampleCount; | ||||
| } VulkanRenderTarget; | ||||
| 
 | ||||
| typedef struct VulkanFramebuffer | ||||
| { | ||||
| 	VkFramebuffer framebuffer; | ||||
| 	SDL_atomic_t referenceCount; | ||||
| } VulkanFramebuffer; | ||||
| 
 | ||||
| typedef struct VulkanSwapchainData | ||||
| { | ||||
| 	/* Window surface */ | ||||
|  | @ -769,9 +768,6 @@ typedef struct VulkanSwapchainData | |||
| 	VulkanTexture *textures; | ||||
| 	uint32_t imageCount; | ||||
| 
 | ||||
| 	/* Recreate flag */ | ||||
| 	uint8_t needsRecreate; | ||||
| 
 | ||||
| 	/* Synchronization primitives */ | ||||
| 	VkSemaphore imageAvailableSemaphore; | ||||
| 	VkSemaphore renderFinishedSemaphore; | ||||
|  | @ -1051,7 +1047,7 @@ typedef struct FramebufferHash | |||
| typedef struct FramebufferHashMap | ||||
| { | ||||
| 	FramebufferHash key; | ||||
| 	VkFramebuffer value; | ||||
| 	VulkanFramebuffer *value; | ||||
| } FramebufferHashMap; | ||||
| 
 | ||||
| typedef struct FramebufferHashArray | ||||
|  | @ -1103,7 +1099,7 @@ static inline uint8_t FramebufferHash_Compare( | |||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| static inline VkFramebuffer FramebufferHashArray_Fetch( | ||||
| static inline VulkanFramebuffer* FramebufferHashArray_Fetch( | ||||
| 	FramebufferHashArray *arr, | ||||
| 	FramebufferHash *key | ||||
| ) { | ||||
|  | @ -1124,7 +1120,7 @@ static inline VkFramebuffer FramebufferHashArray_Fetch( | |||
| static inline void FramebufferHashArray_Insert( | ||||
| 	FramebufferHashArray *arr, | ||||
| 	FramebufferHash key, | ||||
| 	VkFramebuffer value | ||||
| 	VulkanFramebuffer *value | ||||
| ) { | ||||
| 	FramebufferHashMap map; | ||||
| 	map.key = key; | ||||
|  | @ -1520,6 +1516,10 @@ typedef struct VulkanCommandBuffer | |||
| 	uint32_t usedComputePipelineCount; | ||||
| 	uint32_t usedComputePipelineCapacity; | ||||
| 
 | ||||
| 	VulkanFramebuffer **usedFramebuffers; | ||||
| 	uint32_t usedFramebufferCount; | ||||
| 	uint32_t usedFramebufferCapacity; | ||||
| 
 | ||||
| 	/* Shader modules have references tracked by pipelines */ | ||||
| 
 | ||||
| 	VkFence inFlightFence; | ||||
|  | @ -1697,6 +1697,10 @@ typedef struct VulkanRenderer | |||
| 	uint32_t shaderModulesToDestroyCount; | ||||
| 	uint32_t shaderModulesToDestroyCapacity; | ||||
| 
 | ||||
| 	VulkanFramebuffer **framebuffersToDestroy; | ||||
| 	uint32_t framebuffersToDestroyCount; | ||||
| 	uint32_t framebuffersToDestroyCapacity; | ||||
| 
 | ||||
| 	SDL_mutex *allocatorLock; | ||||
| 	SDL_mutex *disposeLock; | ||||
| 	SDL_mutex *submitLock; | ||||
|  | @ -2719,10 +2723,57 @@ static void VULKAN_INTERNAL_TrackComputePipeline( | |||
| 	) | ||||
| } | ||||
| 
 | ||||
| static void VULKAN_INTERNAL_TrackFramebuffer( | ||||
| 	VulkanRenderer *renderer, | ||||
| 	VulkanCommandBuffer *commandBuffer, | ||||
| 	VulkanFramebuffer *framebuffer | ||||
| ) { | ||||
| 	TRACK_RESOURCE( | ||||
| 		framebuffer, | ||||
| 		VulkanFramebuffer*, | ||||
| 		usedFramebuffers, | ||||
| 		usedFramebufferCount, | ||||
| 		usedFramebufferCapacity | ||||
| 	); | ||||
| } | ||||
| 
 | ||||
| #undef TRACK_RESOURCE | ||||
| 
 | ||||
| /* Resource Disposal */ | ||||
| 
 | ||||
| static void VULKAN_INTERNAL_QueueDestroyFramebuffer( | ||||
| 	VulkanRenderer *renderer, | ||||
| 	VulkanFramebuffer *framebuffer | ||||
| ) { | ||||
| 	SDL_LockMutex(renderer->disposeLock); | ||||
| 
 | ||||
| 	EXPAND_ARRAY_IF_NEEDED( | ||||
| 		renderer->framebuffersToDestroy, | ||||
| 		VulkanFramebuffer*, | ||||
| 		renderer->framebuffersToDestroyCount + 1, | ||||
| 		renderer->framebuffersToDestroyCapacity, | ||||
| 		renderer->framebuffersToDestroyCapacity * 2 | ||||
| 	) | ||||
| 
 | ||||
| 	renderer->framebuffersToDestroy[renderer->framebuffersToDestroyCount] = framebuffer; | ||||
| 	renderer->framebuffersToDestroyCount += 1; | ||||
| 
 | ||||
| 	SDL_UnlockMutex(renderer->disposeLock); | ||||
| } | ||||
| 
 | ||||
| static void VULKAN_INTERNAL_DestroyFramebuffer( | ||||
| 	VulkanRenderer *renderer, | ||||
| 	VulkanFramebuffer *framebuffer | ||||
| ) { | ||||
| 	renderer->vkDestroyFramebuffer( | ||||
| 		renderer->logicalDevice, | ||||
| 		framebuffer->framebuffer, | ||||
| 		NULL | ||||
| 	); | ||||
| 
 | ||||
| 	SDL_free(framebuffer); | ||||
| } | ||||
| 
 | ||||
| static void VULKAN_INTERNAL_RemoveFramebuffersContainingView( | ||||
| 	VulkanRenderer *renderer, | ||||
| 	VkImageView view | ||||
|  | @ -2740,10 +2791,9 @@ static void VULKAN_INTERNAL_RemoveFramebuffersContainingView( | |||
| 		{ | ||||
| 			if (hash->colorAttachmentViews[i] == view) | ||||
| 			{ | ||||
| 				renderer->vkDestroyFramebuffer( | ||||
| 					renderer->logicalDevice, | ||||
| 					renderer->framebufferHashArray.elements[i].value, | ||||
| 					NULL | ||||
| 				VULKAN_INTERNAL_QueueDestroyFramebuffer( | ||||
| 					renderer, | ||||
| 					renderer->framebufferHashArray.elements[i].value | ||||
| 				); | ||||
| 
 | ||||
| 				FramebufferHashArray_Remove( | ||||
|  | @ -2945,6 +2995,7 @@ static void VULKAN_INTERNAL_DestroyCommandPool( | |||
| 		SDL_free(commandBuffer->usedSamplers); | ||||
| 		SDL_free(commandBuffer->usedGraphicsPipelines); | ||||
| 		SDL_free(commandBuffer->usedComputePipelines); | ||||
| 		SDL_free(commandBuffer->usedFramebuffers); | ||||
| 
 | ||||
| 		SDL_free(commandBuffer); | ||||
| 	} | ||||
|  | @ -4037,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 | ||||
| ) { | ||||
|  | @ -4066,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( | ||||
|  | @ -4091,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; | ||||
|  | @ -4133,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; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -4158,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( | ||||
|  | @ -4189,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) | ||||
|  | @ -4222,7 +4274,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | |||
| 			} | ||||
| 			SDL_free(swapchainData); | ||||
| 			Refresh_LogError("No fallback swapchain size available!"); | ||||
| 			return CREATE_SWAPCHAIN_FAIL; | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -4295,7 +4347,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | |||
| 		); | ||||
| 		SDL_free(swapchainData); | ||||
| 		LogVulkanResultAsError("vkCreateSwapchainKHR", vulkanResult); | ||||
| 		return CREATE_SWAPCHAIN_FAIL; | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	renderer->vkGetSwapchainImagesKHR( | ||||
|  | @ -4318,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); | ||||
|  | @ -4366,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; | ||||
|  | @ -4408,8 +4460,6 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( | |||
| 		&swapchainData->renderFinishedSemaphore | ||||
| 	); | ||||
| 
 | ||||
| 	swapchainData->needsRecreate = 0; | ||||
| 
 | ||||
| 	SDL_SetWindowData(windowHandle, WINDOW_SWAPCHAIN_DATA, swapchainData); | ||||
| 
 | ||||
| 	if (renderer->swapchainDataCount >= renderer->swapchainDataCapacity) | ||||
|  | @ -4424,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_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 */ | ||||
|  | @ -4516,6 +4556,15 @@ static void VULKAN_DestroyDevice( | |||
| 
 | ||||
| 	VULKAN_Wait(device->driverData); | ||||
| 
 | ||||
| 	for (i = renderer->swapchainDataCount - 1; i >= 0; i -= 1) | ||||
| 	{ | ||||
| 		VULKAN_INTERNAL_DestroySwapchain(renderer, renderer->swapchainDatas[i]->windowHandle); | ||||
| 	} | ||||
| 
 | ||||
| 	SDL_free(renderer->swapchainDatas); | ||||
| 
 | ||||
| 	VULKAN_Wait(device->driverData); | ||||
| 
 | ||||
| 	SDL_free(renderer->submittedCommandBuffers); | ||||
| 
 | ||||
| 	VULKAN_INTERNAL_DestroyBuffer(renderer, renderer->dummyVertexUniformBuffer->vulkanBuffer); | ||||
|  | @ -4675,19 +4724,11 @@ static void VULKAN_DestroyDevice( | |||
| 	VULKAN_INTERNAL_DestroyUniformBufferPool(renderer, renderer->fragmentUniformBufferPool); | ||||
| 	VULKAN_INTERNAL_DestroyUniformBufferPool(renderer, renderer->computeUniformBufferPool); | ||||
| 
 | ||||
| 	for (i = renderer->swapchainDataCount - 1; i >= 0; i -= 1) | ||||
| 	{ | ||||
| 		VULKAN_INTERNAL_DestroySwapchain(renderer, renderer->swapchainDatas[i]->windowHandle); | ||||
| 	} | ||||
| 
 | ||||
| 	SDL_free(renderer->swapchainDatas); | ||||
| 
 | ||||
| 	for (i = 0; i < renderer->framebufferHashArray.count; i += 1) | ||||
| 	{ | ||||
| 		renderer->vkDestroyFramebuffer( | ||||
| 			renderer->logicalDevice, | ||||
| 			renderer->framebufferHashArray.elements[i].value, | ||||
| 			NULL | ||||
| 		VULKAN_INTERNAL_DestroyFramebuffer( | ||||
| 			renderer, | ||||
| 			renderer->framebufferHashArray.elements[i].value | ||||
| 		); | ||||
| 	} | ||||
| 
 | ||||
|  | @ -7779,7 +7820,7 @@ static VkRenderPass VULKAN_INTERNAL_FetchRenderPass( | |||
| 	return renderPass; | ||||
| } | ||||
| 
 | ||||
| static VkFramebuffer VULKAN_INTERNAL_FetchFramebuffer( | ||||
| static VulkanFramebuffer* VULKAN_INTERNAL_FetchFramebuffer( | ||||
| 	VulkanRenderer *renderer, | ||||
| 	VkRenderPass renderPass, | ||||
| 	Refresh_ColorAttachmentInfo *colorAttachmentInfos, | ||||
|  | @ -7788,7 +7829,7 @@ static VkFramebuffer VULKAN_INTERNAL_FetchFramebuffer( | |||
| 	uint32_t width, | ||||
| 	uint32_t height | ||||
| ) { | ||||
| 	VkFramebuffer framebuffer; | ||||
| 	VulkanFramebuffer *vulkanFramebuffer; | ||||
| 	VkFramebufferCreateInfo framebufferInfo; | ||||
| 	VkResult result; | ||||
| 	VkImageView imageViewAttachments[2 * MAX_COLOR_TARGET_BINDINGS + 1]; | ||||
|  | @ -7850,17 +7891,21 @@ static VkFramebuffer VULKAN_INTERNAL_FetchFramebuffer( | |||
| 	hash.width = width; | ||||
| 	hash.height = height; | ||||
| 
 | ||||
| 	framebuffer = FramebufferHashArray_Fetch( | ||||
| 	vulkanFramebuffer = FramebufferHashArray_Fetch( | ||||
| 		&renderer->framebufferHashArray, | ||||
| 		&hash | ||||
| 	); | ||||
| 
 | ||||
| 	if (framebuffer != VK_NULL_HANDLE) | ||||
| 	if (vulkanFramebuffer != NULL) | ||||
| 	{ | ||||
| 		SDL_UnlockMutex(renderer->framebufferFetchLock); | ||||
| 		return framebuffer; | ||||
| 		return vulkanFramebuffer; | ||||
| 	} | ||||
| 
 | ||||
| 	vulkanFramebuffer = SDL_malloc(sizeof(VulkanFramebuffer)); | ||||
| 
 | ||||
| 	SDL_AtomicSet(&vulkanFramebuffer->referenceCount, 0); | ||||
| 
 | ||||
| 	/* Create a new framebuffer */ | ||||
| 
 | ||||
| 	for (i = 0; i < colorAttachmentCount; i += 1) | ||||
|  | @ -7918,7 +7963,7 @@ static VkFramebuffer VULKAN_INTERNAL_FetchFramebuffer( | |||
| 		renderer->logicalDevice, | ||||
| 		&framebufferInfo, | ||||
| 		NULL, | ||||
| 		&framebuffer | ||||
| 		&vulkanFramebuffer->framebuffer | ||||
| 	); | ||||
| 
 | ||||
| 	if (result == VK_SUCCESS) | ||||
|  | @ -7926,17 +7971,18 @@ static VkFramebuffer VULKAN_INTERNAL_FetchFramebuffer( | |||
| 		FramebufferHashArray_Insert( | ||||
| 			&renderer->framebufferHashArray, | ||||
| 			hash, | ||||
| 			framebuffer | ||||
| 			vulkanFramebuffer | ||||
| 		); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		LogVulkanResultAsError("vkCreateFramebuffer", result); | ||||
| 		framebuffer = VK_NULL_HANDLE; | ||||
| 		SDL_free(vulkanFramebuffer); | ||||
| 		vulkanFramebuffer = NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	SDL_UnlockMutex(renderer->framebufferFetchLock); | ||||
| 	return framebuffer; | ||||
| 	return vulkanFramebuffer; | ||||
| } | ||||
| 
 | ||||
| static void VULKAN_INTERNAL_SetCurrentViewport( | ||||
|  | @ -8028,7 +8074,7 @@ static void VULKAN_BeginRenderPass( | |||
| 	VulkanRenderer* renderer = (VulkanRenderer*) driverData; | ||||
| 	VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; | ||||
| 	VkRenderPass renderPass; | ||||
| 	VkFramebuffer framebuffer; | ||||
| 	VulkanFramebuffer *framebuffer; | ||||
| 
 | ||||
| 	VulkanTexture *texture; | ||||
| 	VkClearValue *clearValues; | ||||
|  | @ -8095,6 +8141,8 @@ static void VULKAN_BeginRenderPass( | |||
| 		framebufferHeight | ||||
| 	); | ||||
| 
 | ||||
| 	VULKAN_INTERNAL_TrackFramebuffer(renderer, vulkanCommandBuffer, framebuffer); | ||||
| 
 | ||||
| 	/* Layout transitions */ | ||||
| 
 | ||||
| 	for (i = 0; i < colorAttachmentCount; i += 1) | ||||
|  | @ -8169,14 +8217,25 @@ static void VULKAN_BeginRenderPass( | |||
| 	VkRenderPassBeginInfo renderPassBeginInfo; | ||||
| 	renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; | ||||
| 	renderPassBeginInfo.pNext = NULL; | ||||
| 	renderPassBeginInfo.renderPass = (VkRenderPass) renderPass; | ||||
| 	renderPassBeginInfo.framebuffer = framebuffer; | ||||
| 	renderPassBeginInfo.renderPass = renderPass; | ||||
| 	renderPassBeginInfo.framebuffer = framebuffer->framebuffer; | ||||
| 	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; | ||||
| 	renderPassBeginInfo.pClearValues = clearValues; | ||||
| 	renderPassBeginInfo.clearValueCount = clearCount; | ||||
| 	} | ||||
| 	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, | ||||
|  | @ -8715,6 +8774,12 @@ static void VULKAN_INTERNAL_AllocateCommandBuffers( | |||
| 			commandBuffer->usedComputePipelineCapacity * sizeof(VulkanComputePipeline*) | ||||
| 		); | ||||
| 
 | ||||
| 		commandBuffer->usedFramebufferCapacity = 4; | ||||
| 		commandBuffer->usedFramebufferCount = 0; | ||||
| 		commandBuffer->usedFramebuffers = SDL_malloc( | ||||
| 			commandBuffer->usedFramebufferCapacity * sizeof(VulkanFramebuffer*) | ||||
| 		); | ||||
| 
 | ||||
| 		vulkanCommandPool->inactiveCommandBuffers[ | ||||
| 			vulkanCommandPool->inactiveCommandBufferCount | ||||
| 		] = commandBuffer; | ||||
|  | @ -8867,6 +8932,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, | ||||
|  | @ -8875,35 +8959,18 @@ 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, | ||||
|  | @ -8913,8 +8980,33 @@ static Refresh_Texture* VULKAN_AcquireSwapchainTexture( | |||
| 		&swapchainImageIndex | ||||
| 	); | ||||
| 
 | ||||
| 		if (acquireResult == VK_SUCCESS || acquireResult == VK_SUBOPTIMAL_KHR) | ||||
| 	/* 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, | ||||
| 			UINT64_MAX, | ||||
| 			swapchainData->imageAvailableSemaphore, | ||||
| 			VK_NULL_HANDLE, | ||||
| 			&swapchainImageIndex | ||||
| 		); | ||||
| 
 | ||||
| 		if (acquireResult != VK_SUCCESS) | ||||
| 		{ | ||||
| 			return NULL; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	swapchainTexture = &swapchainData->textures[swapchainImageIndex]; | ||||
| 
 | ||||
| 	VULKAN_INTERNAL_ImageMemoryBarrier( | ||||
|  | @ -8974,13 +9066,6 @@ static Refresh_Texture* VULKAN_AcquireSwapchainTexture( | |||
| 	vulkanCommandBuffer->signalSemaphores[vulkanCommandBuffer->signalSemaphoreCount] = swapchainData->renderFinishedSemaphore; | ||||
| 	vulkanCommandBuffer->signalSemaphoreCount += 1; | ||||
| 
 | ||||
| 			if (acquireResult == VK_SUBOPTIMAL_KHR) | ||||
| 			{ | ||||
| 				swapchainData->needsRecreate = 1; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return (Refresh_Texture*) swapchainTexture; | ||||
| } | ||||
| 
 | ||||
|  | @ -9104,6 +9189,20 @@ static void VULKAN_INTERNAL_PerformPendingDestroys( | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	for (i = renderer->framebuffersToDestroyCount - 1; i >= 0; i -= 1) | ||||
| 	{ | ||||
| 		if (SDL_AtomicGet(&renderer->framebuffersToDestroy[i]->referenceCount) == 0) | ||||
| 		{ | ||||
| 			VULKAN_INTERNAL_DestroyFramebuffer( | ||||
| 				renderer, | ||||
| 				renderer->framebuffersToDestroy[i] | ||||
| 			); | ||||
| 
 | ||||
| 			renderer->framebuffersToDestroy[i] = renderer->framebuffersToDestroy[renderer->framebuffersToDestroyCount - 1]; | ||||
| 			renderer->framebuffersToDestroyCount -= 1; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	SDL_UnlockMutex(renderer->disposeLock); | ||||
| } | ||||
| 
 | ||||
|  | @ -9217,6 +9316,12 @@ static void VULKAN_INTERNAL_CleanCommandBuffer( | |||
| 	} | ||||
| 	commandBuffer->usedComputePipelineCount = 0; | ||||
| 
 | ||||
| 	for (i = 0; i < commandBuffer->usedFramebufferCount; i += 1) | ||||
| 	{ | ||||
| 		SDL_AtomicDecRef(&commandBuffer->usedFramebuffers[i]->referenceCount); | ||||
| 	} | ||||
| 	commandBuffer->usedFramebufferCount = 0; | ||||
| 
 | ||||
| 	/* Return command buffer to pool */ | ||||
| 
 | ||||
| 	SDL_LockMutex(renderer->acquireCommandBufferLock); | ||||
|  | @ -9378,7 +9483,7 @@ static void VULKAN_Submit( | |||
| 				&presentInfo | ||||
| 			); | ||||
| 
 | ||||
| 			if (presentResult != VK_SUCCESS || presentData->swapchainData->needsRecreate) | ||||
| 			if (presentResult != VK_SUCCESS) | ||||
| 			{ | ||||
| 				VULKAN_INTERNAL_RecreateSwapchain(renderer, presentData->swapchainData->windowHandle); | ||||
| 			} | ||||
|  | @ -10239,7 +10344,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; | ||||
|  | @ -10624,6 +10729,13 @@ static Refresh_Device* VULKAN_CreateDevice( | |||
| 		renderer->shaderModulesToDestroyCapacity | ||||
| 	); | ||||
| 
 | ||||
| 	renderer->framebuffersToDestroyCapacity = 16; | ||||
| 	renderer->framebuffersToDestroyCount = 0; | ||||
| 	renderer->framebuffersToDestroy = SDL_malloc( | ||||
| 		sizeof(VulkanFramebuffer*) * | ||||
| 		renderer->framebuffersToDestroyCapacity | ||||
| 	); | ||||
| 
 | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue