116 lines
3.6 KiB
C++
116 lines
3.6 KiB
C++
#include "VulkanManager.h"
|
|
|
|
#define CHECK_RESULT(res) if (res != VK_SUCCESS) { return res; }
|
|
|
|
namespace PB::Renderer
|
|
{
|
|
bool VulkanManager::RenderPass(GLFWwindow* window)
|
|
{
|
|
switch (const VkResult result = RenderPassInternal())
|
|
{
|
|
case VK_ERROR_OUT_OF_DATE_KHR:
|
|
case VK_SUBOPTIMAL_KHR:
|
|
RecreateSwapChain(window);
|
|
return true;
|
|
|
|
default:
|
|
return result == VK_SUCCESS;
|
|
}
|
|
}
|
|
|
|
void VulkanManager::RecreateSwapChain(GLFWwindow* window)
|
|
{
|
|
int width, height;
|
|
glfwGetFramebufferSize(window, &width, &height);
|
|
|
|
/* Pauses if minimised */
|
|
while (width == 0 || height == 0)
|
|
{
|
|
glfwGetFramebufferSize(window, &width, &height);
|
|
glfwWaitEvents();
|
|
}
|
|
|
|
/* Waits until device is idle before recreating swap chain */
|
|
vkDeviceWaitIdle(s_Device);
|
|
CleanupSwapChain();
|
|
|
|
CreateSwapChain(window);
|
|
CreateImageViews();
|
|
CreateRenderPass();
|
|
CreateFramebuffer();
|
|
CreateGraphicsPipeline();
|
|
CreateCommandBuffers();
|
|
CreateSemaphores();
|
|
}
|
|
|
|
void VulkanManager::CleanupSwapChain()
|
|
{
|
|
for (const VkFramebuffer framebuffer : s_Framebuffers)
|
|
{
|
|
vkDestroyFramebuffer(s_Device, framebuffer, nullptr);
|
|
}
|
|
s_Framebuffers.clear();
|
|
|
|
vkFreeCommandBuffers(s_Device, s_CommandPool, static_cast<uint32_t>(s_CommandBuffers.size()), s_CommandBuffers.data());
|
|
vkDestroyPipeline(s_Device, s_RenderPipeline, nullptr);
|
|
vkDestroyPipelineLayout(s_Device, s_PipelineLayout, nullptr);
|
|
vkDestroyRenderPass(s_Device, s_RenderPass, nullptr);
|
|
|
|
for (const VkImageView view : s_SwapChainImageViews)
|
|
{
|
|
vkDestroyImageView(s_Device, view, nullptr);
|
|
}
|
|
|
|
vkDestroySwapchainKHR(s_Device, s_SwapChain, nullptr);
|
|
}
|
|
|
|
VkResult VulkanManager::RenderPassInternal()
|
|
{
|
|
uint32_t imageIndex;
|
|
VkResult result = vkAcquireNextImageKHR(
|
|
s_Device,
|
|
s_SwapChain,
|
|
UINT64_MAX,
|
|
s_ImageAvailableSemaphore,
|
|
VK_NULL_HANDLE,
|
|
&imageIndex
|
|
);
|
|
CHECK_RESULT(result);
|
|
|
|
VkSubmitInfo submitInfo{};
|
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
|
|
|
const VkSemaphore waitSemaphores[] = { s_ImageAvailableSemaphore };
|
|
constexpr VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
|
submitInfo.waitSemaphoreCount = 1;
|
|
submitInfo.pWaitSemaphores = waitSemaphores;
|
|
submitInfo.pWaitDstStageMask = waitStages;
|
|
|
|
submitInfo.commandBufferCount = 1;
|
|
submitInfo.pCommandBuffers = &s_CommandBuffers[imageIndex];
|
|
|
|
const VkSemaphore signalSemaphores[] = { s_RenderFinishedSemaphore };
|
|
submitInfo.signalSemaphoreCount = 1;
|
|
submitInfo.pSignalSemaphores = signalSemaphores;
|
|
|
|
result = vkQueueSubmit(s_GraphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
|
|
CHECK_RESULT(result);
|
|
|
|
VkPresentInfoKHR presentInfo{};
|
|
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
|
presentInfo.waitSemaphoreCount = 1;
|
|
presentInfo.pWaitSemaphores = signalSemaphores;
|
|
|
|
const VkSwapchainKHR swapChains[] = { s_SwapChain };
|
|
presentInfo.swapchainCount = 1;
|
|
presentInfo.pSwapchains = swapChains;
|
|
presentInfo.pImageIndices = &imageIndex;
|
|
|
|
result = vkQueuePresentKHR(s_PresentQueue, &presentInfo);
|
|
CHECK_RESULT(result);
|
|
|
|
vkQueueWaitIdle(s_PresentQueue);
|
|
return VK_SUCCESS;
|
|
}
|
|
}
|