Handled resizing for the render graph resource (not tested)

This commit is contained in:
Brandon Mak 2022-10-01 16:33:16 +08:00
parent ec2ec82163
commit b657ad8884
11 changed files with 220 additions and 105 deletions

View File

@ -195,6 +195,8 @@ namespace SHADE
vk::PhysicalDeviceDescriptorIndexingFeatures descIndexingFeature{}; vk::PhysicalDeviceDescriptorIndexingFeatures descIndexingFeature{};
descIndexingFeature.descriptorBindingVariableDescriptorCount = true; descIndexingFeature.descriptorBindingVariableDescriptorCount = true;
descIndexingFeature.shaderSampledImageArrayNonUniformIndexing = true;
descIndexingFeature.runtimeDescriptorArray = true;
// Prepare to create the device // Prepare to create the device
vk::DeviceCreateInfo deviceCreateInfo vk::DeviceCreateInfo deviceCreateInfo

View File

@ -79,6 +79,41 @@ namespace SHADE
vmaUnmapMemory(*vmaAllocator, stagingAlloc); vmaUnmapMemory(*vmaAllocator, stagingAlloc);
} }
void SHVkImage::CreateFramebufferImage(void) noexcept
{
vk::ImageCreateInfo imageCreateInfo{};
imageCreateInfo.imageType = vk::ImageType::e2D;
imageCreateInfo.extent.width = width;
imageCreateInfo.extent.height = height;
imageCreateInfo.extent.depth = depth;
imageCreateInfo.mipLevels = mipLevelCount;
imageCreateInfo.arrayLayers = layerCount;
imageCreateInfo.format = imageFormat;
imageCreateInfo.tiling = vk::ImageTiling::eOptimal;
imageCreateInfo.initialLayout = vk::ImageLayout::eUndefined;
imageCreateInfo.usage = usageFlags;
imageCreateInfo.sharingMode = vk::SharingMode::eExclusive;
imageCreateInfo.samples = vk::SampleCountFlagBits::e1;
imageCreateInfo.flags = createFlags;
// Prepare allocation parameters for call to create images later
VmaAllocationCreateInfo allocCreateInfo{};
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
allocCreateInfo.flags = {}; // TODO: Make sure the vk::MemoryPropertyFlags returned from vmaGetAllocationMemoryProperties has the device local bit set
VmaAllocationInfo allocInfo{};
VkImage tempImage;
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
vkImage = tempImage;
if (result != VK_SUCCESS)
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
else
SHVulkanDebugUtil::ReportVkSuccess("Successfully created image. ");
}
SHVkImage::SHVkImage( SHVkImage::SHVkImage(
VmaAllocator const* allocator, VmaAllocator const* allocator,
SHImageCreateParams const& imageDetails, SHImageCreateParams const& imageDetails,
@ -196,37 +231,7 @@ namespace SHADE
, createFlags {create} , createFlags {create}
, vmaAllocator {allocator} , vmaAllocator {allocator}
{ {
vk::ImageCreateInfo imageCreateInfo{}; CreateFramebufferImage();
imageCreateInfo.imageType = vk::ImageType::e2D;
imageCreateInfo.extent.width = width;
imageCreateInfo.extent.height = height;
imageCreateInfo.extent.depth = depth;
imageCreateInfo.mipLevels = mipLevelCount;
imageCreateInfo.arrayLayers = layerCount;
imageCreateInfo.format = imageFormat;
imageCreateInfo.tiling = vk::ImageTiling::eOptimal;
imageCreateInfo.initialLayout = vk::ImageLayout::eUndefined;
imageCreateInfo.usage = usageFlags;
imageCreateInfo.sharingMode = vk::SharingMode::eExclusive;
imageCreateInfo.samples = vk::SampleCountFlagBits::e1;
imageCreateInfo.flags = createFlags;
// Prepare allocation parameters for call to create images later
VmaAllocationCreateInfo allocCreateInfo{};
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
allocCreateInfo.flags = {}; // TODO: Make sure the vk::MemoryPropertyFlags returned from vmaGetAllocationMemoryProperties has the device local bit set
VmaAllocationInfo allocInfo{};
VkImage tempImage;
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
vkImage = tempImage;
if (result != VK_SUCCESS)
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
else
SHVulkanDebugUtil::ReportVkSuccess("Successfully created image. ");
} }
Handle<SHVkImageView> SHVkImage::CreateImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept Handle<SHVkImageView> SHVkImage::CreateImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept
@ -288,6 +293,13 @@ namespace SHADE
barrier.subresourceRange.layerCount = layerCount; barrier.subresourceRange.layerCount = layerCount;
} }
void SHVkImage::HandleResizeFramebufferImage(void) noexcept
{
vmaDestroyImage(*vmaAllocator, vkImage, alloc);
CreateFramebufferImage();
}
void SHVkImage::LinkWithExteriorImage(vk::Image inVkImage, vk::ImageType type, uint32_t inWidth, uint32_t inHeight, uint32_t inDepth, uint32_t layers, uint8_t levels, vk::Format format, vk::ImageUsageFlags flags) noexcept void SHVkImage::LinkWithExteriorImage(vk::Image inVkImage, vk::ImageType type, uint32_t inWidth, uint32_t inHeight, uint32_t inDepth, uint32_t layers, uint8_t levels, vk::Format format, vk::ImageUsageFlags flags) noexcept
{ {
vkImage = inVkImage; vkImage = inVkImage;

View File

@ -108,7 +108,7 @@ namespace SHADE
/* PRIVATE MEMBER FUNCTIONS */ /* PRIVATE MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
void PrepStagingBuffer(const void* data, uint32_t srcSize) noexcept; void PrepStagingBuffer(const void* data, uint32_t srcSize) noexcept;
void CreateFramebufferImage (void) noexcept;
public: public:
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -137,6 +137,7 @@ namespace SHADE
Handle<SHVkImageView> CreateImageView (Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept; Handle<SHVkImageView> CreateImageView (Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept;
void TransferToDeviceResource (Handle<SHVkCommandBuffer> cmdBufferHdl) noexcept; void TransferToDeviceResource (Handle<SHVkCommandBuffer> cmdBufferHdl) noexcept;
void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept; void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept;
void HandleResizeFramebufferImage(void) noexcept;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* GETTERS AND SETTERS */ /* GETTERS AND SETTERS */

View File

@ -6,27 +6,13 @@
namespace SHADE namespace SHADE
{ {
/***************************************************************************/
/*!
\brief void SHVkImageView::Create(void) noexcept
Non-default ctor. Initializes image view with image that it is a view of.
\param parent
Parent image the view is a view of.
*/
/***************************************************************************/
SHVkImageView::SHVkImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept
: parentImage{ }
, vkImageView{}
, imageViewDetails{}
, logicalDeviceHdl {inLogicalDeviceHdl}
{ {
auto parentImageCreateFlags = parent->GetImageeCreateFlags(); auto parentImageCreateFlags = parentImage->GetImageeCreateFlags();
// 2D array image type means parent image must be 2D array compatible // 2D array image type means parent image must be 2D array compatible
if (createParams.viewType == vk::ImageViewType::e2DArray) if (imageViewDetails.viewType == vk::ImageViewType::e2DArray)
{ {
if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::e2DArrayCompatible)) if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::e2DArrayCompatible))
{ {
@ -36,7 +22,7 @@ namespace SHADE
} }
// Check if its possible for the image view to have different format than parent image // Check if its possible for the image view to have different format than parent image
if (createParams.format != parent->GetImageFormat()) if (imageViewDetails.format != parentImage->GetImageFormat())
{ {
if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::eMutableFormat)) if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::eMutableFormat))
{ {
@ -49,9 +35,9 @@ namespace SHADE
vk::ImageViewCreateInfo viewCreateInfo vk::ImageViewCreateInfo viewCreateInfo
{ {
.pNext = nullptr, // Can be used to override with a VkImageViewUsageCreateInfo to override usage. See Vulkan spec page 877 for more information .pNext = nullptr, // Can be used to override with a VkImageViewUsageCreateInfo to override usage. See Vulkan spec page 877 for more information
.image = parent->GetVkImage(), .image = parentImage->GetVkImage(),
.viewType = createParams.viewType, .viewType = imageViewDetails.viewType,
.format = createParams.format, .format = imageViewDetails.format,
.components .components
{ {
.r = vk::ComponentSwizzle::eR, .r = vk::ComponentSwizzle::eR,
@ -61,15 +47,15 @@ namespace SHADE
}, },
.subresourceRange .subresourceRange
{ {
.aspectMask = createParams.imageAspectFlags, .aspectMask = imageViewDetails.imageAspectFlags,
.baseMipLevel = createParams.baseMipLevel, .baseMipLevel = imageViewDetails.baseMipLevel,
.levelCount = createParams.mipLevelCount, .levelCount = imageViewDetails.mipLevelCount,
.baseArrayLayer = createParams.baseArrayLayer, .baseArrayLayer = imageViewDetails.baseArrayLayer,
.layerCount = createParams.layerCount, .layerCount = imageViewDetails.layerCount,
}, },
}; };
if (auto result = inLogicalDeviceHdl->GetVkLogicalDevice().createImageView(&viewCreateInfo, nullptr, &vkImageView); result != vk::Result::eSuccess) if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createImageView(&viewCreateInfo, nullptr, &vkImageView); result != vk::Result::eSuccess)
{ {
SHVulkanDebugUtil::ReportVkError(result, "Failed to create image view! "); SHVulkanDebugUtil::ReportVkError(result, "Failed to create image view! ");
return; return;
@ -79,9 +65,26 @@ namespace SHADE
SHVulkanDebugUtil::ReportVkSuccess("Successfully created image view. "); SHVulkanDebugUtil::ReportVkSuccess("Successfully created image view. ");
} }
// After success, THEN assign variables }
parentImage = parent;
imageViewDetails = createParams; /***************************************************************************/
/*!
\brief
Non-default ctor. Initializes image view with image that it is a view of.
\param parent
Parent image the view is a view of.
*/
/***************************************************************************/
SHVkImageView::SHVkImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept
: parentImage{ parent }
, vkImageView{}
, imageViewDetails{createParams}
, logicalDeviceHdl {inLogicalDeviceHdl}
{
Create();
} }
SHVkImageView::SHVkImageView(SHVkImageView&& rhs) noexcept SHVkImageView::SHVkImageView(SHVkImageView&& rhs) noexcept
@ -94,6 +97,17 @@ namespace SHADE
} }
void SHVkImageView::ViewNewImage(Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept
{
imageViewDetails = createParams;
parentImage = parent;
if (vkImageView)
logicalDeviceHdl->GetVkLogicalDevice().destroyImageView(vkImageView, nullptr);
Create();
}
Handle<SHVkImage> const& SHVkImageView::GetParentImage(void) const noexcept Handle<SHVkImage> const& SHVkImageView::GetParentImage(void) const noexcept
{ {
return parentImage; return parentImage;

View File

@ -25,12 +25,17 @@ namespace SHADE
//! Logical Device needed for creation and destruction //! Logical Device needed for creation and destruction
Handle<SHVkLogicalDevice> logicalDeviceHdl; Handle<SHVkLogicalDevice> logicalDeviceHdl;
//! Create new image view
void Create (void) noexcept;
public: public:
SHVkImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept; SHVkImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept;
~SHVkImageView(void) noexcept; ~SHVkImageView(void) noexcept;
SHVkImageView(SHVkImageView&& rhs) noexcept; SHVkImageView(SHVkImageView&& rhs) noexcept;
SHVkImageView& operator=(SHVkImageView&& rhs) noexcept; SHVkImageView& operator=(SHVkImageView&& rhs) noexcept;
void ViewNewImage (Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* GETTERS AND SETTERS */ /* GETTERS AND SETTERS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/

View File

@ -341,10 +341,7 @@ namespace SHADE
{ {
device->WaitIdle(); device->WaitIdle();
// Resize the swapchain HandleResize();
swapchain->Resize(surface, windowDims.first, windowDims.second);
renderContext.HandleResize();
} }
const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame(); const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame();
@ -387,10 +384,8 @@ namespace SHADE
// If swapchain is incompatible/outdated // If swapchain is incompatible/outdated
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR) if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR)
{ {
auto windowDims = window->GetWindowSize();
swapchain->Resize(surface, windowDims.first, windowDims.second);
renderContext.HandleResize(); HandleResize();
} }
} }
@ -509,6 +504,16 @@ namespace SHADE
); );
} }
void SHGraphicsSystem::HandleResize(void) noexcept
{
auto windowDims = window->GetWindowSize();
// Resize the swapchain
swapchain->Resize(surface, windowDims.first, windowDims.second);
renderContext.HandleResize();
}
void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept
{ {
window = wind; window = wind;

View File

@ -246,6 +246,8 @@ namespace SHADE
/***************************************************************************/ /***************************************************************************/
void BuildTextures(); void BuildTextures();
void HandleResize(void) noexcept;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Setters */ /* Setters */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/

View File

@ -480,6 +480,15 @@ namespace SHADE
} }
} }
void SHRenderGraph::HandleResize(void) noexcept
{
// resize resources
for (auto& [name, resource]: graphResources)
resource->HandleResize();
}
Handle<SHRenderGraphNode> SHRenderGraph::GetNode(std::string const& nodeName) const noexcept Handle<SHRenderGraphNode> SHRenderGraph::GetNode(std::string const& nodeName) const noexcept
{ {
if (nodeIndexing.contains(nodeName)) if (nodeIndexing.contains(nodeName))

View File

@ -80,6 +80,7 @@ namespace SHADE
void Generate (void) noexcept; void Generate (void) noexcept;
void Execute (uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept; void Execute (uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept;
void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool); void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
void HandleResize (void) noexcept;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */ /* SETTERS AND GETTERS */

View File

@ -2,9 +2,11 @@
#include "SHRenderGraphResource.h" #include "SHRenderGraphResource.h"
#include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/Swapchain/SHVkSwapchain.h" #include "Graphics/Swapchain/SHVkSwapchain.h"
#include "Graphics/Images/SHVkImageView.h"
namespace SHADE namespace SHADE
{ {
/***************************************************************************/ /***************************************************************************/
/*! /*!
@ -42,7 +44,9 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
SHRenderGraphResource::SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageCreateFlagBits createFlags) noexcept SHRenderGraphResource::SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageCreateFlagBits createFlags) noexcept
: resourceType{ type } : logicalDevice {logicalDevice}
, swapchain{ swapchain }
, resourceType{ type }
, resourceFormat{ format } , resourceFormat{ format }
, images{} , images{}
, imageViews{} , imageViews{}
@ -52,10 +56,10 @@ namespace SHADE
, resourceName{ name } , resourceName{ name }
{ {
// If the resource type is an arbitrary image and not swapchain image // If the resource type is an arbitrary image and not swapchain image
if (type != SH_ATT_DESC_TYPE::COLOR_PRESENT) if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT)
{ {
vk::ImageAspectFlags imageAspectFlags; imageAspectFlags = vk::ImageAspectFlags{};
vk::ImageUsageFlags usage = {}; usage = {};
// Check the resource type and set image usage flags and image aspect flags accordingly // Check the resource type and set image usage flags and image aspect flags accordingly
switch (resourceType) switch (resourceType)
@ -189,4 +193,48 @@ namespace SHADE
} }
void SHRenderGraphResource::HandleResize(void) noexcept
{
if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT)
{
// prepare image view details
SHImageViewDetails viewDetails
{
.viewType = vk::ImageViewType::e2D,
.format = images[0]->GetImageFormat(),
.imageAspectFlags = imageAspectFlags,
.baseMipLevel = 0,
.mipLevelCount = mipLevels,
.baseArrayLayer = 0,
.layerCount = 1,
};
for (uint32_t i = 0; i < images.size(); ++i)
{
images[i]->HandleResizeFramebufferImage();
imageViews[i]->ViewNewImage(images[i], viewDetails);
}
}
else
{
// Prepare image view details
SHImageViewDetails viewDetails
{
.viewType = vk::ImageViewType::e2D,
.format = swapchain->GetSurfaceFormatKHR().format,
.imageAspectFlags = vk::ImageAspectFlagBits::eColor,
.baseMipLevel = 0,
.mipLevelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
};
for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i)
{
images[i] = swapchain->GetSwapchainImage(i);
imageViews[i]->ViewNewImage(images[i], viewDetails);
}
}
}
} }

View File

@ -20,6 +20,12 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */ /* PRIVATE MEMBER VARIABLES */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
// for creation/recreation
Handle<SHVkLogicalDevice> logicalDevice;
// for creation/recreation
Handle<SHVkSwapchain> swapchain;
//! Name of the resource //! Name of the resource
std::string resourceName; std::string resourceName;
@ -47,6 +53,14 @@ namespace SHADE
//! Number of mipmap levels //! Number of mipmap levels
uint8_t mipLevels; uint8_t mipLevels;
//! image aspect flags
vk::ImageAspectFlags imageAspectFlags;
//! usage flags
vk::ImageUsageFlags usage = {};
public: public:
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */ /* CTORS AND DTORS */
@ -56,6 +70,8 @@ namespace SHADE
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept; SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
~SHRenderGraphResource(void) noexcept; ~SHRenderGraphResource(void) noexcept;
void HandleResize (void) noexcept;
friend class SHRenderGraphNode; friend class SHRenderGraphNode;
friend class SHRenderGraph; friend class SHRenderGraph;
}; };