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{};
descIndexingFeature.descriptorBindingVariableDescriptorCount = true;
descIndexingFeature.shaderSampledImageArrayNonUniformIndexing = true;
descIndexingFeature.runtimeDescriptorArray = true;
// Prepare to create the device
vk::DeviceCreateInfo deviceCreateInfo

View File

@ -79,6 +79,41 @@ namespace SHADE
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(
VmaAllocator const* allocator,
SHImageCreateParams const& imageDetails,
@ -196,37 +231,7 @@ namespace SHADE
, createFlags {create}
, vmaAllocator {allocator}
{
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. ");
CreateFramebufferImage();
}
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;
}
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
{
vkImage = inVkImage;

View File

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

View File

@ -6,6 +6,67 @@
namespace SHADE
{
void SHVkImageView::Create(void) noexcept
{
auto parentImageCreateFlags = parentImage->GetImageeCreateFlags();
// 2D array image type means parent image must be 2D array compatible
if (imageViewDetails.viewType == vk::ImageViewType::e2DArray)
{
if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::e2DArrayCompatible))
{
SHLOG_ERROR("Failed to create image view. Parent image not 2D array compatible. ");
return;
}
}
// Check if its possible for the image view to have different format than parent image
if (imageViewDetails.format != parentImage->GetImageFormat())
{
if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::eMutableFormat))
{
SHLOG_ERROR("Failed to create image view. Format for image view not same as image but image not initialized with mutable format bit. ");
return;
}
}
vk::ImageViewCreateInfo viewCreateInfo
{
.pNext = nullptr, // Can be used to override with a VkImageViewUsageCreateInfo to override usage. See Vulkan spec page 877 for more information
.image = parentImage->GetVkImage(),
.viewType = imageViewDetails.viewType,
.format = imageViewDetails.format,
.components
{
.r = vk::ComponentSwizzle::eR,
.g = vk::ComponentSwizzle::eG,
.b = vk::ComponentSwizzle::eB,
.a = vk::ComponentSwizzle::eA,
},
.subresourceRange
{
.aspectMask = imageViewDetails.imageAspectFlags,
.baseMipLevel = imageViewDetails.baseMipLevel,
.levelCount = imageViewDetails.mipLevelCount,
.baseArrayLayer = imageViewDetails.baseArrayLayer,
.layerCount = imageViewDetails.layerCount,
},
};
if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createImageView(&viewCreateInfo, nullptr, &vkImageView); result != vk::Result::eSuccess)
{
SHVulkanDebugUtil::ReportVkError(result, "Failed to create image view! ");
return;
}
else
{
SHVulkanDebugUtil::ReportVkSuccess("Successfully created image view. ");
}
}
/***************************************************************************/
/*!
@ -18,70 +79,12 @@ namespace SHADE
*/
/***************************************************************************/
SHVkImageView::SHVkImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept
: parentImage{ }
: parentImage{ parent }
, vkImageView{}
, imageViewDetails{}
, imageViewDetails{createParams}
, logicalDeviceHdl {inLogicalDeviceHdl}
{
auto parentImageCreateFlags = parent->GetImageeCreateFlags();
// 2D array image type means parent image must be 2D array compatible
if (createParams.viewType == vk::ImageViewType::e2DArray)
{
if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::e2DArrayCompatible))
{
SHLOG_ERROR("Failed to create image view. Parent image not 2D array compatible. ");
return;
}
}
// Check if its possible for the image view to have different format than parent image
if (createParams.format != parent->GetImageFormat())
{
if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::eMutableFormat))
{
SHLOG_ERROR("Failed to create image view. Format for image view not same as image but image not initialized with mutable format bit. ");
return;
}
}
vk::ImageViewCreateInfo viewCreateInfo
{
.pNext = nullptr, // Can be used to override with a VkImageViewUsageCreateInfo to override usage. See Vulkan spec page 877 for more information
.image = parent->GetVkImage(),
.viewType = createParams.viewType,
.format = createParams.format,
.components
{
.r = vk::ComponentSwizzle::eR,
.g = vk::ComponentSwizzle::eG,
.b = vk::ComponentSwizzle::eB,
.a = vk::ComponentSwizzle::eA,
},
.subresourceRange
{
.aspectMask = createParams.imageAspectFlags,
.baseMipLevel = createParams.baseMipLevel,
.levelCount = createParams.mipLevelCount,
.baseArrayLayer = createParams.baseArrayLayer,
.layerCount = createParams.layerCount,
},
};
if (auto result = inLogicalDeviceHdl->GetVkLogicalDevice().createImageView(&viewCreateInfo, nullptr, &vkImageView); result != vk::Result::eSuccess)
{
SHVulkanDebugUtil::ReportVkError(result, "Failed to create image view! ");
return;
}
else
{
SHVulkanDebugUtil::ReportVkSuccess("Successfully created image view. ");
}
// After success, THEN assign variables
parentImage = parent;
imageViewDetails = createParams;
Create();
}
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
{
return parentImage;

View File

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

View File

@ -341,10 +341,7 @@ namespace SHADE
{
device->WaitIdle();
// Resize the swapchain
swapchain->Resize(surface, windowDims.first, windowDims.second);
renderContext.HandleResize();
HandleResize();
}
const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame();
@ -387,10 +384,8 @@ namespace SHADE
// If swapchain is incompatible/outdated
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
{
window = wind;

View File

@ -246,6 +246,8 @@ namespace SHADE
/***************************************************************************/
void BuildTextures();
void HandleResize(void) noexcept;
/*-----------------------------------------------------------------------------*/
/* 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
{
if (nodeIndexing.contains(nodeName))

View File

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

View File

@ -2,9 +2,11 @@
#include "SHRenderGraphResource.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/Swapchain/SHVkSwapchain.h"
#include "Graphics/Images/SHVkImageView.h"
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
: resourceType{ type }
: logicalDevice {logicalDevice}
, swapchain{ swapchain }
, resourceType{ type }
, resourceFormat{ format }
, images{}
, imageViews{}
@ -52,10 +56,10 @@ namespace SHADE
, resourceName{ name }
{
// 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;
vk::ImageUsageFlags usage = {};
imageAspectFlags = vk::ImageAspectFlags{};
usage = {};
// Check the resource type and set image usage flags and image aspect flags accordingly
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 */
/*-----------------------------------------------------------------------*/
// for creation/recreation
Handle<SHVkLogicalDevice> logicalDevice;
// for creation/recreation
Handle<SHVkSwapchain> swapchain;
//! Name of the resource
std::string resourceName;
@ -47,6 +53,14 @@ namespace SHADE
//! Number of mipmap levels
uint8_t mipLevels;
//! image aspect flags
vk::ImageAspectFlags imageAspectFlags;
//! usage flags
vk::ImageUsageFlags usage = {};
public:
/*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */
@ -56,6 +70,8 @@ namespace SHADE
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
~SHRenderGraphResource(void) noexcept;
void HandleResize (void) noexcept;
friend class SHRenderGraphNode;
friend class SHRenderGraph;
};