From d7754e125dc3684bd97d6b77560569b713058f13 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 1 Jan 2023 12:02:51 +0800 Subject: [PATCH] Wrote remove resource for render graph (untested) --- SHADE_Engine/src/Events/SHEventDefines.h | 35 +-- .../src/Graphics/Events/SHGraphicsEvents.h | 14 ++ .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 79 +++++-- .../MiddleEnd/Interface/SHGraphicsSystem.h | 10 +- .../MiddleEnd/Lights/SHLightComponent.cpp | 17 ++ .../MiddleEnd/Lights/SHLightComponent.h | 4 +- .../Graphics/MiddleEnd/Lights/SHLightData.cpp | 6 + .../Graphics/MiddleEnd/Lights/SHLightData.h | 9 + .../Graphics/RenderGraph/SHRenderGraph.cpp | 189 +++++------------ .../src/Graphics/RenderGraph/SHRenderGraph.h | 51 ++++- .../RenderGraph/SHRenderGraphNode.cpp | 200 ++++++++++++++++++ .../Graphics/RenderGraph/SHRenderGraphNode.h | 4 +- .../src/Graphics/RenderGraph/SHSubpass.cpp | 144 ++++++++----- .../src/Graphics/RenderGraph/SHSubpass.h | 9 +- 14 files changed, 535 insertions(+), 236 deletions(-) create mode 100644 SHADE_Engine/src/Graphics/Events/SHGraphicsEvents.h diff --git a/SHADE_Engine/src/Events/SHEventDefines.h b/SHADE_Engine/src/Events/SHEventDefines.h index bdc4c505..8077fcc1 100644 --- a/SHADE_Engine/src/Events/SHEventDefines.h +++ b/SHADE_Engine/src/Events/SHEventDefines.h @@ -5,21 +5,22 @@ typedef uint32_t SHEventIdentifier; typedef uint32_t SHEventHandle; //Add your event identifiers here: -constexpr SHEventIdentifier SH_EXAMPLE_EVENT { 0 }; -constexpr SHEventIdentifier SH_ENTITY_DESTROYED_EVENT { 1 }; -constexpr SHEventIdentifier SH_ENTITY_CREATION_EVENT { 2 }; -constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT { 3 }; -constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 }; -constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 }; -constexpr SHEventIdentifier SH_SCENEGRAPH_ADD_CHILD_EVENT { 6 }; -constexpr SHEventIdentifier SH_SCENEGRAPH_REMOVE_CHILD_EVENT { 7 }; -constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 8 }; -constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 9 }; -constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 10 }; -constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 11 }; -constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 12 }; -constexpr SHEventIdentifier SH_SCENE_INIT_PRE { 13 }; -constexpr SHEventIdentifier SH_SCENE_INIT_POST { 14 }; -constexpr SHEventIdentifier SH_SCENE_EXIT_PRE { 15 }; -constexpr SHEventIdentifier SH_SCENE_EXIT_POST { 16 }; +constexpr SHEventIdentifier SH_EXAMPLE_EVENT { 0 }; +constexpr SHEventIdentifier SH_ENTITY_DESTROYED_EVENT { 1 }; +constexpr SHEventIdentifier SH_ENTITY_CREATION_EVENT { 2 }; +constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT { 3 }; +constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 }; +constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 }; +constexpr SHEventIdentifier SH_SCENEGRAPH_ADD_CHILD_EVENT { 6 }; +constexpr SHEventIdentifier SH_SCENEGRAPH_REMOVE_CHILD_EVENT { 7 }; +constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 8 }; +constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 9 }; +constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 10 }; +constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 11 }; +constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 12 }; +constexpr SHEventIdentifier SH_SCENE_INIT_PRE { 13 }; +constexpr SHEventIdentifier SH_SCENE_INIT_POST { 14 }; +constexpr SHEventIdentifier SH_SCENE_EXIT_PRE { 15 }; +constexpr SHEventIdentifier SH_SCENE_EXIT_POST { 16 }; +constexpr SHEventIdentifier SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT { 17 }; diff --git a/SHADE_Engine/src/Graphics/Events/SHGraphicsEvents.h b/SHADE_Engine/src/Graphics/Events/SHGraphicsEvents.h new file mode 100644 index 00000000..ab120a1f --- /dev/null +++ b/SHADE_Engine/src/Graphics/Events/SHGraphicsEvents.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include +#include "ECS_Base/SHECSMacros.h" + +namespace SHADE +{ + struct SHLightEnableShadowEvent + { + //! We need to get the light component and initialize the relevant variables. + EntityID lightEntity; + }; +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 6ac941f9..b1256921 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -183,34 +183,32 @@ namespace SHADE /*-----------------------------------------------------------------------*/ // Initialize world render graph renderGraph->Init("World Render Graph", device, swapchain, &resourceManager, renderContextCmdPools); - renderGraph->AddResource("Position", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); - renderGraph->AddResource("Normals", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); + renderGraph->AddResource("Position", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); + renderGraph->AddResource("Normals", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); //worldRenderGraph->AddResource("Tangents", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); - renderGraph->AddResource("Albedo", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second); - renderGraph->AddResource("Depth Buffer", { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); - renderGraph->AddResource("Entity ID", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); + renderGraph->AddResource("Albedo", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second); + renderGraph->AddResource("Depth Buffer", { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); + renderGraph->AddResource("Entity ID", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); renderGraph->AddResource("Light Layer Indices", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); - renderGraph->AddResource("Scene", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, windowDims.first, windowDims.second); + renderGraph->AddResource("Scene", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, windowDims.first, windowDims.second); renderGraph->AddResource("SSAO", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm); renderGraph->AddResource("SSAO Blur", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm); renderGraph->AddResource("Present", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second); - /*-----------------------------------------------------------------------*/ /* MAIN NODE */ /*-----------------------------------------------------------------------*/ - auto gBufferNode = renderGraph->AddNode("G-Buffer", + auto gBufferNode = renderGraph->AddNode("G-Buffer", { - "Position", - "Entity ID", + "Position", + "Entity ID", "Light Layer Indices", "Normals", "Albedo", - "Depth Buffer", - "Scene", + "Depth Buffer", "SSAO", "SSAO Blur" - }, + }, {}); // no predecessors /*-----------------------------------------------------------------------*/ @@ -251,23 +249,46 @@ namespace SHADE auto viewSamplerLayout = ssaoStorage->GetViewSamplerLayout(); ssaoPass->ModifyWriteDescImageComputeResource(SHSSAO::DESC_SET_IMAGE_BINDING, { &viewSamplerLayout, 1 }); - ssaoPass->SetRenderer (worldRenderer); + ssaoPass->SetRenderer(worldRenderer); // Add another pass to blur SSAO Handle ssaoBlurPass = gBufferNode->AddNodeCompute("SSAO Blur Step", ssaoBlurShader, { "SSAO", "SSAO Blur" }); + /*-----------------------------------------------------------------------*/ + /* SHADOW MAP PASS */ + /*-----------------------------------------------------------------------*/ + // Shadow map pass will have no resources bound at first. Lighting system will add resources to the node. + // It will initially also not have any subpasses since they will be added for each light that casts shadows. + //auto shadowMapPass = renderGraph->AddNode("Shadow Map Pass", {}, {}); + + + + /*-----------------------------------------------------------------------*/ + /* DEFERRED COMPOSITE NODE */ + /*-----------------------------------------------------------------------*/ + // This pass will facilitate both lighting and shadows in 1 single pass. + auto deferredCompositeNode = renderGraph->AddNode("Deferred Comp Pass", + { + "Position", + "Light Layer Indices", + "Normals", + "Albedo", + "Scene", + "SSAO Blur" + }, + {"G-Buffer"}); + /*-----------------------------------------------------------------------*/ /* DEFERRED COMPOSITE SUBPASS INIT */ /*-----------------------------------------------------------------------*/ - gBufferNode->AddNodeCompute("Deferred Composite", deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene" }); - + deferredCompositeNode->AddNodeCompute("Deferred Composite", deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene" }); /*-----------------------------------------------------------------------*/ /* DEBUG DRAW PASS INIT */ /*-----------------------------------------------------------------------*/ // Set up Debug Draw Passes // - Depth Tested - auto debugDrawNodeDepth = renderGraph->AddNode("Debug Draw with Depth", { "Scene", "Depth Buffer" }, {"G-Buffer"}); + auto debugDrawNodeDepth = renderGraph->AddNode("Debug Draw with Depth", { "Scene", "Depth Buffer" }, {"G-Buffer", "Deferred Comp Pass"}); auto debugDrawDepthSubpass = debugDrawNodeDepth->AddSubpass("Debug Draw with Depth", worldViewport, worldRenderer); debugDrawDepthSubpass->AddColorOutput("Scene"); debugDrawDepthSubpass->AddDepthOutput("Depth Buffer"); @@ -279,7 +300,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* SCREEN SPACE PASS */ /*-----------------------------------------------------------------------*/ - auto screenSpaceNode = renderGraph->AddNode("Screen Space Pass", { "Scene", "Entity ID" }, {"G-Buffer", "Debug Draw" }); + auto screenSpaceNode = renderGraph->AddNode("Screen Space Pass", { "Scene", "Entity ID" }, {"Deferred Comp Pass", "G-Buffer", "Debug Draw" }); auto uiSubpass = screenSpaceNode->AddSubpass("UI", worldViewport, screenRenderer); uiSubpass->AddColorOutput("Scene"); uiSubpass->AddColorOutput("Entity ID"); @@ -410,6 +431,16 @@ namespace SHADE } + void SHGraphicsSystem::InitEvents(void) noexcept + { + std::shared_ptr> thisReceiver + { + std::make_shared>(this, &SHGraphicsSystem::ReceiveLightEnableShadowEvent) + }; + ReceiverPtr receiver = std::dynamic_pointer_cast(thisReceiver); + SHEventManager::SubscribeTo(SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT, receiver); + } + /*---------------------------------------------------------------------------------*/ /* Constructor/Destructors */ /*---------------------------------------------------------------------------------*/ @@ -694,6 +725,18 @@ namespace SHADE renderers.erase(iter); } + SHEventHandle SHGraphicsSystem::ReceiveLightEnableShadowEvent(SHEventPtr event) noexcept + { + // Add the shadow map resource to the graph + + // link resource to node. This means linking the resource and regenerating the node's renderpass and framebuffer. + + // Add a subpass to render to that shadow map + + //renderGraph->GetNode (); + return event->handle; + } + Handle SHGraphicsSystem::AddMaterial(Handle vertShader, Handle fragShader, Handle subpass) { // Retrieve pipeline from pipeline storage or create if unavailable diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 945db2d9..40148e05 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -35,6 +35,7 @@ of DigiPen Institute of Technology is prohibited. #include "Camera/SHCameraDirector.h" #include "Graphics/MiddleEnd/TextRendering/SHFontLibrary.h" #include "Graphics/MiddleEnd/Interface/SHRenderer.h" +#include "Graphics/Events/SHGraphicsEvents.h" namespace SHADE { @@ -102,10 +103,7 @@ namespace SHADE void InitMiddleEnd (void) noexcept; void InitSubsystems (void) noexcept; void InitBuiltInResources (void); - -#ifdef SHEDITOR - void InitEditorRenderGraph (void) noexcept; -#endif + void InitEvents (void) noexcept; public: class SH_API BeginRoutine final : public SHSystemRoutine @@ -176,6 +174,10 @@ namespace SHADE Handle AddRenderer(SHRenderer::PROJECTION_TYPE projectionType); void RemoveRenderer(Handle renderer); + /*-----------------------------------------------------------------------*/ + /* Light functions */ + /*-----------------------------------------------------------------------*/ + SHEventHandle ReceiveLightEnableShadowEvent (SHEventPtr event) noexcept; /*-----------------------------------------------------------------------------*/ /* Material Functions */ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp index 2ea6bc8b..362b0e8f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp @@ -1,5 +1,7 @@ #include "SHpch.h" #include "SHLightComponent.h" +#include "Graphics/Events/SHGraphicsEvents.h" +#include "Events/SHEventManager.hpp" namespace SHADE { @@ -104,6 +106,21 @@ namespace SHADE //MakeDirty(); } + void SHLightComponent::SetEnableShadow(bool flag) noexcept + { + lightData.castShadows = flag; + + // If the flag is true + if (flag && lightData.shadowMapIndex == SHLightData::INVALID_SHADOW_MAP_INDEX) + { + // Create new event and broadcast it + SHLightEnableShadowEvent newEvent; + newEvent.lightEntity = GetEID(); + + SHEventManager::BroadcastEvent(newEvent, SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT); + } + } + SHLightData const& SHLightComponent::GetLightData(void) const noexcept { return lightData; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h index 6b35559c..1d636595 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h @@ -25,7 +25,6 @@ namespace SHADE ////! If the light's data is already in the buffers, this will be set to true. //bool bound; - public: /*-----------------------------------------------------------------------*/ /* LIFECYCLE FUNCTIONS */ @@ -49,6 +48,7 @@ namespace SHADE //void Unbind (void) noexcept; //void SetBound (uint32_t inIndexInBuffer) noexcept; void SetStrength (float value) noexcept; // serialized + void SetEnableShadow (bool flag) noexcept; SHLightData const& GetLightData (void) const noexcept; @@ -59,7 +59,7 @@ namespace SHADE uint32_t const& GetCullingMask (void) const noexcept; // serialized //bool IsDirty (void) const noexcept; //bool GetBound (void) const noexcept; - uint32_t GetIndexInBuffer (void) const noexcept; + //uint32_t GetIndexInBuffer (void) const noexcept; float GetStrength (void) const noexcept; RTTR_ENABLE() }; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.cpp index 8e8f0783..f51fdfa7 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.cpp @@ -16,6 +16,12 @@ namespace SHADE // Diffuse color set to 1 color = SHVec4::One; + + // light will default not cast shadows + castShadows = false; + + // shadow map index is invalid. + shadowMapIndex = INVALID_SHADOW_MAP_INDEX; } } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.h b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.h index e9a02c1a..4d62700d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.h @@ -26,6 +26,8 @@ namespace SHADE /***************************************************************************/ struct SHLightData { + static constexpr uint32_t INVALID_SHADOW_MAP_INDEX = std::numeric_limits::max(); + //! position of the light SHVec3 position; @@ -46,6 +48,13 @@ namespace SHADE //! Strength of the light float strength; + //! Whether or not the light will cast a shadow. More technically, whether or + //! not the light will result in the addition of a depth map into the render graph + //! to be used for shadow mapping calculations. + bool castShadows; + + //! Index of the shadow map when it gets placed in the descriptor array of textures (that are all shadow maps). + uint32_t shadowMapIndex; void Reset (void) noexcept; //! TODO: diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 67cc9112..74371a64 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -68,6 +68,56 @@ namespace SHADE renderGraphStorage->graphResources->try_emplace(resourceName, resource); } + + void SHRenderGraph::RemoveResource(std::string resourceName) noexcept + { + // 1. Check if nodes are using said attachment and remove if they are + // - Check subpasses while at it and remove as well if used as attachment + // 2. Regenerate graph + // - Delete all vulkan objects first as well and clear the necessary containers + + if (!renderGraphStorage->graphResources->contains(resourceName)) + return; + + renderGraphStorage->logicalDevice->WaitIdle(); + + uint64_t handleID = renderGraphStorage->graphResources->at (resourceName).GetId().Raw; + + // Record nodes that will be affected + std::vector affectedNodes{}; + + // Detach resource from all nodes if applicable + for (uint32_t i = 0; i < nodes.size(); ++i) + { + if (nodes[i]->DetachResource(resourceName, handleID)) + affectedNodes.emplace_back(i); + } + + // Up to this point the nodes and subpasses should have no trace of the deleted resource. Attachment + // descriptions and subpass indices should also have been reconfigured at this point. However, this + // means that the subpass descriptions and subpass dependencies need to be reconfigured. + + // configure subpass dependencies and descriptions. + for (auto& affectedNode : affectedNodes) + nodes[affectedNode]->ConfigureSubpasses(); + + for (auto& affectedNode : affectedNodes) + nodes[affectedNode]->CreateRenderpass(); + + for (auto& affectedNode : affectedNodes) + nodes[affectedNode]->CreateFramebuffer(); + /* + * IMPORTANT NOTES + * + * This remove resource function would be more complete if it accounted for renderpass compatibility by + * recreating the graphics pipelines stored in render graph nodes. However due to time constraints, this is left out. As such, + * pipelines that are recreated with a certain renderpass and subpass will assumed to be compatible when used in different subpasses. + * + * This function also recreates renderpasses and framebuffers so it does not account for removing of resources that are used in nodes whose + * renderpasses and framebuffers are used externally in systems like Editor with ImGui. + */ + } + void SHRenderGraph::LinkNonOwningResource(Handle resourceOrigin, std::string resourceName) noexcept { // resource to link @@ -236,140 +286,12 @@ namespace SHADE */ /***************************************************************************/ - void SHRenderGraph::ConfigureSubpasses(void) noexcept + void SHRenderGraph::ConfigureAllSubpasses(void) noexcept { // For all nodes for (auto& node : nodes) { - // Create subpass description and dependencies based on number of subpasses - node->spDescs.resize(node->subpasses.size()); - node->spDeps.resize(node->subpasses.size()); - - // Now we want to loop through all attachments in all subpasses in the node and query - // the resources being used. For each resource we want to query the type and record it - // in bit fields (1 bit for each subpass). - uint32_t colorRead = 0, colorWrite = 0, depthRead = 0, depthWrite = 0, inputDependencies = 0; - - uint32_t i = 0; - - // For all subpasses (see above description about bit field for this). - for (auto& subpass : node->subpasses) - { - // Configure subpass description - auto& desc = node->spDescs[i]; - desc.pColorAttachments = subpass->colorReferences.data(); - desc.colorAttachmentCount = static_cast(subpass->colorReferences.size()); - desc.pInputAttachments = subpass->inputReferences.data(); - desc.inputAttachmentCount = static_cast(subpass->inputReferences.size()); - desc.pDepthStencilAttachment = subpass->depthReferences.data(); - desc.pipelineBindPoint = vk::PipelineBindPoint::eGraphics; // TODO: Just graphics for now. See if its possible to allow user defined params. - - // Get reference to subpass description - auto& dep = node->spDeps[i]; - - // Configure subpass index for dependencies - dep.srcSubpass = (i == 0) ? VK_SUBPASS_EXTERNAL : i - 1; - dep.dstSubpass = i; - - // First we want to see if the subpass has color, depth or input attachments and set bit field accordingly - if (subpass->colorReferences.size()) - { - colorRead |= (1 << i); - colorWrite |= (1 << i); - } - - // Same thing for depth - if (subpass->depthReferences.size()) - { - depthRead |= (1 << i); - depthWrite |= (1 << i); - } - if (subpass->inputReferences.size()) - inputDependencies |= (1 << i); - - // Input attachments can be any type, so we need to check what type it is - for (auto& inputAtt : subpass->inputReferences) - { - auto resource = node->attResources[inputAtt.attachment]; - if (resource->resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT)) - { - if (resource->resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR) || - resource->resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) - colorRead |= (1 << i); - else if (resource->resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_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; - } - - // Loop through all subpasses again but this time we use the bit field to initialize - // the dependencies. - for (i = 0; i < node->subpasses.size(); ++i) - { - vk::PipelineStageFlags srcStage; - vk::PipelineStageFlags dstStage; - vk::AccessFlags srcAccess; - vk::AccessFlags dstAccess; - auto& dep = node->spDeps[i]; - - if (colorRead & (1 << i)) - { - srcStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput; - dstStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput; - srcAccess |= vk::AccessFlagBits::eColorAttachmentWrite; - dstAccess |= vk::AccessFlagBits::eColorAttachmentRead; - } - if (colorWrite & (1 << i)) - { - srcStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput; - dstStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput; - srcAccess |= vk::AccessFlagBits::eColorAttachmentWrite; - dstAccess |= vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead; - } - if (depthRead & (1 << i)) - { - srcStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests; - dstStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests; - srcAccess |= vk::AccessFlagBits::eDepthStencilAttachmentWrite; - dstAccess |= vk::AccessFlagBits::eDepthStencilAttachmentRead; - } - if (depthWrite & (1 << i)) - { - srcStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests; - dstStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests; - srcAccess |= vk::AccessFlagBits::eDepthStencilAttachmentWrite; - dstAccess |= vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite; - } - if (inputDependencies & (1 << i)) - { - dstStage |= vk::PipelineStageFlagBits::eFragmentShader; - dstAccess |= vk::AccessFlagBits::eInputAttachmentRead; - } - - //// If subpass of first renderpass, stage flag should be bottom of pipe - //if (&node == &nodes.front() && i == 0) - // srcStage = vk::PipelineStageFlagBits::eBottomOfPipe; - - //// If subpass of last renderpass, stage flag should be bottom of pipe - //if (&node == &nodes.back() && i == node->subpasses.size() - 1) - // dstStage = vk::PipelineStageFlagBits::eTopOfPipe; - - dep.srcStageMask = srcStage; - dep.dstStageMask = dstStage; - dep.srcAccessMask = srcAccess; - dep.dstAccessMask = dstAccess; - - dep.srcStageMask = srcStage; - - // initialize input descriptors - node->subpasses[i]->CreateInputDescriptors(); - } + node->ConfigureSubpasses(); } } @@ -604,12 +526,17 @@ namespace SHADE { CheckForNodeComputes(); ConfigureAttachmentDescriptions(); - ConfigureSubpasses(); + ConfigureAllSubpasses(); ConfigureRenderpasses(); ConfigureFramebuffers(); ConfigureSubSystems(); } + void SHRenderGraph::Regenerate(void) noexcept + { + + } + /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index 948fd9f7..c7fe221b 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -51,7 +51,7 @@ namespace SHADE /* PRIVATE MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ void ConfigureAttachmentDescriptions (void) noexcept; - void ConfigureSubpasses (void) noexcept; + void ConfigureAllSubpasses (void) noexcept; void ConfigureRenderpasses (void) noexcept; void ConfigureSubSystems (void) noexcept; void ConfigureFramebuffers (void) noexcept; @@ -89,13 +89,52 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ - void Init (std::string graphName, Handle logicalDevice, Handle swapchain, SHResourceHub* resourceHub, std::vector>& cmdPools) noexcept; - void AddResource(std::string resourceName, std::initializer_list typeFlags, uint32_t w = static_cast(-1), uint32_t h = static_cast(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {}); - void LinkNonOwningResource (Handle resourceOrigin, std::string resourceName) noexcept; - Handle AddNode (std::string nodeName, std::initializer_list resourceInstruction, std::initializer_list predecessorNodes) noexcept; - void AddRenderToSwapchainNode (std::string toSwapchainResource, std::string swapchainResource, std::initializer_list predecessorNodes, std::pair, Handle> shaderModules) noexcept; + void Init + ( + std::string graphName, + Handle logicalDevice, + Handle swapchain, SHResourceHub* resourceHub, + std::vector>& cmdPools + ) noexcept; + + void AddResource + ( + std::string resourceName, + std::initializer_list typeFlags, + uint32_t w = static_cast(-1), + uint32_t h = static_cast(-1), + vk::Format format = vk::Format::eB8G8R8A8Unorm, + uint8_t levels = 1, + vk::ImageUsageFlagBits usageFlags = {}, + vk::ImageCreateFlagBits createFlags = {} + ); + + void RemoveResource (std::string resourceName) noexcept; + + void LinkNonOwningResource + ( + Handle resourceOrigin, + std::string resourceName + ) noexcept; + + Handle AddNode + ( + std::string nodeName, + std::initializer_list resourceInstruction, + std::initializer_list predecessorNodes + ) noexcept; + + void AddRenderToSwapchainNode + ( + std::string toSwapchainResource, + std::string swapchainResource, + std::initializer_list predecessorNodes, + std::pair, + Handle> shaderModules + ) noexcept; void Generate (void) noexcept; + void Regenerate (void) noexcept; void CheckForNodeComputes (void) noexcept; void Execute (uint32_t frameIndex, Handle descPool) noexcept; void Begin (uint32_t frameIndex) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index b8185176..3c412645 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -26,6 +26,12 @@ namespace SHADE /***************************************************************************/ void SHRenderGraphNode::CreateRenderpass(void) noexcept { + if (renderpass) + { + if (renderpass) + renderpass.Free(); + } + renderpass = graphStorage->logicalDevice->CreateRenderpass(attachmentDescriptions, spDescs, spDeps); SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eRenderPass, renderpass->GetVkRenderpass(), "[RenderPass] " + name); } @@ -40,6 +46,15 @@ namespace SHADE /***************************************************************************/ void SHRenderGraphNode::CreateFramebuffer(void) noexcept { + if (!framebuffers.empty()) + { + for (auto fbo : framebuffers) + { + if (fbo) + fbo.Free(); + } + } + for (uint32_t i = 0; i < framebuffers.size(); ++i) { std::vector> imageViews(attResources.size()); @@ -100,6 +115,139 @@ namespace SHADE } } + void SHRenderGraphNode::ConfigureSubpasses(void) noexcept + { + // Create subpass description and dependencies based on number of subpasses + spDescs.resize(subpasses.size()); + spDeps.resize(subpasses.size()); + + // Now we want to loop through all attachments in all subpasses in the node and query + // the resources being used. For each resource we want to query the type and record it + // in bit fields (1 bit for each subpass). + uint32_t colorRead = 0, colorWrite = 0, depthRead = 0, depthWrite = 0, inputDependencies = 0; + + uint32_t i = 0; + + // For all subpasses (see above description about bit field for this). + for (auto& subpass : subpasses) + { + // Configure subpass description + auto& desc = spDescs[i]; + desc.pColorAttachments = subpass->colorReferences.data(); + desc.colorAttachmentCount = static_cast(subpass->colorReferences.size()); + desc.pInputAttachments = subpass->inputReferences.data(); + desc.inputAttachmentCount = static_cast(subpass->inputReferences.size()); + desc.pDepthStencilAttachment = subpass->depthReferences.data(); + desc.pipelineBindPoint = vk::PipelineBindPoint::eGraphics; // TODO: Just graphics for now. See if its possible to allow user defined params. + + // Get reference to subpass description + auto& dep = spDeps[i]; + + // Configure subpass index for dependencies + dep.srcSubpass = (i == 0) ? VK_SUBPASS_EXTERNAL : i - 1; + dep.dstSubpass = i; + + // First we want to see if the subpass has color, depth or input attachments and set bit field accordingly + if (subpass->colorReferences.size()) + { + colorRead |= (1 << i); + colorWrite |= (1 << i); + } + + // Same thing for depth + if (subpass->depthReferences.size()) + { + depthRead |= (1 << i); + depthWrite |= (1 << i); + } + if (subpass->inputReferences.size()) + inputDependencies |= (1 << i); + + // Input attachments can be any type, so we need to check what type it is + for (auto& inputAtt : subpass->inputReferences) + { + auto resource = attResources[inputAtt.attachment]; + if (resource->resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT)) + { + if (resource->resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR) || + resource->resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) + colorRead |= (1 << i); + else if (resource->resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_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; + } + + // Loop through all subpasses again but this time we use the bit field to initialize + // the dependencies. + for (i = 0; i < subpasses.size(); ++i) + { + vk::PipelineStageFlags srcStage; + vk::PipelineStageFlags dstStage; + vk::AccessFlags srcAccess; + vk::AccessFlags dstAccess; + auto& dep = spDeps[i]; + + if (colorRead & (1 << i)) + { + srcStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput; + dstStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput; + srcAccess |= vk::AccessFlagBits::eColorAttachmentWrite; + dstAccess |= vk::AccessFlagBits::eColorAttachmentRead; + } + if (colorWrite & (1 << i)) + { + srcStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput; + dstStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput; + srcAccess |= vk::AccessFlagBits::eColorAttachmentWrite; + dstAccess |= vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead; + } + if (depthRead & (1 << i)) + { + srcStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests; + dstStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests; + srcAccess |= vk::AccessFlagBits::eDepthStencilAttachmentWrite; + dstAccess |= vk::AccessFlagBits::eDepthStencilAttachmentRead; + } + if (depthWrite & (1 << i)) + { + srcStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests; + dstStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests; + srcAccess |= vk::AccessFlagBits::eDepthStencilAttachmentWrite; + dstAccess |= vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite; + } + if (inputDependencies & (1 << i)) + { + dstStage |= vk::PipelineStageFlagBits::eFragmentShader; + dstAccess |= vk::AccessFlagBits::eInputAttachmentRead; + } + + //// If subpass of first renderpass, stage flag should be bottom of pipe + //if (&node == &nodes.front() && i == 0) + // srcStage = vk::PipelineStageFlagBits::eBottomOfPipe; + + //// If subpass of last renderpass, stage flag should be bottom of pipe + //if (&node == &nodes.back() && i == subpasses.size() - 1) + // dstStage = vk::PipelineStageFlagBits::eTopOfPipe; + + dep.srcStageMask = srcStage; + dep.dstStageMask = dstStage; + dep.srcAccessMask = srcAccess; + dep.dstAccessMask = dstAccess; + + dep.srcStageMask = srcStage; + + // initialize input descriptors + subpasses[i]->CreateInputDescriptors(); + } + } + /***************************************************************************/ /*! @@ -335,6 +483,58 @@ namespace SHADE } } + /***************************************************************************/ + /*! + + \brief + For detaching attachments from the node. The node would need to be + rebuilt but it won't be done in this function. This function just removes + any footprint of the resource in the class. + + \param resourceHandleID + The handle ID of the resource. + + */ + /***************************************************************************/ + bool SHRenderGraphNode::DetachResource(std::string const& resourceName, uint64_t resourceHandleID) noexcept + { + if (resourceAttachmentMapping->contains(resourceHandleID)) + { + // Get attachment index in the node's attachment container + auto index = resourceAttachmentMapping->at(resourceHandleID); + + // remove attachment from the list of attachments + attResources.erase (attResources.begin() + index); + + // remove attachment reference + attachmentDescriptions.erase (attachmentDescriptions.begin() + index); + + // Remove footprint of attachment from all subpasses as well + for (auto it = subpasses.begin(); it != subpasses.end(); ++it) + { + // attempt to detach resource from subpass + (*it)->DetachResource(resourceName, index); + + // If the subpass ends up having no attachments after, erase it from the node + if ((*it)->HasNoAttachments()) + { + // erase from indexing + subpassIndexing.erase((*it)->GetName()); + + // erase from container of subpasses. + it = subpasses.erase(it); + } + } + + // give existing subpasses new indices + for (uint32_t i = 0; i < subpasses.size(); ++i) + subpasses[i]->SetIndex(i); + + return true; + } + return false; + } + void SHRenderGraphNode::Execute(Handle commandBuffer, Handle descPool, uint32_t frameIndex) noexcept { uint32_t framebufferIndex = (framebuffers.size() > 1) ? frameIndex : 0; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index ebaf48e2..a581d21c 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -55,7 +55,7 @@ namespace SHADE //! Vector of subpasses std::vector> subpasses; - //! Descriptions to pass to renderpass for renderpass creation. We want to keep this here because + //! Descriptions to pass to renderpass for renderpass creation. std::vector spDescs; //! Subpass dependencies for renderpass creation @@ -92,6 +92,7 @@ namespace SHADE void CreateRenderpass(void) noexcept; void CreateFramebuffer(void) noexcept; void HandleResize (void) noexcept; + void ConfigureSubpasses (void) noexcept; public: /*-----------------------------------------------------------------------*/ @@ -107,6 +108,7 @@ namespace SHADE Handle AddSubpass(std::string subpassName, Handle viewport, Handle renderer) noexcept; Handle AddNodeCompute(std::string nodeName, Handle computeShaderModule, std::initializer_list resources, std::unordered_set&& dynamicBufferBindings = {}, float numWorkGroupScale = 1.0f) noexcept; void AddDummySubpassIfNeeded (void) noexcept; + bool DetachResource (std::string const& resourceName, uint64_t resourceHandleID) noexcept; // TODO: RemoveSubpass() void Execute(Handle commandBuffer, Handle descPool, uint32_t frameIndex) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index 88d375ce..3d2b1699 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -68,7 +68,6 @@ namespace SHADE , depthReferences{ std::move(rhs.depthReferences) } , inputReferences{ std::move(rhs.inputReferences) } , resourceAttachmentMapping{ rhs.resourceAttachmentMapping } - , descriptorSetLayout{ rhs.descriptorSetLayout } , exteriorDrawCalls{ std::move(rhs.exteriorDrawCalls) } , graphStorage{ rhs.graphStorage } , inputNames{ std::move(rhs.inputNames) } @@ -105,7 +104,6 @@ namespace SHADE depthReferences = std::move(rhs.depthReferences); inputReferences = std::move(rhs.inputReferences); resourceAttachmentMapping = std::move(rhs.resourceAttachmentMapping); - descriptorSetLayout = rhs.descriptorSetLayout; exteriorDrawCalls = std::move(rhs.exteriorDrawCalls); graphStorage = rhs.graphStorage; inputNames = std::move(rhs.inputNames); @@ -253,6 +251,64 @@ namespace SHADE } } + /***************************************************************************/ + /*! + + \brief + Removes all footprints of a resource in the subpass. + + \param resourceName + Name of resource. + + \param attachmentIndex + index of attachment. + + */ + /***************************************************************************/ + void SHSubpass::DetachResource(std::string const& resourceName, uint32_t attachmentIndex) noexcept + { + for (uint32_t i = 0; i < colorReferences.size(); ++i) + { + if (colorReferences[i].attachment == attachmentIndex) + { + colorReferences.erase (colorReferences.begin() + i); + break; + } + } + + for (uint32_t i = 0; i < depthReferences.size(); ++i) + { + if (depthReferences[i].attachment == attachmentIndex) + { + depthReferences.erase(depthReferences.begin() + i); + break; + } + } + + for (uint32_t i = 0; i < inputReferences.size(); ++i) + { + if (inputReferences[i].attachment == attachmentIndex) + { + inputReferences.erase(inputReferences.begin() + i); + break; + } + } + + for (uint32_t i = 0; i < inputNames.size(); ++i) + { + if (inputNames[i] == resourceName) + { + inputNames.erase(inputNames.begin() + i); + break; + } + } + } + + bool SHSubpass::HasNoAttachments(void) const noexcept + { + return colorReferences.empty() && depthReferences.empty() && inputReferences.empty(); + } + void SHSubpass::AddExteriorDrawCalls(ExteriorDrawCallFunction const& newDrawCall) noexcept { exteriorDrawCalls.push_back(newDrawCall); @@ -269,6 +325,21 @@ namespace SHADE if (inputNames.empty()) return; + for (auto& set : inputImageDescriptorSets) + { + if (set) + set.Free(); + } + + if (inputDescriptorLayout) + inputDescriptorLayout.Free(); + + for (auto& sampler : inputSamplers) + { + if (sampler) + sampler.Free(); + } + inputImageDescriptorSets.resize(SHGraphicsConstants::NUM_FRAME_BUFFERS); std::vector bindings{}; @@ -369,58 +440,23 @@ namespace SHADE } } - //void SHSubpass::InitComputeBarriers(void) noexcept - //{ - // std::unordered_set handleBarriers{}; - - // // we will have swapchainNumImages vectors of vector of barriers - // subpassComputeBarriers.resize(graphStorage->swapchain->GetNumImages()); - - // for (auto sbCompute : subpassComputes) - // { - // // for every resource the subpass compute is using - // for (auto resource : sbCompute->resources) - // { - // // Get the resource handle - // uint64_t resourceRaw = resource.GetId().Raw; - - // // if the barrier is not registered - // if (!handleBarriers.contains(resourceRaw)) - // { - // // If the resource is a swapchain image - // bool isSwapchainImage = (resource->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)); - // for (uint32_t i = 0; i < graphStorage->swapchain->GetNumImages(); ++i) - // { - // // if swapchain image, we want the index of the swapchain image, if not take base image - // uint32_t imageIndex = isSwapchainImage ? i : 0; - - // // Prepare image barrier - // vk::ImageMemoryBarrier imageBarrier - // { - // .oldLayout = colorReferences[resourceAttachmentMapping->at(resource.GetId().Raw)].layout, - // .newLayout = vk::ImageLayout::eGeneral, - // .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - // .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - // .image = resource->GetImage(imageIndex)->GetVkImage(), - // .subresourceRange = - // { - // .aspectMask = resource->imageAspectFlags, - // .levelCount = resource->GetMipLevels(), - // .baseArrayLayer = 0, - // .layerCount = 1 - // } - // }; - - // // push the barrier - // subpassComputeBarriers[i].push_back(imageBarrier); - // } - - // // Image transition registered - // handleBarriers.emplace(resourceRaw); - // } - // } - // } - //} + /***************************************************************************/ + /*! + + \brief + This function is mainly used for the purposes of giving a subpass a new + index in the case another subpass in the node gets deleted, and subpasses + need to be re-indexed. + + \param index + New index of the subpass. + + */ + /***************************************************************************/ + void SHSubpass::SetIndex(uint32_t index) noexcept + { + subpassIndex = index; + } /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h index 66d41ffd..6c582aa6 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h @@ -50,9 +50,6 @@ namespace SHADE //! Handle superBatch; - //! Descriptor set layout to hold attachments - Handle descriptorSetLayout; - //! Color attachments std::vector colorReferences; @@ -122,6 +119,8 @@ namespace SHADE void Execute(Handle commandBuffer, Handle descPool, uint32_t frameIndex) noexcept; void HandleResize (void) noexcept; void BindInputDescriptorSets (Handle cmdBuffer, uint32_t setIndex, uint32_t frameIndex) const noexcept; + void DetachResource (std::string const& resourceName, uint32_t attachmentIndex) noexcept; + bool HasNoAttachments (void) const noexcept; void Init(SHResourceHub& resourceManager) noexcept; @@ -132,6 +131,10 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* GETTERS AND SETTERS */ /*-----------------------------------------------------------------------*/ + private: + void SetIndex (uint32_t index) noexcept; + + public: Handle const& GetParentNode(void) const noexcept; SHSubPassIndex GetIndex() const noexcept; Handle GetSuperBatch(void) const noexcept;