Added editor functionality for lights to enable shadows

This commit is contained in:
Brandon Mak 2023-03-08 09:38:07 +08:00
parent ff4c294313
commit 64e60a5114
14 changed files with 290 additions and 133 deletions

View File

@ -30,4 +30,5 @@ constexpr SHEventIdentifier SH_BUTTON_RELEASE_EVENT { 21 };
constexpr SHEventIdentifier SH_BUTTON_HOVER_ENTER_EVENT { 22 }; constexpr SHEventIdentifier SH_BUTTON_HOVER_ENTER_EVENT { 22 };
constexpr SHEventIdentifier SH_BUTTON_HOVER_EXIT_EVENT { 23 }; constexpr SHEventIdentifier SH_BUTTON_HOVER_EXIT_EVENT { 23 };
constexpr SHEventIdentifier SH_ASSET_COMPILE_EVENT { 24 }; constexpr SHEventIdentifier SH_ASSET_COMPILE_EVENT { 24 };
constexpr SHEventIdentifier SH_LIGHT_DELETE_EVENT { 25 };

View File

@ -6,13 +6,16 @@
namespace SHADE namespace SHADE
{ {
struct SHLightEnableShadowEvent struct SHLightShadowEvent
{ {
//! We need to get the light component and initialize the relevant variables. //! We need to get the light component and initialize the relevant variables.
EntityID lightEntity; EntityID lightEntity;
//! Generate a renderer for the light component //! Generate a renderer for the light component
bool generateRenderer; bool firstEnable;
//! True when light is set enable shadow
bool enableShadow;
}; };
struct SHWindowResizeEvent struct SHWindowResizeEvent
@ -23,4 +26,10 @@ namespace SHADE
// New height when window resizes // New height when window resizes
uint32_t resizeHeight; uint32_t resizeHeight;
}; };
struct SHDeleteLightEvent
{
//! Entity of the light we are deleting
EntityID lightEntity;
};
} }

View File

