diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp index e77234ca..7c5c0e48 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp @@ -177,6 +177,21 @@ namespace SHADE } } + void SHVkDescriptorSetGroup::ModifyWriteDescImage(uint32_t set, uint32_t binding, std::tuple, Handle, vk::ImageLayout> const& imageViewAndSampler, uint32_t descIndex) noexcept + { + // Find the target writeDescSet + BindingAndSetHash writeHash = binding; + writeHash |= static_cast(set) << 32; + auto& writeInfo = updater.writeInfos[updater.writeHashMap.at(writeHash)]; + + // write sampler and image view + auto& [view, sampler, layout] = imageViewAndSampler; + writeInfo.descImageInfos[descIndex].imageView = view->GetImageView(); + writeInfo.descImageInfos[descIndex].sampler = sampler ? sampler->GetVkSampler() : nullptr; + writeInfo.descImageInfos[descIndex].imageLayout = layout; + + } + void SHVkDescriptorSetGroup::ModifyWriteDescBuffer(uint32_t set, uint32_t binding, std::span> const& buffers, uint32_t offset, uint32_t range) noexcept { // Find the target writeDescSet diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h index a228bc66..4538b271 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h @@ -67,6 +67,7 @@ namespace SHADE void UpdateDescriptorSetBuffer(uint32_t set, uint32_t binding) noexcept; void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span, Handle, vk::ImageLayout>> const& imageViewsAndSamplers) noexcept; + void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::tuple, Handle, vk::ImageLayout> const& imageViewAndSampler, uint32_t descIndex) noexcept; void ModifyWriteDescBuffer (uint32_t set, uint32_t binding, std::span> const& buffers, uint32_t offset, uint32_t range) noexcept; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp index ffe29b36..d09ec5b4 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp @@ -150,12 +150,26 @@ namespace SHADE Handle fontDataDescSetLayout = logicalDevice->CreateDescriptorSetLayout({ fontBitmapBinding, fontMatrixBinding }); SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, fontDataDescSetLayout->GetVkHandle(), "[Descriptor Set Layout] Font Data"); + // descriptor binding for storing shadow maps + SHVkDescriptorSetLayout::Binding shadowMapBinding + { + .Type = vk::DescriptorType::eCombinedImageSampler, + .Stage = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eCompute, + .BindPoint = SHGraphicsConstants::DescriptorSetBindings::IMAGE_AND_SAMPLERS_DATA, + .DescriptorCount = 200, // we can have up to 2000 textures for now + .flags = vk::DescriptorBindingFlagBits::eVariableDescriptorCount, + }; + + // For global data (generic data and textures) + Handle shadowMapDescLayout = logicalDevice->CreateDescriptorSetLayout({ shadowMapBinding }); + SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, shadowMapDescLayout->GetVkHandle(), "[Descriptor Set Layout] Shadow Maps"); predefinedLayouts.push_back(staticGlobalLayout); predefinedLayouts.push_back(lightDataDescSetLayout); predefinedLayouts.push_back(cameraDataGlobalLayout); predefinedLayouts.push_back(materialDataPerInstanceLayout); predefinedLayouts.push_back(fontDataDescSetLayout); + predefinedLayouts.push_back(shadowMapDescLayout); perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descSetLayouts = GetPredefinedDescSetLayouts ( diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h index 11bfc469..b4004d5a 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h @@ -28,6 +28,7 @@ namespace SHADE CAMERA = 0x04, MATERIALS = 0x08, FONT = 0x10, + SHADOW = 0x20, }; enum class SystemType diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h index f331ce02..b061dde3 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h @@ -169,6 +169,15 @@ namespace SHADE /***************************************************************************/ static constexpr uint32_t FONT_MATRIX_DATA = 1; + /***************************************************************************/ + /*! + \brief + Descriptor set binding for shadow map images. + + */ + /***************************************************************************/ + static constexpr uint32_t SHADOW_MAP_IMAGE_SAMPLER_DATA = 0; + }; struct VertexBufferBindings diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 2ad41151..6647ea74 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -394,7 +394,11 @@ namespace SHADE postOffscreenRenderSubSystem->Init(device, renderGraph->GetRenderGraphResource("Scene"), descPool); lightingSubSystem = resourceManager.Create(); - lightingSubSystem->Init(device, descPool); + lightingSubSystem->Init(device, descPool, samplerCache.GetSampler (device, SHVkSamplerParams + { + // nothing for now + }) + ); textRenderingSubSystem = resourceManager.Create(); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp index ddacf3a7..7a4a3203 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp @@ -10,6 +10,9 @@ #include "SHLightComponent.h" #include "Math/Vector/SHVec4.h" #include "Math/SHMatrix.h" +#include "Graphics/Images/SHVkImageView.h" +#include "Graphics/MiddleEnd/Textures/SHVkSamplerCache.h" +#include "Graphics/Images/SHVkSampler.h" namespace SHADE { @@ -365,6 +368,11 @@ namespace SHADE } } + void SHLightingSubSystem::UpdateShadowMapDesc(void) noexcept + { + + } + /***************************************************************************/ /*! @@ -375,13 +383,14 @@ namespace SHADE */ /***************************************************************************/ - void SHLightingSubSystem::Init(Handle device, Handle descPool) noexcept + void SHLightingSubSystem::Init(Handle device, Handle descPool, Handle inShadowMapSampler) noexcept { SHComponentManager::CreateComponentSparseSet(); logicalDevice = device; uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ConvertEnum(SH_LIGHT_TYPE::NUM_TYPES); +#pragma region LIGHTING std::vector variableSizes{ NUM_LIGHT_TYPES }; std::fill (variableSizes.begin(), variableSizes.end(), 1); @@ -418,7 +427,21 @@ namespace SHADE dynamicOffsets[i].resize(NUM_LIGHT_TYPES + 1); // +1 for the count } +#pragma endregion + +#pragma region SHADOWS + std::vector shadowDescVariableSizes{ MAX_SHADOWS }; + shadowMapDescriptorSet = descPool->Allocate({SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::SHADOW)}, shadowDescVariableSizes); + +#ifdef _DEBUG + const auto& SHADOW_MAP_DESC_SETS = shadowMapDescriptorSet->GetVkHandle(); + for (int i = 0; i < static_cast(SHADOW_MAP_DESC_SETS.size()); ++i) + SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSet, SHADOW_MAP_DESC_SETS[i], "[Descriptor Set] Shadow Map Data Frame #" + std::to_string(i)); +#endif + + shadowMapSampler = inShadowMapSampler; //numLightComponents = 0; +#pragma endregion } /***************************************************************************/ @@ -526,6 +549,36 @@ namespace SHADE } + void SHLightingSubSystem::AddShadowMap(Handle newShadowMap) noexcept + { + // Add to container of shadow maps + shadowMaps.emplace_back(newShadowMap); + + // Just use the image view stored in the resource + Handle const NEW_IMAGE_VIEW = newShadowMap->GetImageView(); + + // Prepare to write to descriptor + shadowMapImageSamplers.emplace_back(NEW_IMAGE_VIEW, shadowMapSampler, vk::ImageLayout::eShaderReadOnlyOptimal); + + static constexpr uint32_t SHADOW_MAP_DESC_SET_INDEX = 0; + uint32_t const SHADOW_MAP_DESC_ARRAY_INDEX = shadowMapImageSamplers.size() - 1; + 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 + ); + + } + Handle SHLightingSubSystem::GetLightDataDescriptorSet(void) const noexcept { return lightingDataDescSet; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h index fa103136..ec42193a 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h @@ -6,6 +6,7 @@ #include "SHLightData.h" #include #include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" +#include "Graphics/RenderGraph/SHRenderGraphResource.h" namespace SHADE { @@ -16,6 +17,9 @@ namespace SHADE class SHVkBuffer; class SHLightComponent; class SHVkCommandBuffer; + class SHSamplerCache; + class SHVkImageView; + class SHVkSampler; // Represents how the data will be interpreted in GPU. we want to copy to a container of these before passing to GPU. struct SHDirectionalLightData @@ -69,7 +73,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* STATIC MEMBER VARIABLES */ /*-----------------------------------------------------------------------*/ - static constexpr uint32_t STARTING_NUM_LIGHTS = 50; + static constexpr uint32_t STARTING_NUM_LIGHTS = 50; /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ @@ -123,50 +127,78 @@ namespace SHADE }; private: + /*-----------------------------------------------------------------------*/ + /* STATIC MEMBER VARIABLES */ + /*-----------------------------------------------------------------------*/ + + static constexpr uint32_t MAX_SHADOWS = 200; //! logical device used for creation - Handle logicalDevice; + Handle logicalDevice; //! The descriptor set that will hold the lighting data. Each binding will hold a buffer, NUM_FRAMES times the size required. - Handle lightingDataDescSet; - - //! Each type will have some data associated with it for processing - std::array(SH_LIGHT_TYPE::NUM_TYPES)> perTypeData; - - //! Container to store dynamic offsets for binding descriptor sets - DynamicOffsetArray dynamicOffsets; - - //! holds the data that represents how many lights are in the scene - std::array(SH_LIGHT_TYPE::NUM_TYPES)> lightCountsData; - - //! GPU buffer to hold lightCountData - Handle lightCountsBuffer; - - //! For padding in the buffer - uint32_t lightCountsAlignedSize; + Handle lightingDataDescSet; + + //! Each type will have some data associated with it for processing + std::array(SH_LIGHT_TYPE::NUM_TYPES)> perTypeData; + + //! Container to store dynamic offsets for binding descriptor sets + DynamicOffsetArray dynamicOffsets; + + //! holds the data that represents how many lights are in the scene + std::array(SH_LIGHT_TYPE::NUM_TYPES)> lightCountsData; + + //! GPU buffer to hold lightCountData + Handle lightCountsBuffer; + + //! For padding in the buffer + uint32_t lightCountsAlignedSize; //! Number of SHLightComponents recorded. If at the beginning of the run function the size returned by the dense //! set is less than the size recorded, rewrite all light components into the its respective buffers. If its more, //! don't do anything. //uint32_t numLightComponents; + //! Handle to sampler that all shadow map descriptors will use + Handle shadowMapSampler; + + //! Shadow maps for every light that casts a shadow + std::vector> 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 shadowMapDescriptorSet; + + //! Combined image samplers for the texture descriptors + std::vector, Handle, vk::ImageLayout>> shadowMapImageSamplers; + + //! Barriers required to transition the resources from whatever layout they are in (probably from VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) + //! to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + std::vector shadowMapMemoryBarriers; + /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ void UpdateDescSet (uint32_t binding) noexcept; void ComputeDynamicOffsets (void) noexcept; void ResetNumLights (void) noexcept; + void UpdateShadowMapDesc (void) noexcept; public: /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ - void Init (Handle device, Handle descPool) noexcept; - void Run (SHMatrix const& viewMat, uint32_t frameIndex) noexcept; - void Exit (void) noexcept; + void Init (Handle device, Handle descPool, Handle inShadowMapSampler) noexcept; + void Run (SHMatrix const& viewMat, uint32_t frameIndex) noexcept; + void Exit (void) noexcept; + void BindDescSet (Handle cmdBuffer, uint32_t setIndex, uint32_t frameIndex) noexcept; + void AddShadowMap (Handle newShadowMap) noexcept; + //void RemoveShadowMap (uint32_t index) noexcept; - void BindDescSet (Handle cmdBuffer, uint32_t setIndex, uint32_t frameIndex) noexcept; + /*-----------------------------------------------------------------------*/ + /* SETTERS AND GETTERS */ + /*-----------------------------------------------------------------------*/ Handle GetLightDataDescriptorSet (void) const noexcept; };