Merge pull request #90 from SHADE-DP/SP3-1-Rendering

Support for docking (incomplete)
This commit is contained in:
XiaoQiDigipen 2022-10-16 16:38:30 +08:00 committed by GitHub
commit bda38049ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 347 additions and 117 deletions

View File

@ -39,7 +39,8 @@ namespace SHADE
}
SHVkSampler::SHVkSampler(SHVkSampler&& rhs) noexcept
: vkSampler { rhs.vkSampler }
: vkSampler{ rhs.vkSampler }
, device{ rhs.device }
{
rhs.vkSampler = nullptr;
}
@ -56,6 +57,7 @@ namespace SHADE
SHADE::SHVkSampler& SHVkSampler::operator=(SHVkSampler&& rhs) noexcept
{
vkSampler = rhs.vkSampler;
device = rhs.device;
rhs.vkSampler = nullptr;
return *this;
}

View File

@ -144,27 +144,32 @@ namespace SHADE
// Initialize world render graph
worldRenderGraph->Init(device, swapchain);
worldRenderGraph->AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second);
worldRenderGraph->AddResource("Depth Buffer", SH_ATT_DESC_TYPE::DEPTH_STENCIL, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
worldRenderGraph->AddResource("Entity ID", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
worldRenderGraph->AddResource("Present", {SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT}, windowDims.first, windowDims.second);
worldRenderGraph->AddResource("Scene", {SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT}, windowDims.first, windowDims.second);
worldRenderGraph->AddResource("Depth Buffer", {SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL}, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
worldRenderGraph->AddResource("Entity ID", {SH_ATT_DESC_TYPE_FLAGS::COLOR}, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
//worldRenderGraph->AddResource("Position", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
//worldRenderGraph->AddResource("Normals", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
//worldRenderGraph->AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
//worldRenderGraph->AddResource("Scene", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eB8G8R8A8Unorm);
auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Present"}, {}); // no predecessors
auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene"}, {}); // no predecessors
//First subpass to write to G-Buffer
auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write");
gBufferWriteSubpass->AddColorOutput("Present");
gBufferWriteSubpass->AddColorOutput("Scene");
gBufferWriteSubpass->AddColorOutput("Entity ID");
gBufferWriteSubpass->AddDepthOutput ("Depth Buffer", SH_ATT_DESC_TYPE::DEPTH_STENCIL);
gBufferWriteSubpass->AddDepthOutput ("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL);
// We do this to just transition our scene layout to shader read
auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition");
sceneLayoutTransitionSubpass->AddInput("Scene");
// TODO: Use macro to add this node when SH_EDITOR is enabled
#ifdef SHEDITOR
auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {"G-Buffer"});
auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw");
imguiSubpass->AddColorOutput("Present");
#endif
worldRenderGraph->Generate();
@ -184,7 +189,6 @@ namespace SHADE
worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
worldRenderer->SetCamera(worldCamera);
// TODO: This is VERY temporarily here until a more solid resource management system is implemented
shaderSourceLibrary.Init("../../TempShaderFolder/");
@ -207,6 +211,10 @@ namespace SHADE
cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]);
mousePickSystem->Init(device, cmdPools, worldRenderGraph->GetRenderGraphResource("Entity ID"));
// Register the post offscreen render to the system
postOffscreenRender = resourceManager.Create<SHPostOffscreenRenderSystem>();
postOffscreenRender->Init(device, worldRenderGraph->GetRenderGraphResource("Scene"), descPool);
}
/***************************************************************************/
@ -551,6 +559,8 @@ namespace SHADE
worldRenderGraph->HandleResize(windowDims.first, windowDims.second);
mousePickSystem->HandleResize();
defaultViewport->SetWidth(static_cast<float>(windowDims.first));
defaultViewport->SetHeight(static_cast<float>(windowDims.second));

View File

@ -31,6 +31,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h"
#include "../Textures/SHTextureLibrary.h"
#include "../Textures/SHVkSamplerCache.h"
#include "Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h"
namespace SHADE
{
@ -262,14 +263,15 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/
/* Getters (Temporary) */
/*-----------------------------------------------------------------------------*/
Handle<SHVkLogicalDevice> GetDevice() const { return device; }
Handle<SHVkSwapchain> GetSwapchain() const { return swapchain; }
Handle<SHVkSurface> GetSurface() const { return surface; }
Handle<SHVkPhysicalDevice> GetPhysicalDevice() const { return physicalDevice; }
Handle<SHVkQueue> GetQueue() const { return graphicsQueue; }
Handle<SHVkDescriptorPool> GetDescriptorPool() const { return descPool; }
Handle<SHViewport> GetDefaultViewport() const {return defaultViewport;}
Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;};
Handle<SHVkLogicalDevice> GetDevice() const { return device; }
Handle<SHVkSwapchain> GetSwapchain() const { return swapchain; }
Handle<SHVkSurface> GetSurface() const { return surface; }
Handle<SHVkPhysicalDevice> GetPhysicalDevice() const { return physicalDevice; }
Handle<SHVkQueue> GetQueue() const { return graphicsQueue; }
Handle<SHVkDescriptorPool> GetDescriptorPool() const { return descPool; }
Handle<SHViewport> GetDefaultViewport() const {return defaultViewport;}
Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;};
Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;};
//SHRenderGraph const& GetRenderGraph(void) const noexcept;
//Handle<SHVkRenderpass> GetRenderPass() const { return renderPass; }
@ -327,5 +329,7 @@ namespace SHADE
// Sub systems
Handle<SHMousePickSystem> mousePickSystem;
Handle<SHPostOffscreenRenderSystem> postOffscreenRender;
};
}