@ -537,12 +537,21 @@ namespace SHADE
ReceiverPtr lightEnableShadowReceivePtr = std::dynamic_pointer_cast<SHEventReceiver>(lightEnableShadowReceiver); ReceiverPtr lightEnableShadowReceivePtr = std::dynamic_pointer_cast<SHEventReceiver>(lightEnableShadowReceiver);
SHEventManager::SubscribeTo(SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT, lightEnableShadowReceivePtr); SHEventManager::SubscribeTo(SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT, lightEnableShadowReceivePtr);
std::shared_ptr<SHEventReceiverSpec<SHGraphicsSystem>> lightDeleteEvent
{
std::make_shared<SHEventReceiverSpec<SHGraphicsSystem>>(this, &SHGraphicsSystem::ReceiveLightDeleteEvent)
};
ReceiverPtr lightDeleteReceivePtr = std::dynamic_pointer_cast<SHEventReceiver>(lightDeleteEvent);
SHEventManager::SubscribeTo(SH_ASSET_COMPILE_EVENT, lightDeleteReceivePtr);
std::shared_ptr<SHEventReceiverSpec<SHGraphicsSystem>> compileAssetReceiever std::shared_ptr<SHEventReceiverSpec<SHGraphicsSystem>> compileAssetReceiever
{ {
std::make_shared<SHEventReceiverSpec<SHGraphicsSystem>>(this, &SHGraphicsSystem::ReceiveCompileAssetEvent) std::make_shared<SHEventReceiverSpec<SHGraphicsSystem>>(this, &SHGraphicsSystem::ReceiveCompileAssetEvent)
}; };
ReceiverPtr compileAssetReceivePtr = std::dynamic_pointer_cast<SHEventReceiver>(compileAssetReceiever); ReceiverPtr compileAssetReceivePtr = std::dynamic_pointer_cast<SHEventReceiver>(compileAssetReceiever);
SHEventManager::SubscribeTo(SH_ASSET_COMPILE_EVENT, compileAssetReceivePtr); SHEventManager::SubscribeTo(SH_ASSET_COMPILE_EVENT, compileAssetReceivePtr);
} }
void SHGraphicsSystem::InitGenericDataAndTexturesDescSet(void) noexcept void SHGraphicsSystem::InitGenericDataAndTexturesDescSet(void) noexcept
@ -846,10 +855,7 @@ namespace SHADE
SHEventHandle SHGraphicsSystem::ReceiveLightEnableShadowEvent(SHEventPtr eventPtr) noexcept SHEventHandle SHGraphicsSystem::ReceiveLightEnableShadowEvent(SHEventPtr eventPtr) noexcept
{ {
// we need to wait for the device to finish using the graph first auto const& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHLightShadowEvent>*>(eventPtr.get())->data;
device->WaitIdle();
auto const& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHLightEnableShadowEvent>*>(eventPtr.get())->data;
auto* lightComp = SHComponentManager::GetComponent<SHLightComponent>(EVENT_DATA->lightEntity); auto* lightComp = SHComponentManager::GetComponent<SHLightComponent>(EVENT_DATA->lightEntity);
std::string depthResourceName = "ShadowMap_Depth " + std::to_string(EVENT_DATA->lightEntity); std::string depthResourceName = "ShadowMap_Depth " + std::to_string(EVENT_DATA->lightEntity);
std::string shadowMapResourceName = "ShadowMap " + std::to_string(EVENT_DATA->lightEntity); std::string shadowMapResourceName = "ShadowMap " + std::to_string(EVENT_DATA->lightEntity);
@ -857,15 +863,20 @@ namespace SHADE
Handle<SHSubpass> gBufferWriteSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_SUBPASS); Handle<SHSubpass> gBufferWriteSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_SUBPASS);
Handle<SHSubpass> gBufferWriteVfxSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_VFX_SUBPASS); Handle<SHSubpass> gBufferWriteVfxSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_VFX_SUBPASS);
if (EVENT_DATA->generateRenderer) if (EVENT_DATA->enableShadow)
{ {
// When the light first enables shadow rendering, we need to prepare the relevant objects to render shadows; namely renderpasses and subpasses, pipelines and descriptor sets
if (EVENT_DATA->firstEnable)
{
// we need to wait for the device to finish using the graph first
device->WaitIdle();
// Create new renderer for the light component and give it to the light component // Create new renderer for the light component and give it to the light component
Handle<SHRenderer> newRenderer = resourceManager.Create<SHRenderer>(device, swapchain->GetNumImages(), descPool, SHRenderer::PROJECTION_TYPE::ORTHOGRAPHIC); Handle<SHRenderer> newRenderer = resourceManager.Create<SHRenderer>(device, swapchain->GetNumImages(), descPool, SHRenderer::PROJECTION_TYPE::ORTHOGRAPHIC);
lightComp->SetRenderer(newRenderer); lightComp->SetRenderer(newRenderer);
// assign shadow map index to light component // assign shadow map index to light component
lightComp->SetShadowMapIndex(lightingSubSystem->GetNumShadowMaps()); lightComp->SetShadowMapIndex(lightingSubSystem->GetNumShadowMaps());
}
// Add the shadow map resource to the graph // Add the shadow map resource to the graph
@ -883,15 +894,8 @@ namespace SHADE
shadowMapDrawSubpass->AddColorOutput(shadowMapResourceName); shadowMapDrawSubpass->AddColorOutput(shadowMapResourceName);
shadowMapDrawSubpass->AddDepthOutput(depthResourceName, SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH); shadowMapDrawSubpass->AddDepthOutput(depthResourceName, SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH);
// add dummy subpass to transition the shadow map images for compute shader usage
//auto dummySubpass = shadowMapNode->RuntimeAddSubpass(shadowMapResourceName + "Dummy", {}, {});
//dummySubpass->AddGeneralColorOutput(shadowMapResourceName);
//dummySubpass->AddGeneralColorOutput(shadowMapBlurredResourceName);
// add compute pass to blur shadow ma // add compute pass to blur shadow ma
shadowMapNode->AddNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName, shadowMapBlurCS, { shadowMapResourceName.c_str(), shadowMapBlurredResourceName.c_str() }); shadowMapNode->AddNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName, shadowMapBlurCS, { shadowMapResourceName.c_str(), shadowMapBlurredResourceName.c_str() });
//shadowMapNode->AddNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName, shadowMapBlurCS, { shadowMapBlurredResourceName.c_str(), shadowMapResourceName.c_str() });
//shadowMapNode->AddNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName, shadowMapBlurCS, { shadowMapResourceName.c_str(), shadowMapBlurredResourceName.c_str() });
// regenerate the node // regenerate the node
shadowMapNode->RuntimeStandaloneRegenerate(); shadowMapNode->RuntimeStandaloneRegenerate();
@ -920,8 +924,51 @@ namespace SHADE
// add the shadow map and the blurred version to the lighting system // add the shadow map and the blurred version to the lighting system
uint32_t const NEW_SHADOW_MAP_INDEX = lightingSubSystem->AddShadowMap(renderGraph->GetRenderGraphResource(shadowMapBlurredResourceName), EVENT_DATA->lightEntity); uint32_t const NEW_SHADOW_MAP_INDEX = lightingSubSystem->AddShadowMap(renderGraph->GetRenderGraphResource(shadowMapBlurredResourceName), EVENT_DATA->lightEntity);
// Get deferred composite node compute and modify descriptor set
auto nodeCompute = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data())->GetNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data()); auto nodeCompute = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data())->GetNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data());
nodeCompute->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA, lightingSubSystem->GetViewSamplerLayout(NEW_SHADOW_MAP_INDEX), NEW_SHADOW_MAP_INDEX); nodeCompute->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA, lightingSubSystem->GetViewSamplerLayout(NEW_SHADOW_MAP_INDEX), NEW_SHADOW_MAP_INDEX);
}
else
{
// get the shadow map node
renderGraph->GetNode (SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName)->SetDynamicActive(true);
}
}
else
{
// get the shadow map node
renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName)->SetDynamicActive(false);
}
return eventPtr->handle;
}
SHEventHandle SHGraphicsSystem::ReceiveLightDeleteEvent(SHEventPtr eventPtr) noexcept
{
// we need to wait for the device to finish using the graph first
device->WaitIdle();
auto const& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHLightShadowEvent>*>(eventPtr.get())->data;
auto* lightComp = SHComponentManager::GetComponent<SHLightComponent>(EVENT_DATA->lightEntity);
if (lightComp && lightComp->GetShadowMapIndex())
{
std::string depthResourceName = "ShadowMap_Depth " + std::to_string(EVENT_DATA->lightEntity);
std::string shadowMapResourceName = "ShadowMap " + std::to_string(EVENT_DATA->lightEntity);
std::string shadowMapBlurredResourceName = "ShadowMap Blurred" + std::to_string(EVENT_DATA->lightEntity);
// Remove render graph node
renderGraph->RemoveNode(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName);
// Remove render graph resource
renderGraph->RemoveResource(depthResourceName);
renderGraph->RemoveResource(shadowMapResourceName);
renderGraph->RemoveResource(shadowMapBlurredResourceName);
// Register light component shadow map index into light system as recyclable
lightingSubSystem->RemoveShadowMap (EVENT_DATA->lightEntity);
}
return eventPtr->handle; return eventPtr->handle;
} }

