From e2b86545bb8482c95d2f90f457e1a6d253bfbb14 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sat, 1 Oct 2022 23:57:08 +0800 Subject: [PATCH] Window resize working --- SHADE_Application/src/Scenes/SBTestScene.cpp | 4 +- .../Graphics/Framebuffer/SHVkFramebuffer.cpp | 45 +++++++++++++++++++ .../Graphics/Framebuffer/SHVkFramebuffer.h | 2 + .../src/Graphics/Images/SHVkImage.cpp | 5 ++- SHADE_Engine/src/Graphics/Images/SHVkImage.h | 2 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 18 +++++++- .../MiddleEnd/Interface/SHGraphicsSystem.h | 2 + .../MiddleEnd/Interface/SHViewport.cpp | 12 +++++ .../Graphics/MiddleEnd/Interface/SHViewport.h | 6 +++ .../Graphics/RenderGraph/SHRenderGraph.cpp | 14 +++--- .../src/Graphics/RenderGraph/SHRenderGraph.h | 2 +- .../RenderGraph/SHRenderGraphNode.cpp | 23 ++++++++++ .../RenderGraph/SHRenderGraphResource.cpp | 9 +++- .../RenderGraph/SHRenderGraphResource.h | 2 +- .../Graphics/Renderpass/SHVkRenderpass.cpp | 27 +++++++++++ .../src/Graphics/Renderpass/SHVkRenderpass.h | 2 + 16 files changed, 158 insertions(+), 17 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 6daa3645..5eee8cac 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -76,8 +76,8 @@ namespace Sandbox // Create Stress Test Objects static const SHVec3 TEST_OBJ_SCALE = { 0.05f, 0.05f, 0.05f }; - constexpr int NUM_ROWS = 100; - constexpr int NUM_COLS = 100; + constexpr int NUM_ROWS = 10; + constexpr int NUM_COLS = 10; static const SHVec3 TEST_OBJ_SPACING = { 0.05f, 0.05f, 0.05f }; static const SHVec3 TEST_OBJ_START_POS = { - (NUM_COLS / 2 * TEST_OBJ_SPACING.x ) + 1.0f, -2.0f, -1.0f }; diff --git a/SHADE_Engine/src/Graphics/Framebuffer/SHVkFramebuffer.cpp b/SHADE_Engine/src/Graphics/Framebuffer/SHVkFramebuffer.cpp index 1386134f..76e627d3 100644 --- a/SHADE_Engine/src/Graphics/Framebuffer/SHVkFramebuffer.cpp +++ b/SHADE_Engine/src/Graphics/Framebuffer/SHVkFramebuffer.cpp @@ -98,6 +98,51 @@ namespace SHADE return *this; } + void SHVkFramebuffer::HandleResize(Handle const& renderpassHdl, std::vector> const& attachments, uint32_t inWidth, uint32_t inHeight) noexcept + { + width = inWidth; + height = inHeight; + + for (auto& attachment : attachments) + { + // Not sure if its an error to pass in diff dimension images. + if (attachment->GetParentImage()->GetWidth() != (*attachments.begin())->GetParentImage()->GetWidth() || attachment->GetParentImage()->GetHeight() != (*attachments.begin())->GetParentImage()->GetHeight()) + { + SHLOG_ERROR("Dimensions of images not same as each other. Cannot create framebuffer."); + return; + } + } + + std::vector vkAttachments(attachments.size()); + + uint32_t i = 0; + for(auto const& attachment : attachments) + { + vkAttachments[i] = attachment->GetImageView(); + ++i; + } + + vk::FramebufferCreateInfo createInfo + { + .renderPass = renderpassHdl->GetVkRenderpass(), + .attachmentCount = static_cast(vkAttachments.size()), + .pAttachments = vkAttachments.data(), + .width = width, + .height = height, + .layers = 1 // TODO: Find out why this is 1 + }; + + if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createFramebuffer(&createInfo, nullptr, &vkFramebuffer); result != vk::Result::eSuccess) + { + SHVulkanDebugUtil::ReportVkError(result, "Failed to create framebuffer. "); + return; + } + else + { + SHVulkanDebugUtil::ReportVkSuccess("Successfully created framebuffer. "); + } + } + /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/Framebuffer/SHVkFramebuffer.h b/SHADE_Engine/src/Graphics/Framebuffer/SHVkFramebuffer.h index fa9161e8..47bfcf99 100644 --- a/SHADE_Engine/src/Graphics/Framebuffer/SHVkFramebuffer.h +++ b/SHADE_Engine/src/Graphics/Framebuffer/SHVkFramebuffer.h @@ -37,6 +37,8 @@ namespace SHADE SHVkFramebuffer(SHVkFramebuffer&& rhs) noexcept; SHVkFramebuffer& operator=(SHVkFramebuffer&& rhs) noexcept; + void HandleResize (Handle const& renderpassHdl, std::vector> const& attachments, uint32_t inWidth, uint32_t inHeight) noexcept; + /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ /*-----------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp b/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp index ed539a6c..00cc31bf 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp +++ b/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp @@ -293,10 +293,13 @@ namespace SHADE barrier.subresourceRange.layerCount = layerCount; } - void SHVkImage::HandleResizeFramebufferImage(void) noexcept + void SHVkImage::HandleResizeFramebufferImage(uint32_t newWidth, uint32_t newHeight) noexcept { vmaDestroyImage(*vmaAllocator, vkImage, alloc); + width = newWidth; + height = newHeight; + CreateFramebufferImage(); } diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImage.h b/SHADE_Engine/src/Graphics/Images/SHVkImage.h index b23d7bd4..51b71b26 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkImage.h +++ b/SHADE_Engine/src/Graphics/Images/SHVkImage.h @@ -137,7 +137,7 @@ namespace SHADE Handle CreateImageView (Handle const& inLogicalDeviceHdl, Handle const& parent, SHImageViewDetails const& createParams) const noexcept; void TransferToDeviceResource (Handle cmdBufferHdl) noexcept; void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept; - void HandleResizeFramebufferImage(void) noexcept; + void HandleResizeFramebufferImage(uint32_t newWidth, uint32_t newHeight) noexcept; /*-----------------------------------------------------------------------*/ /* GETTERS AND SETTERS */ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index e4207c20..979f8d40 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -67,6 +67,9 @@ namespace SHADE // Register callback to notify render context upon a window resize window->RegisterWindowSizeCallback([&]([[maybe_unused]] uint32_t width, [[maybe_unused]] uint32_t height) { + if (width == 0 || height == 0) + return; + renderContext.SetIsResized(true); }); @@ -116,8 +119,8 @@ namespace SHADE screenCamera = resourceManager.Create(); screenCamera->SetLookAt(SHVec3(0.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 1.0f), SHVec3(0.0f, 1.0f, 0.0f)); screenCamera->SetOrthographic(static_cast(windowDims.first), static_cast(windowDims.second), 0.01f, 100.0f); + worldCamera = resourceManager.Create(); - //worldCamera->SetLookAt(SHVec3(1.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 2.0f), SHVec3(0.0f, 1.0f, 0.0f)); worldCamera->SetLookAt(SHVec3(0.0f, 0.0f, 0.0f), SHVec3(0.0f, 0.0f, -2.0f), SHVec3(0.0f, 1.0f, 0.0f)); worldCamera->SetPerspective(90.0f, static_cast(windowDims.first), static_cast(windowDims.second), 0.0f, 100.0f); @@ -125,7 +128,7 @@ namespace SHADE defaultViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast(window->GetWindowSize().first), static_cast(window->GetWindowSize().second), 0.0f, 1.0f)); // Get render graph from default viewport world renderer - auto worldRenderGraph = resourceManager.Create(); + worldRenderGraph = resourceManager.Create(); std::vector> renderContextCmdPools{swapchain->GetNumImages()}; for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i) @@ -249,6 +252,10 @@ namespace SHADE // Begin recording the command buffer currentCmdBuffer->BeginRecording(); + uint32_t w = viewports[vpIndex]->GetWidth(); + uint32_t h = viewports[vpIndex]->GetHeight(); + currentCmdBuffer->SetViewportScissor (static_cast(w), static_cast(h), w, h); + currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout()); // Bind all the buffers required for meshes @@ -512,6 +519,13 @@ namespace SHADE swapchain->Resize(surface, windowDims.first, windowDims.second); renderContext.HandleResize(); + + worldRenderGraph->HandleResize(windowDims.first, windowDims.second); + + defaultViewport->SetWidth(windowDims.first); + defaultViewport->SetHeight(windowDims.second); + + worldCamera->SetPerspective(90.0f, static_cast(windowDims.first), static_cast(windowDims.second), 0.0f, 100.0f); } void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 10df44a5..1dddaeb1 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -316,5 +316,7 @@ namespace SHADE // Temp Materials Handle defaultMaterial; + + Handle worldRenderGraph; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp index 25c5bca2..d6eea3d7 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp @@ -73,4 +73,16 @@ namespace SHADE iter->Free(); renderers.erase(iter); } + + void SHViewport::SetWidth(uint32_t w) noexcept + { + viewport.width = w; + } + + void SHViewport::SetHeight(uint32_t h) noexcept + { + viewport.height = h; + + } + } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h index d97d62ce..ce992f77 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h @@ -62,6 +62,12 @@ namespace SHADE Handle AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, std::vector>& cmdPools, Handle descriptorPool, Handle cameraDescLayout, Handle renderGraph); void RemoveRenderer(Handle renderer); + /*-----------------------------------------------------------------------------*/ + /* Setters */ + /*-----------------------------------------------------------------------------*/ + void SetWidth(uint32_t w) noexcept; + void SetHeight (uint32_t h) noexcept; + /*-----------------------------------------------------------------------------*/ /* Getters */ /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 27a1d604..cad6a78e 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -46,7 +46,7 @@ namespace SHADE if (w == static_cast(-1) && h == static_cast(-1)) { w = swapchainHdl->GetSwapchainImage(0)->GetWidth(); - w = swapchainHdl->GetSwapchainImage(0)->GetHeight(); + h = swapchainHdl->GetSwapchainImage(0)->GetHeight(); format = swapchainHdl->GetSurfaceFormatKHR().format; } @@ -465,9 +465,6 @@ namespace SHADE // better way to manage these void SHRenderGraph::Execute(uint32_t frameIndex, Handle cmdBuffer, Handle descPool) noexcept { - // TODO: DON'T HARDCODE THIS - cmdBuffer->SetViewportScissor(1920.0f, 1080.0f, 1920, 1080); - for (auto& node : nodes) node->Execute(cmdBuffer, descPool, frameIndex); } @@ -480,13 +477,16 @@ namespace SHADE } } - void SHRenderGraph::HandleResize(void) noexcept + void SHRenderGraph::HandleResize(uint32_t newWidth, uint32_t newHeight) noexcept { // resize resources for (auto& [name, resource]: graphResources) - resource->HandleResize(); - + resource->HandleResize(newWidth, newHeight); + for (auto& node : nodes) + { + node->HandleResize(); + } } Handle SHRenderGraph::GetNode(std::string const& nodeName) const noexcept diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index 83aeeb2c..a3140a4f 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -80,7 +80,7 @@ namespace SHADE void Generate (void) noexcept; void Execute (uint32_t frameIndex, Handle cmdBuffer, Handle descPool) noexcept; void FinaliseBatch(uint32_t frameIndex, Handle descPool); - void HandleResize (void) noexcept; + void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept; /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index 551e90fc..05232af3 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -3,6 +3,7 @@ #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Images/SHVkImageView.h" #include "Graphics/Swapchain/SHVkSwapchain.h" +#include "Graphics/Framebuffer/SHVkFramebuffer.h" #include "SHRenderGraphResource.h" #include "SHSubpass.h" @@ -58,7 +59,29 @@ namespace SHADE void SHRenderGraphNode::HandleResize(void) noexcept { + renderpass->HandleResize(); + for (uint32_t i = 0; i < framebuffers.size(); ++i) + { + std::vector> imageViews(attResources.size()); + uint32_t fbWidth = std::numeric_limits::max(); + uint32_t fbHeight = std::numeric_limits::max(); + + for (uint32_t j = 0; j < attResources.size(); ++j) + { + uint32_t imageViewIndex = (attResources[j]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) ? i : 0; + imageViews[j] = attResources[j]->imageViews[imageViewIndex]; + + // We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's + if (fbWidth > attResources[j]->width) + fbWidth = attResources[j]->width; + if (fbHeight > attResources[j]->height) + fbHeight = attResources[j]->height; + } + + + framebuffers[i]->HandleResize(renderpass, imageViews, fbWidth, fbHeight); + } } /***************************************************************************/ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp index 72dd557f..cc881867 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp @@ -146,6 +146,7 @@ namespace SHADE , width{ rhs.width } , height{ rhs.height } , mipLevels{ rhs.mipLevels } + , imageAspectFlags{ rhs.imageAspectFlags } { } @@ -176,6 +177,7 @@ namespace SHADE width = rhs.width; height = rhs.height; mipLevels = rhs.mipLevels; + imageAspectFlags = rhs.imageAspectFlags; return *this; } @@ -193,8 +195,11 @@ namespace SHADE } - void SHRenderGraphResource::HandleResize(void) noexcept + void SHRenderGraphResource::HandleResize(uint32_t newWidth, uint32_t newHeight) noexcept { + width = newWidth; + height = newHeight; + if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT) { // prepare image view details @@ -211,7 +216,7 @@ namespace SHADE for (uint32_t i = 0; i < images.size(); ++i) { - images[i]->HandleResizeFramebufferImage(); + images[i]->HandleResizeFramebufferImage(width, height); imageViews[i]->ViewNewImage(images[i], viewDetails); } } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h index 741acdc0..ebb699d8 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h @@ -70,7 +70,7 @@ namespace SHADE SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept; ~SHRenderGraphResource(void) noexcept; - void HandleResize (void) noexcept; + void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept; friend class SHRenderGraphNode; friend class SHRenderGraph; diff --git a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp index 349c507e..fee23f13 100644 --- a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp +++ b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp @@ -227,6 +227,7 @@ namespace SHADE , vkSubpassDeps{ std::move(rhs.vkSubpassDeps) } , clearColors{ std::move(rhs.clearColors) } , vkAttachmentDescriptions{ std::move(rhs.vkAttachmentDescriptions) } + , numAttDescs{rhs.numAttDescs} { rhs.vkRenderpass = VK_NULL_HANDLE; } @@ -243,6 +244,7 @@ namespace SHADE vkSubpassDeps = std::move(rhs.vkSubpassDeps); clearColors = std::move(rhs.clearColors); vkAttachmentDescriptions = std::move(rhs.vkAttachmentDescriptions); + numAttDescs = std::move(rhs.numAttDescs); rhs.vkRenderpass = VK_NULL_HANDLE; @@ -255,6 +257,31 @@ namespace SHADE } + void SHVkRenderpass::HandleResize(void) noexcept + { + logicalDeviceHdl->GetVkLogicalDevice().destroyRenderPass(vkRenderpass, nullptr); + + vk::RenderPassCreateInfo renderPassCreateInfo{}; + + renderPassCreateInfo.attachmentCount = static_cast(vkAttachmentDescriptions.size()); + renderPassCreateInfo.pAttachments = vkAttachmentDescriptions.data(); + renderPassCreateInfo.subpassCount = static_cast(vkSubpassDescriptions.size()); + renderPassCreateInfo.pSubpasses = vkSubpassDescriptions.data(); + renderPassCreateInfo.dependencyCount = static_cast(vkSubpassDeps.size()); + renderPassCreateInfo.pDependencies = vkSubpassDeps.data(); + + + if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createRenderPass(&renderPassCreateInfo, nullptr, &vkRenderpass); result != vk::Result::eSuccess) + { + SHVulkanDebugUtil::ReportVkError(result, "Failed to create Renderpass. "); + } + else + { + SHVulkanDebugUtil::ReportVkSuccess("Successfully created Renderpass. "); + } + + } + vk::RenderPass SHVkRenderpass::GetVkRenderpass(void) const noexcept { return vkRenderpass; diff --git a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.h b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.h index a2799eb7..70a04bbf 100644 --- a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.h +++ b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.h @@ -55,6 +55,8 @@ namespace SHADE SHVkRenderpass(SHVkRenderpass&& rhs) noexcept; SHVkRenderpass& operator=(SHVkRenderpass&& rhs) noexcept; + void HandleResize (void) noexcept; + /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/