View File

@ -9,8 +9,10 @@
namespace SHADE
{
void SHMousePickSystem::Init(Handle<SHVkLogicalDevice> logicalDevice, std::span<Handle<SHVkCommandPool>> cmdPools, Handle<SHRenderGraphResource> eidAttachment) noexcept
void SHMousePickSystem::Init(Handle<SHVkLogicalDevice> device, std::span<Handle<SHVkCommandPool>> cmdPools, Handle<SHRenderGraphResource> eidAttachment) noexcept
{
logicalDevice = device;
pickedEID = 0;
// Create command buffers
@ -22,13 +24,7 @@ namespace SHADE
// assign the attachment
entityIDAttachment = eidAttachment;
// Create the fence
afterCopyFence = logicalDevice->CreateFence();
uint32_t bufferSize = entityIDAttachment->GetWidth() * eidAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat());
// Create the buffer
imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
HandleResize();
}
void SHMousePickSystem::Run(Handle<SHVkQueue> queue, uint32_t frameIndex) noexcept
@ -63,6 +59,23 @@ namespace SHADE
}
}
void SHMousePickSystem::HandleResize(void) noexcept
{
if (afterCopyFence)
afterCopyFence.Free();
if (imageDataDstBuffer)
imageDataDstBuffer.Free();
// Create the fence
afterCopyFence = logicalDevice->CreateFence();
uint32_t bufferSize = entityIDAttachment->GetWidth() * entityIDAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat());
// Create the buffer
imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
}
EntityID SHMousePickSystem::GetPickedEntity(void) const noexcept
{
return pickedEID;

View File

@ -17,6 +17,8 @@ namespace SHADE
class SHMousePickSystem
{
private:
Handle<SHVkLogicalDevice> logicalDevice;
//! Handle to the render graph resource that will contain the entity IDs
Handle<SHRenderGraphResource> entityIDAttachment;
@ -35,8 +37,9 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
void Init(Handle<SHVkLogicalDevice> logicalDevice, std::span<Handle<SHVkCommandPool>> cmdPools, Handle<SHRenderGraphResource> eidAttachment) noexcept;
void Init(Handle<SHVkLogicalDevice> device, std::span<Handle<SHVkCommandPool>> cmdPools, Handle<SHRenderGraphResource> eidAttachment) noexcept;
void Run (Handle<SHVkQueue> queue, uint32_t frameIndex) noexcept;
void HandleResize (void) noexcept;
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */

View File

@ -0,0 +1,79 @@
#include "SHpch.h"
#include "SHPostOffscreenRenderSystem.h"
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/Images/SHVkSampler.h"
#include "Graphics/RenderGraph/SHRenderGraphResource.h"
namespace SHADE
{
/***************************************************************************/
/*!
\brief
This function basically creates the entities required for offscreen
rendering. It takes in a render graph resource. Side note: it creates
a descriptor set layout that is similar to the one created in imgui. This
is so that the descriptor set passed to imGui won't be invalid.
\param logicalDevice
For vulkan object creation
\param renderGraphResource
The resource in which has been
\param descriptorPool
\return
*/
/***************************************************************************/
void SHPostOffscreenRenderSystem::Init(Handle<SHVkLogicalDevice> logicalDevice, Handle<SHRenderGraphResource> renderGraphResource, Handle<SHVkDescriptorPool> descriptorPool) noexcept
{
offscreenRender = renderGraphResource;
// Create sampler
offscreenRenderSampler = logicalDevice->CreateSampler(
{
.minFilter = vk::Filter::eLinear,
.magFilter = vk::Filter::eLinear,
.addressMode = vk::SamplerAddressMode::eRepeat,
.mipmapMode = vk::SamplerMipmapMode::eLinear,
.minLod = -1000,
.maxLod = 1000
}
);
// Create descriptor set layout binding
SHVkDescriptorSetLayout::Binding imageBinding
{
.Type = vk::DescriptorType::eCombinedImageSampler,
.Stage = vk::ShaderStageFlagBits::eFragment,
.BindPoint = 0,
.DescriptorCount = 1,
};
// Create descriptor set layout
offscreenRenderDescSetLayout = logicalDevice->CreateDescriptorSetLayout(0, { imageBinding });
// Create descriptor set
offscreenRenderDescSet = descriptorPool->Allocate({ offscreenRenderDescSetLayout }, { 1 });
std::vector combinedImageSampler
{
std::make_tuple(renderGraphResource->GetImageView(), offscreenRenderSampler, vk::ImageLayout::eShaderReadOnlyOptimal),
};
// Register the image view and sampler with the descriptor set. Now whenever rendering to the offscreen image is done, the descriptor set will see the change
offscreenRenderDescSet->ModifyWriteDescImage(0, 0, combinedImageSampler);
offscreenRenderDescSet->UpdateDescriptorSetImages(0, 0);
}
Handle<SHVkDescriptorSetGroup> SHPostOffscreenRenderSystem::GetDescriptorSetGroup(void) const noexcept
{
return offscreenRenderDescSet;
}
}

View File

@ -0,0 +1,29 @@
#pragma once
#include "Resource/Handle.h"
namespace SHADE
{
class SHVkLogicalDevice;
class SHVkDescriptorSetLayout;
class SHVkDescriptorSetGroup;
class SHVkDescriptorPool;
class SHVkSampler;
class SHRenderGraphResource;
class SHPostOffscreenRenderSystem
{
private:
Handle<SHRenderGraphResource> offscreenRender;
Handle<SHVkDescriptorSetLayout> offscreenRenderDescSetLayout;
Handle<SHVkDescriptorSetGroup> offscreenRenderDescSet;
Handle<SHVkSampler> offscreenRenderSampler;
public:
void Init (Handle<SHVkLogicalDevice> logicalDevice, Handle<SHRenderGraphResource> renderGraphResource, Handle<SHVkDescriptorPool> descriptorPool) noexcept;
//void Run ()
Handle<SHVkDescriptorSetGroup> GetDescriptorSetGroup (void) const noexcept;
};
}

View File

@ -0,0 +1,7 @@
#include "SHpch.h"
#include "SHAttachmentDescInitParams.h"
namespace SHADE
{
}

View File

@ -0,0 +1,14 @@
#pragma once
#include "Resource/Handle.h"
namespace SHADE
{
class SHRenderGraphResource;
struct SHAttachmentDescInitParams
{
Handle<SHRenderGraphResource> resourceHdl;
bool dontClearOnLoad{false};
};
}

View File

@ -3,12 +3,13 @@
namespace SHADE
{
// Used for attachment description creation for renderpass node
enum class SH_ATT_DESC_TYPE
enum class SH_ATT_DESC_TYPE_FLAGS
{
COLOR,
COLOR_PRESENT,
DEPTH,
STENCIL,
DEPTH_STENCIL,
COLOR = 0x01,
COLOR_PRESENT = 0x02,
DEPTH = 0x04,
STENCIL = 0x08,
DEPTH_STENCIL = 0x10,
INPUT = 0x20
};
}

View File

@ -8,10 +8,17 @@
#include "Graphics/Framebuffer/SHVkFramebuffer.h"
#include "Graphics/Buffers/SHVkBuffer.h"
#include "Tools/SHLogger.h"
#include "SHAttachmentDescInitParams.h"
namespace SHADE
{
SHRenderGraph::ResourceInstruction::ResourceInstruction(char const* resourceName, bool dontClearOnLoad /*= false*/) noexcept
: resourceName{ resourceName }
, dontClearOnLoad{ dontClearOnLoad }
{
}
/***************************************************************************/
/*!
@ -40,7 +47,7 @@ namespace SHADE
*/
/***************************************************************************/
void SHRenderGraph::AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w /*= static_cast<uint32_t>(-1)*/, uint32_t h /*= static_cast<uint32_t>(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageUsageFlagBits usageFlags/* = {}*/, vk::ImageCreateFlagBits createFlags /*= {}*/)
void SHRenderGraph::AddResource(std::string resourceName, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, uint32_t w /*= static_cast<uint32_t>(-1)*/, uint32_t h /*= static_cast<uint32_t>(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageUsageFlagBits usageFlags/* = {}*/, vk::ImageCreateFlagBits createFlags /*= {}*/)
{
// If we set to
if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1))
@ -50,7 +57,7 @@ namespace SHADE
format = swapchainHdl->GetSurfaceFormatKHR().format;
}
graphResources.try_emplace(resourceName, resourceManager.Create<SHRenderGraphResource>(logicalDeviceHdl, swapchainHdl, resourceName, type, format, w, h, levels, usageFlags, createFlags));
graphResources.try_emplace(resourceName, resourceManager.Create<SHRenderGraphResource>(logicalDeviceHdl, swapchainHdl, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags));
}
/***************************************************************************/
@ -82,7 +89,7 @@ namespace SHADE
{
for (auto& color : subpass->colorReferences)
{
if (i == nodes.size() - 1 && node->attResources[color.attachment]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT)
if (i == nodes.size() - 1 && (node->attResources[color.attachment]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)))
resourceAttLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR;
else
resourceAttLayouts[color.attachment] = color.layout;
@ -210,10 +217,18 @@ namespace SHADE
for (auto& inputAtt : subpass->inputReferences)
{
auto resource = node->attResources[inputAtt.attachment];
if (resource->resourceType == SH_ATT_DESC_TYPE::COLOR || resource->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT)
colorRead |= (1 << i);
else if (resource->resourceType == SH_ATT_DESC_TYPE::DEPTH_STENCIL)
depthRead |= (1 << i);
if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::INPUT))
{
if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR) ||
resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT))
colorRead |= (1 << i);
else if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL))
depthRead |= (1 << i);
}
else
{
SHLOG_ERROR("While configuring subpass, an input reference was detected but the resource to be used is not marked as SH_ATT_DESC_TYPE_FLAGS::INPUT. ");
}
}
++i;
@ -400,7 +415,7 @@ namespace SHADE
*/
/***************************************************************************/
Handle<SHRenderGraphNode> SHRenderGraph::AddNode(std::string nodeName, std::initializer_list<std::string> resourceNames, std::initializer_list<std::string> predecessorNodes) noexcept
SHADE::Handle<SHADE::SHRenderGraphNode> SHRenderGraph::AddNode(std::string nodeName, std::initializer_list<ResourceInstruction> resourceInstruction, std::initializer_list<std::string> predecessorNodes) noexcept
{
if (nodeIndexing.contains(nodeName))
{
@ -408,12 +423,19 @@ namespace SHADE
return {};
}
std::vector<Handle<SHRenderGraphResource>> resources;
for (auto const& name : resourceNames)
std::vector<SHAttachmentDescInitParams> descInitParams;
for (auto const& instruction : resourceInstruction)
{
// If the resource that the new node is requesting for exists, allow the graph to reference it
if (graphResources.contains(name))
resources.push_back(graphResources.at(name));
if (graphResources.contains(instruction.resourceName))
{
descInitParams.push_back(
{
.resourceHdl = graphResources.at(instruction.resourceName),
.dontClearOnLoad = false,
}
);
}
else
{
SHLOG_ERROR("Resource doesn't exist in graph yet. Cannot create new node.");
@ -435,7 +457,7 @@ namespace SHADE
}
}
nodes.emplace_back(resourceManager.Create<SHRenderGraphNode>(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(resources), std::move(predecessors), &graphResources));
nodes.emplace_back(resourceManager.Create<SHRenderGraphNode>(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(descInitParams), std::move(predecessors), &graphResources));
nodeIndexing.emplace(nodeName, static_cast<uint32_t>(nodes.size()) - 1u);
return nodes.at(nodeIndexing[nodeName]);
}