View File

@ -182,6 +182,7 @@ namespace SHADE
/* Light functions */ /* Light functions */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
SHEventHandle ReceiveLightEnableShadowEvent (SHEventPtr eventPtr) noexcept; SHEventHandle ReceiveLightEnableShadowEvent (SHEventPtr eventPtr) noexcept;
SHEventHandle ReceiveLightDeleteEvent (SHEventPtr eventPtr) noexcept;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* Asset Events */ /* Asset Events */

View File

@ -113,15 +113,21 @@ namespace SHADE
lightData.castShadows = flag; lightData.castShadows = flag;
// If the flag is true // If the flag is true
if (flag && lightData.shadowMapIndex == SHLightData::INVALID_SHADOW_MAP_INDEX) if (flag)
{ {
// Create new event and broadcast it // Create new event and broadcast it
SHLightEnableShadowEvent newEvent; SHLightShadowEvent newEvent;
newEvent.lightEntity = GetEID(); newEvent.lightEntity = GetEID();
newEvent.generateRenderer = static_cast<bool>(!renderer);
SHEventManager::BroadcastEvent<SHLightEnableShadowEvent>(newEvent, SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT); // If shadow map index is invalid, that means light is enabling shadow for the first time.
newEvent.firstEnable = (lightData.shadowMapIndex == SHLightData::INVALID_SHADOW_MAP_INDEX);
// pass the flag to the event
newEvent.enableShadow = flag;
SHEventManager::BroadcastEvent<SHLightShadowEvent>(newEvent, SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT);
} }
} }
void SHLightComponent::SetRenderer(Handle<SHRenderer> newRenderer) noexcept void SHLightComponent::SetRenderer(Handle<SHRenderer> newRenderer) noexcept
@ -195,6 +201,11 @@ namespace SHADE
return lightData.castShadows; return lightData.castShadows;
} }
uint32_t SHLightComponent::GetShadowMapIndex(void) const noexcept
{
return lightData.shadowMapIndex;
}
} }
RTTR_REGISTRATION RTTR_REGISTRATION

