Added resize + fullscreen support
This commit is contained in:
@@ -89,7 +89,7 @@ namespace PB::Renderer
|
||||
|
||||
/*
|
||||
Assembles shaders, fixed function state and creates the render pipeline.
|
||||
Also checks that the render pass is compatiable.
|
||||
Also checks that the render pass is compatible.
|
||||
*/
|
||||
static bool CreateGraphicsPipeline();
|
||||
|
||||
@@ -108,9 +108,11 @@ namespace PB::Renderer
|
||||
/*
|
||||
Draws a frame to the screen using the command buffers and sync objects.
|
||||
*/
|
||||
static bool RenderPass();
|
||||
static bool RenderPass(GLFWwindow* window);
|
||||
|
||||
private:
|
||||
// === Vulkan init helpers === //
|
||||
|
||||
static bool IsDeviceSuitable(const VkPhysicalDevice& device);
|
||||
static QueueFamilyIndices FindQueueFamilies(const VkPhysicalDevice& device);
|
||||
static bool CheckDeviceExtensionSupport(const VkPhysicalDevice& device);
|
||||
@@ -122,6 +124,15 @@ namespace PB::Renderer
|
||||
|
||||
static VkShaderModule CreateShaderModule(const std::string& filename);
|
||||
|
||||
// === Vulkan render helpers === //
|
||||
|
||||
static VkResult RenderPassInternal();
|
||||
|
||||
static void RecreateSwapChain(GLFWwindow* window);
|
||||
static void CleanupSwapChain();
|
||||
|
||||
// === Vulkan resources === //
|
||||
|
||||
static VkInstance s_Instance;
|
||||
static VkSurfaceKHR s_Surface;
|
||||
|
||||
|
||||
@@ -1,8 +1,70 @@
|
||||
#include "VulkanManager.h"
|
||||
|
||||
#define CHECK_RESULT(res) if (res != VK_SUCCESS) { return res; }
|
||||
|
||||
namespace PB::Renderer
|
||||
{
|
||||
bool VulkanManager::RenderPass()
|
||||
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(
|
||||
@@ -13,17 +75,7 @@ namespace PB::Renderer
|
||||
VK_NULL_HANDLE,
|
||||
&imageIndex
|
||||
);
|
||||
|
||||
if (result == VK_ERROR_OUT_OF_DATE_KHR)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)
|
||||
{
|
||||
std::cout << "PB::Renderer::VulkanManager::RenderPass(): Failed to acquire swap chain image!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
CHECK_RESULT(result);
|
||||
|
||||
VkSubmitInfo submitInfo{};
|
||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
@@ -41,11 +93,8 @@ namespace PB::Renderer
|
||||
submitInfo.signalSemaphoreCount = 1;
|
||||
submitInfo.pSignalSemaphores = signalSemaphores;
|
||||
|
||||
if (vkQueueSubmit(s_GraphicsQueue, 1, &submitInfo, VK_NULL_HANDLE) != VK_SUCCESS)
|
||||
{
|
||||
std::cout << "PB::Renderer::VulkanManager::RenderPass(): Failed to submit draw command buffer!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
result = vkQueueSubmit(s_GraphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
|
||||
CHECK_RESULT(result);
|
||||
|
||||
VkPresentInfoKHR presentInfo{};
|
||||
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||
@@ -58,19 +107,9 @@ namespace PB::Renderer
|
||||
presentInfo.pImageIndices = &imageIndex;
|
||||
|
||||
result = vkQueuePresentKHR(s_PresentQueue, &presentInfo);
|
||||
|
||||
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (result != VK_SUCCESS)
|
||||
{
|
||||
std::cout << "PB::Renderer::VulkanManager::RenderPass(): Failed to present swap chain image!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
CHECK_RESULT(result);
|
||||
|
||||
vkQueueWaitIdle(s_PresentQueue);
|
||||
return true;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user