View File

@ -33,7 +33,17 @@ namespace SHADE
class SH_API SHRenderGraph
{
public:
struct ResourceInstruction
{
std::string resourceName;
bool dontClearOnLoad;
ResourceInstruction (char const* resourceName, bool dontClearOnLoad = false) noexcept;
};
private:
/*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
@ -74,13 +84,14 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
void Init (Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain) noexcept;
void AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {});
Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<std::string> resourceNames, std::initializer_list<std::string> predecessorNodes) noexcept;
void Init (Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain) noexcept;
void AddResource(std::string resourceName, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {});
Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<ResourceInstruction> resourceInstruction, std::initializer_list<std::string> predecessorNodes) noexcept;
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 (uint32_t newWidth, uint32_t newHeight) noexcept;
void Execute (uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept;
void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept;
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */

View File

@ -42,7 +42,7 @@ namespace SHADE
for (uint32_t j = 0; j < attResources.size(); ++j)
{
uint32_t imageViewIndex = (attResources[j]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) ? i : 0;
uint32_t imageViewIndex = (attResources[j]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::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
@ -69,7 +69,7 @@ namespace SHADE
for (uint32_t j = 0; j < attResources.size(); ++j)
{
uint32_t imageViewIndex = (attResources[j]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) ? i : 0;
uint32_t imageViewIndex = (attResources[j]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::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
@ -104,14 +104,14 @@ namespace SHADE
*/
/***************************************************************************/
SHRenderGraphNode::SHRenderGraphNode(ResourceManager& rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<Handle<SHRenderGraphResource>> attRes, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
SHRenderGraphNode::SHRenderGraphNode(ResourceManager& rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
: logicalDeviceHdl{ logicalDevice }
, renderpass{}
, framebuffers{}
, prereqNodes{ std::move(predecessors) }
, attachmentDescriptions{}
, resourceAttachmentMapping{}
, attResources{ std::move(attRes) }
, attResources{ }
, subpasses{}
, executed{ false }
, configured{ false }
@ -121,6 +121,12 @@ namespace SHADE
// pipeline library initialization
pipelineLibrary.Init(logicalDeviceHdl);
// Store all the handles to resources
attResources.reserve (attDescInitParams.size());
for (auto& param : attDescInitParams)
attResources.push_back(param.resourceHdl);
// We have as many descriptions as we have resources
attachmentDescriptions.resize(attResources.size());
bool containsSwapchainImage = false;
@ -140,7 +146,7 @@ namespace SHADE
newDesc.format = attResources[i]->resourceFormat;
if (attResources[i]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT)
if (attResources[i]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT))
containsSwapchainImage = true;
resourceAttachmentMapping.try_emplace(attResources[i].GetId().Raw, i);

View File

@ -9,6 +9,7 @@
#include "SH_API.h"
#include "Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h"
#include "Graphics/MiddleEnd/Batching/SHBatcher.h"
#include "SHAttachmentDescInitParams.h"
namespace SHADE
{
@ -87,7 +88,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/
SHRenderGraphNode(ResourceManager& rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<Handle<SHRenderGraphResource>> attRes, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept;
SHRenderGraphNode(ResourceManager& rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept;
SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept;
SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept;

View File

@ -45,10 +45,10 @@ 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::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept
SHRenderGraphResource::SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept
: logicalDevice {logicalDevice}
, swapchain{ swapchain }
, resourceType{ type }
, resourceTypeFlags{ }
, resourceFormat{ format }
, images{}
, imageViews{}
@ -58,52 +58,10 @@ namespace SHADE
, resourceName{ name }
{
// If the resource type is an arbitrary image and not swapchain image
if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT)
if (typeFlags.size() == 1 && *typeFlags.begin() == SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)
{
imageAspectFlags = vk::ImageAspectFlags{};
usage = usageFlags;
resourceTypeFlags |= static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT);
// Check the resource type and set image usage flags and image aspect flags accordingly
switch (resourceType)
{
case SH_ATT_DESC_TYPE::COLOR:
usage |= vk::ImageUsageFlagBits::eColorAttachment;
imageAspectFlags |= vk::ImageAspectFlagBits::eColor;
break;
case SH_ATT_DESC_TYPE::DEPTH:
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
imageAspectFlags |= vk::ImageAspectFlagBits::eDepth;
break;
case SH_ATT_DESC_TYPE::STENCIL:
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
imageAspectFlags |= vk::ImageAspectFlagBits::eStencil;
break;
case SH_ATT_DESC_TYPE::DEPTH_STENCIL:
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
imageAspectFlags |= vk::ImageAspectFlagBits::eStencil | vk::ImageAspectFlagBits::eDepth;
break;
}
// The resource is not a swapchain image, just use the first slot of the vector
images.push_back(logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags));
// prepare image view details
SHImageViewDetails viewDetails
{
.viewType = vk::ImageViewType::e2D,
.format = images[0]->GetImageFormat(),
.imageAspectFlags = imageAspectFlags,
.baseMipLevel = 0,
.mipLevelCount = mipLevels,
.baseArrayLayer = 0,
.layerCount = 1,
};
// just 1 image view created
imageViews.push_back(images[0]->CreateImageView(logicalDevice, images[0], viewDetails));
}
else // if swapchain image resource
{
// Prepare image view details
SHImageViewDetails viewDetails
{
@ -126,6 +84,65 @@ namespace SHADE
imageViews[i] = images[i]->CreateImageView(logicalDevice, images[i], viewDetails);
}
}
else // if swapchain image resource
{
imageAspectFlags = vk::ImageAspectFlags{};
usage = usageFlags;
for (auto& type : typeFlags)
{
// store the flags
resourceTypeFlags |= static_cast<uint32_t>(type);
// Check the resource type and set image usage flags and image aspect flags accordingly
switch (type)
{
case SH_ATT_DESC_TYPE_FLAGS::COLOR:
usage |= vk::ImageUsageFlagBits::eColorAttachment;
imageAspectFlags |= vk::ImageAspectFlagBits::eColor;
break;
case SH_ATT_DESC_TYPE_FLAGS::DEPTH:
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
imageAspectFlags |= vk::ImageAspectFlagBits::eDepth;
break;
case SH_ATT_DESC_TYPE_FLAGS::STENCIL:
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
imageAspectFlags |= vk::ImageAspectFlagBits::eStencil;
break;
case SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL:
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
imageAspectFlags |= vk::ImageAspectFlagBits::eStencil | vk::ImageAspectFlagBits::eDepth;
break;
case SH_ATT_DESC_TYPE_FLAGS::INPUT:
usage |= vk::ImageUsageFlagBits::eInputAttachment;
usage |= vk::ImageUsageFlagBits::eSampled;
break;
case SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT:
{
SHLOG_ERROR ("COLOR_PRESENT cannot be with other resource type flags. ");
return;
}
}
}
// The resource is not a swapchain image, just use the first slot of the vector
images.push_back(logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags));
// prepare image view details
SHImageViewDetails viewDetails
{
.viewType = vk::ImageViewType::e2D,
.format = images[0]->GetImageFormat(),
.imageAspectFlags = imageAspectFlags,
.baseMipLevel = 0,
.mipLevelCount = mipLevels,
.baseArrayLayer = 0,
.layerCount = 1,
};
// just 1 image view created
imageViews.push_back(images[0]->CreateImageView(logicalDevice, images[0], viewDetails));
}
}
/***************************************************************************/
@ -141,7 +158,7 @@ namespace SHADE
/***************************************************************************/
SHRenderGraphResource::SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept
: resourceName{ std::move(rhs.resourceName) }
, resourceType{ std::move(rhs.resourceType) }
, resourceTypeFlags{ std::move(rhs.resourceTypeFlags) }
, images{ std::move(rhs.images) }
, imageViews{ std::move(rhs.imageViews) }
, resourceFormat{ std::move(rhs.resourceFormat) }
@ -149,6 +166,7 @@ namespace SHADE
, height{ rhs.height }
, mipLevels{ rhs.mipLevels }
, imageAspectFlags{ rhs.imageAspectFlags }
, swapchain {rhs.swapchain}
{
}
@ -172,7 +190,7 @@ namespace SHADE
return *this;
resourceName = std::move(rhs.resourceName);
resourceType = std::move(rhs.resourceType);
resourceTypeFlags = std::move(rhs.resourceTypeFlags);
images = std::move(rhs.images);
imageViews = std::move(rhs.imageViews);
resourceFormat = std::move(rhs.resourceFormat);
@ -180,6 +198,7 @@ namespace SHADE
height = rhs.height;
mipLevels = rhs.mipLevels;
imageAspectFlags = rhs.imageAspectFlags;
swapchain = rhs.swapchain;
return *this;
}
@ -202,7 +221,7 @@ namespace SHADE
width = newWidth;
height = newHeight;
if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT)
if ((resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) == 0)
{
// prepare image view details
SHImageViewDetails viewDetails
@ -299,4 +318,9 @@ namespace SHADE
return height;
}
Handle<SHVkImageView> SHRenderGraphResource::GetImageView(uint32_t index /*= NON_SWAPCHAIN_RESOURCE_INDEX*/) const noexcept
{
return imageViews [index];
}
}

View File

@ -16,6 +16,8 @@ namespace SHADE
class SHVkCommandBuffer;
class SHVkBuffer;
static constexpr uint32_t NON_SWAPCHAIN_RESOURCE_INDEX = 0;
class SH_API SHRenderGraphResource
{
private:
@ -32,7 +34,7 @@ namespace SHADE
std::string resourceName;
//! Used for initializing image layouts
SH_ATT_DESC_TYPE resourceType;
SHRenderGraphResourceFlags resourceTypeFlags;
//! The resource itself (this is a vector because if the resource happens
//! to be a swapchain image, then we need however many frames in flight).
@ -67,7 +69,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/
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::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept;
SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept;
SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept;
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
~SHRenderGraphResource(void) noexcept;
@ -82,9 +84,10 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/
vk::Format GetResourceFormat (void) const noexcept;
uint32_t GetWidth (void) const noexcept;
uint32_t GetHeight (void) const noexcept;
vk::Format GetResourceFormat (void) const noexcept;
uint32_t GetWidth (void) const noexcept;
uint32_t GetHeight (void) const noexcept;
Handle<SHVkImageView> GetImageView (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept;
friend class SHRenderGraphNode;
friend class SHRenderGraph;

View File

@ -120,18 +120,18 @@ namespace SHADE
*/
/***************************************************************************/
void SHSubpass::AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType) noexcept
void SHSubpass::AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType) noexcept
{
vk::ImageLayout imageLayout;
switch (attachmentDescriptionType)
{
case SH_ATT_DESC_TYPE::DEPTH:
case SH_ATT_DESC_TYPE_FLAGS::DEPTH:
imageLayout = vk::ImageLayout::eDepthAttachmentOptimal;
break;
case SH_ATT_DESC_TYPE::STENCIL:
case SH_ATT_DESC_TYPE_FLAGS::STENCIL:
imageLayout = vk::ImageLayout::eStencilAttachmentOptimal;
break;
case SH_ATT_DESC_TYPE::DEPTH_STENCIL:
case SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL:
imageLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
break;
default:

View File

@ -71,7 +71,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
// Preparation functions
void AddColorOutput(std::string resourceToReference) noexcept;
void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType = SH_ATT_DESC_TYPE::DEPTH_STENCIL) noexcept;
void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType = SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL) noexcept;
void AddInput(std::string resourceToReference) noexcept;
// Runtime functions

View File

@ -12,6 +12,7 @@ namespace SHADE
using BindingAndSetHash = uint64_t;
using SetIndex = uint32_t;
using SHSubPassIndex = uint32_t;
using SHRenderGraphResourceFlags = uint32_t;
}