View File

@ -70,6 +70,8 @@ namespace SHADE
float GetStrength (void) const noexcept; float GetStrength (void) const noexcept;
Handle<SHRenderer> GetRenderer (void) const noexcept; Handle<SHRenderer> GetRenderer (void) const noexcept;
bool GetEnableShadow (void) const noexcept; bool GetEnableShadow (void) const noexcept;
uint32_t GetShadowMapIndex (void) const noexcept;
RTTR_ENABLE() RTTR_ENABLE()
}; };
} }

View File

@ -599,39 +599,15 @@ namespace SHADE
{ {
//Bind descriptor set(We bind at an offset because the buffer holds NUM_FRAME_BUFFERS sets of data). //Bind descriptor set(We bind at an offset because the buffer holds NUM_FRAME_BUFFERS sets of data).
cmdBuffer->BindDescriptorSet(lightingDataDescSet, SH_PIPELINE_TYPE::COMPUTE, setIndex, { dynamicOffsets[frameIndex] }); cmdBuffer->BindDescriptorSet(lightingDataDescSet, SH_PIPELINE_TYPE::COMPUTE, setIndex, { dynamicOffsets[frameIndex] });
} }
uint32_t SHLightingSubSystem::AddShadowMap(Handle<SHRenderGraphResource> newShadowMapBlurred, EntityID lightEntity) noexcept uint32_t SHLightingSubSystem::AddShadowMap(Handle<SHRenderGraphResource> newShadowMapBlurred, EntityID lightEntity) noexcept
{ {
// Add to container of shadow maps uint32_t usedIndex = 0;
shadowMapIndexing.emplace(lightEntity, static_cast<uint32_t> (shadowMaps.size()));
shadowMaps.emplace_back(newShadowMapBlurred);
// Just use the image view stored in the resource // Just use the image view stored in the resource
Handle<SHVkImageView> const NEW_IMAGE_VIEW = newShadowMapBlurred->GetImageView(); Handle<SHVkImageView> const NEW_IMAGE_VIEW = newShadowMapBlurred->GetImageView();
// Prepare to write to descriptor
shadowMapImageSamplers.emplace_back(NEW_IMAGE_VIEW, shadowMapSampler, vk::ImageLayout::eShaderReadOnlyOptimal);
// Update descriptor set
//static constexpr uint32_t SHADOW_MAP_DESC_SET_INDEX = 0;
//uint32_t const SHADOW_MAP_DESC_ARRAY_INDEX = static_cast<uint32_t>(shadowMapImageSamplers.size()) - 1u;
//shadowMapDescriptorSet->ModifyWriteDescImage
//(
// SHADOW_MAP_DESC_SET_INDEX,
// SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA,
// shadowMapImageSamplers[SHADOW_MAP_DESC_ARRAY_INDEX],
// SHADOW_MAP_DESC_ARRAY_INDEX
//);
//// TODO: Definitely can be optimized by writing a function that modifies a specific descriptor in the array
//shadowMapDescriptorSet->UpdateDescriptorSetImages
//(
// SHADOW_MAP_DESC_SET_INDEX,
// SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA
//);
// add to barriers // add to barriers
shadowMapMemoryBarriers.push_back (vk::ImageMemoryBarrier shadowMapMemoryBarriers.push_back (vk::ImageMemoryBarrier
{ {
@ -652,8 +628,68 @@ namespace SHADE
} }
}); });
if (recyclableIndices.empty())
{
shadowMaps.emplace_back(newShadowMapBlurred);
// Prepare to write to descriptor
shadowMapImageSamplers.emplace_back(NEW_IMAGE_VIEW, shadowMapSampler, vk::ImageLayout::eShaderReadOnlyOptimal);
// Add to container of shadow maps
shadowMapIndexing.emplace(lightEntity, static_cast<uint32_t> (shadowMaps.size()));
usedIndex = static_cast<uint32_t>(shadowMapImageSamplers.size()) - 1u;
}
else
{
uint32_t usedIndex = recyclableIndices.top();
recyclableIndices.pop();
// Recycle the slot in the vector of shadow maps
shadowMaps[usedIndex] = newShadowMapBlurred;
// register indexing for shadow maps
shadowMapIndexing.emplace(lightEntity, usedIndex);
// Recycle the slot in the vector of image view, samplers and layout
shadowMapImageSamplers[usedIndex] = std::make_tuple(NEW_IMAGE_VIEW, shadowMapSampler, vk::ImageLayout::eShaderReadOnlyOptimal);
}
// return new index of shadow map // return new index of shadow map
return static_cast<uint32_t>(shadowMapImageSamplers.size()) - 1u; return usedIndex;
}
void SHLightingSubSystem::RemoveShadowMap(EntityID lightEntity) noexcept
{
auto* lightComp = SHComponentManager::GetComponent<SHLightComponent>(lightEntity);
if (lightComp && shadowMapIndexing.contains(lightEntity))
{
uint32_t shadowMapIndex = shadowMapIndexing[lightEntity];
// Recycle the shadow map index used by the component
RecycleShadowMapIndex(lightComp);
// Not removed from container, can recycle
shadowMaps[shadowMapIndex] = {};
// Not removed from container, can recycle
shadowMapImageSamplers[shadowMapIndex] = {};
// Remove from barriers
shadowMapMemoryBarriers.erase(shadowMapMemoryBarriers.begin() + shadowMapIndex);
// remove from map for indexing
shadowMapIndexing.erase(lightEntity);
}
}
void SHLightingSubSystem::RecycleShadowMapIndex(SHLightComponent* lightComp) noexcept
{
// if index is recyclable, recycle it
if (lightComp && lightComp->GetShadowMapIndex() != SHLightData::INVALID_SHADOW_MAP_INDEX)
recyclableIndices.push (lightComp->GetShadowMapIndex());
} }
void SHLightingSubSystem::PrepareShadowMapsForRead(Handle<SHVkCommandBuffer> cmdBuffer) noexcept void SHLightingSubSystem::PrepareShadowMapsForRead(Handle<SHVkCommandBuffer> cmdBuffer) noexcept
@ -662,28 +698,6 @@ namespace SHADE
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eComputeShader, vk::PipelineStageFlagBits::eComputeShader, {}, {}, {}, shadowMapMemoryBarriers); cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eComputeShader, vk::PipelineStageFlagBits::eComputeShader, {}, {}, {}, shadowMapMemoryBarriers);
} }
//void SHLightingSubSystem::HandleResize(Handle<SHRenderGraphNodeCompute> compute) noexcept
//{
// uint32_t const NUM_SHADOW_MAPS = static_cast<uint32_t>(shadowMaps.size());
// for (uint32_t i = 0; i < NUM_SHADOW_MAPS; ++i)
// {
// // Just use the image view stored in the resource
// Handle<SHVkImageView> const NEW_IMAGE_VIEW = shadowMaps[i]->GetImageView();
// // set new image view
// std::get<Handle<SHVkImageView>>(shadowMapImageSamplers[i]) = NEW_IMAGE_VIEW;
// // Set image for barrier
// shadowMapMemoryBarriers[i].image = shadowMaps[i]->GetImage()->GetVkImage();
// }
// if (NUM_SHADOW_MAPS > 0)
// {
// // modify descriptors in render graph node compute
// compute->ModifyWriteDescImageComputeResource (SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA, shadowMapImageSamplers);
// }
//}
Handle<SHVkDescriptorSetGroup> SHLightingSubSystem::GetLightDataDescriptorSet(void) const noexcept Handle<SHVkDescriptorSetGroup> SHLightingSubSystem::GetLightDataDescriptorSet(void) const noexcept
{ {
return lightingDataDescSet; return lightingDataDescSet;

View File

@ -9,6 +9,7 @@
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
#include "Graphics/RenderGraph/SHRenderGraphResource.h" #include "Graphics/RenderGraph/SHRenderGraphResource.h"
#include "ECS_Base/SHECSMacros.h" #include "ECS_Base/SHECSMacros.h"
#include <stack>
namespace SHADE namespace SHADE
@ -183,10 +184,6 @@ namespace SHADE
//! Shadow maps for every light that casts a shadow Order here doesn't matter. We just want to store it //! Shadow maps for every light that casts a shadow Order here doesn't matter. We just want to store it
std::vector<Handle<SHRenderGraphResource>> shadowMaps; std::vector<Handle<SHRenderGraphResource>> shadowMaps;
//! Descriptor sets required to be given to the compute shader for shadow calculation. This will be a descriptor array.
//! It will also be preallocated.
//Handle<SHVkDescriptorSetGroup> shadowMapDescriptorSet;
//! Combined image samplers for the texture descriptors //! Combined image samplers for the texture descriptors
std::vector<std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout>> shadowMapImageSamplers; std::vector<std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout>> shadowMapImageSamplers;
@ -194,6 +191,9 @@ namespace SHADE
//! to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) //! to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
std::vector<vk::ImageMemoryBarrier> shadowMapMemoryBarriers; std::vector<vk::ImageMemoryBarrier> shadowMapMemoryBarriers;
//! recycled indices after deleting lights with shadows
std::stack<uint32_t> recyclableIndices;
//! Resource hub from Graphics System //! Resource hub from Graphics System
SHResourceHub* resourceHub; SHResourceHub* resourceHub;
@ -217,6 +217,8 @@ namespace SHADE
void Exit (void) noexcept; void Exit (void) noexcept;
void BindDescSet (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t setIndex, uint32_t frameIndex) noexcept; void BindDescSet (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t setIndex, uint32_t frameIndex) noexcept;
uint32_t AddShadowMap (Handle<SHRenderGraphResource> newShadowMapBlurred, EntityID lightEntity) noexcept; uint32_t AddShadowMap (Handle<SHRenderGraphResource> newShadowMapBlurred, EntityID lightEntity) noexcept;
void RemoveShadowMap (EntityID lightEntity) noexcept;
void RecycleShadowMapIndex (SHLightComponent* lightComp) noexcept;
void PrepareShadowMapsForRead (Handle<SHVkCommandBuffer> cmdBuffer) noexcept; void PrepareShadowMapsForRead (Handle<SHVkCommandBuffer> cmdBuffer) noexcept;
//void HandleResize (Handle<SHRenderGraphNodeCompute> compute) noexcept; //void HandleResize (Handle<SHRenderGraphNodeCompute> compute) noexcept;
//void RemoveShadowMap (uint32_t index) noexcept; //void RemoveShadowMap (uint32_t index) noexcept;

View File

@ -81,7 +81,8 @@ namespace SHADE
renderGraphStorage->logicalDevice->WaitIdle(); renderGraphStorage->logicalDevice->WaitIdle();
uint64_t handleID = renderGraphStorage->graphResources->at (resourceName).GetId().Raw; auto resourceHdl = renderGraphStorage->graphResources->at(resourceName);
uint64_t handleID = resourceHdl.GetId().Raw;
// Record nodes that will be affected // Record nodes that will be affected
std::vector<uint32_t> affectedNodes{}; std::vector<uint32_t> affectedNodes{};
@ -89,7 +90,7 @@ namespace SHADE
// Detach resource from all nodes if applicable // Detach resource from all nodes if applicable
for (uint32_t i = 0; i < nodes.size(); ++i) for (uint32_t i = 0; i < nodes.size(); ++i)
{ {
if (nodes[i]->DetachResource(resourceName, handleID)) if (nodes[i] && nodes[i]->DetachResource(resourceName, handleID))
affectedNodes.emplace_back(i); affectedNodes.emplace_back(i);
} }
@ -109,6 +110,8 @@ namespace SHADE
renderGraphStorage->graphResources->at(resourceName).Free(); renderGraphStorage->graphResources->at(resourceName).Free();
renderGraphStorage->graphResources->erase (resourceName); renderGraphStorage->graphResources->erase (resourceName);
resourceHdl.Free ();
/* /*
* IMPORTANT NOTES * IMPORTANT NOTES
* *
@ -121,6 +124,21 @@ namespace SHADE
*/ */
} }
void SHRenderGraph::RemoveNode(std::string nodeName) noexcept
{
if (nodeIndexing.contains(nodeName))
{
// wait for device to stop
renderGraphStorage->logicalDevice->WaitIdle();
// Get handle to node since it exists
auto nodeHdl = nodes[nodeIndexing[nodeName]];
nodeHdl.Free();
nodeIndexing.erase(nodeName);
}
}
void SHRenderGraph::LinkNonOwningResource(Handle<SHRenderGraph> resourceOrigin, std::string resourceName) noexcept void SHRenderGraph::LinkNonOwningResource(Handle<SHRenderGraph> resourceOrigin, std::string resourceName) noexcept
{ {
// resource to link // resource to link

View File

@ -112,6 +112,7 @@ namespace SHADE
); );
void RemoveResource (std::string resourceName) noexcept; void RemoveResource (std::string resourceName) noexcept;
void RemoveNode (std::string nodeName) noexcept;
void LinkNonOwningResource void LinkNonOwningResource
( (

View File

@ -405,6 +405,22 @@ namespace SHADE
return *this; return *this;
} }
SHRenderGraphNode::~SHRenderGraphNode(void) noexcept
{
if (renderpass)
renderpass.Free();
for (auto& framebuffer : framebuffers)
framebuffer.Free();
for (auto& subpass : subpasses)
subpass.Free();
// Too tired to test, its nearing end of milestone 3....
//for (auto& nc : nodeComputes)
// nc.Free();
}
/***************************************************************************/ /***************************************************************************/
/*! /*!

View File

@ -111,6 +111,7 @@ namespace SHADE
SHRenderGraphNode(std::string nodeName, Handle<SHRenderGraphStorage> renderGraphStorage, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors, bool inIsDynamic = false) noexcept; SHRenderGraphNode(std::string nodeName, Handle<SHRenderGraphStorage> renderGraphStorage, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors, bool inIsDynamic = false) noexcept;
SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept; SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept;
SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept; SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept;
~SHRenderGraphNode (void) noexcept;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */ /* PUBLIC MEMBER FUNCTIONS */

View File

@ -80,6 +80,14 @@ namespace SHADE
, companionSubpasses {std::move (rhs.companionSubpasses)} , companionSubpasses {std::move (rhs.companionSubpasses)}
, dummyPipelineLayout{rhs.dummyPipelineLayout} , dummyPipelineLayout{rhs.dummyPipelineLayout}
{ {
superBatch = std::move(rhs.superBatch);
rhs.superBatch = {};
inputDescriptorLayout = std::move(rhs.inputDescriptorLayout);
rhs.inputDescriptorLayout = {};
dummyPipelineLayout = std::move(rhs.dummyPipelineLayout);
rhs.dummyPipelineLayout = {};
} }
@ -101,7 +109,6 @@ namespace SHADE
subpassIndex = std::move(rhs.subpassIndex); subpassIndex = std::move(rhs.subpassIndex);
parentNode = std::move(rhs.parentNode); parentNode = std::move(rhs.parentNode);
superBatch = std::move(rhs.superBatch);
colorReferences = std::move(rhs.colorReferences); colorReferences = std::move(rhs.colorReferences);
depthReferences = std::move(rhs.depthReferences); depthReferences = std::move(rhs.depthReferences);
inputReferences = std::move(rhs.inputReferences); inputReferences = std::move(rhs.inputReferences);
@ -118,10 +125,36 @@ namespace SHADE
companionSubpasses = rhs.companionSubpasses; companionSubpasses = rhs.companionSubpasses;
dummyPipelineLayout = rhs.dummyPipelineLayout; dummyPipelineLayout = rhs.dummyPipelineLayout;
superBatch = std::move(rhs.superBatch);
rhs.superBatch = {};
inputDescriptorLayout = std::move(rhs.inputDescriptorLayout);
rhs.inputDescriptorLayout = {};
dummyPipelineLayout = std::move(rhs.dummyPipelineLayout);
rhs.dummyPipelineLayout = {};
return *this; return *this;
} }
SHSubpass::~SHSubpass(void) noexcept
{
graphStorage->logicalDevice->WaitIdle();
for (auto& set : inputImageDescriptorSets)
set.Free();
if (inputDescriptorLayout)
inputDescriptorLayout.Free();
if (dummyPipelineLayout)
dummyPipelineLayout.Free();
// not working
//if (superBatch)
// superBatch.Free();
}
/***************************************************************************/ /***************************************************************************/
/*! /*!

View File

@ -130,6 +130,7 @@ namespace SHADE
SHSubpass(const std::string& name, Handle<SHViewport> inViewport, Handle<SHRenderer> inRenderer, Handle<SHRenderGraphStorage> renderGraphStorage, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping) noexcept; SHSubpass(const std::string& name, Handle<SHViewport> inViewport, Handle<SHRenderer> inRenderer, Handle<SHRenderGraphStorage> renderGraphStorage, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping) noexcept;
SHSubpass(SHSubpass&& rhs) noexcept; SHSubpass(SHSubpass&& rhs) noexcept;
SHSubpass& operator=(SHSubpass&& rhs) noexcept; SHSubpass& operator=(SHSubpass&& rhs) noexcept;
~SHSubpass(void) noexcept;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */ /* PUBLIC MEMBER FUNCTIONS */