diff --git a/SHADE_Engine/src/Assets/Events/SHAssetManagerEvents.h b/SHADE_Engine/src/Assets/Events/SHAssetManagerEvents.h index aaf367e3..d61395e9 100644 --- a/SHADE_Engine/src/Assets/Events/SHAssetManagerEvents.h +++ b/SHADE_Engine/src/Assets/Events/SHAssetManagerEvents.h @@ -7,14 +7,14 @@ namespace SHADE { struct SHCompileAssetEvent { - //! Name of the shader. Should just contain stem from file path. - std::string shaderName; + //! Name of the asset (where applicable) + std::string assetName; - //! NEw binary data for shader module to use - std::vector newBinaryData; + //! asset ID of the asset + AssetID assetID; - //! Extension to check for type - std::string ext; + //! type of the asset + AssetType assetType; }; } diff --git a/SHADE_Engine/src/Assets/Libraries/Compilers/SHShaderSourceCompiler.cpp b/SHADE_Engine/src/Assets/Libraries/Compilers/SHShaderSourceCompiler.cpp index eb0b677c..0bde59c7 100644 --- a/SHADE_Engine/src/Assets/Libraries/Compilers/SHShaderSourceCompiler.cpp +++ b/SHADE_Engine/src/Assets/Libraries/Compilers/SHShaderSourceCompiler.cpp @@ -11,7 +11,6 @@ #include "SHpch.h" #include "SHShaderSourceCompiler.h" #include "shaderc/shaderc.hpp" -#include "Assets/Events/SHAssetManagerEvents.h" #include "Events/SHEventManager.hpp" #include @@ -142,14 +141,6 @@ namespace SHADE return{}; } - SHCompileAssetEvent compileShaderEvent - { - .shaderName = std::filesystem::path (data->name).stem().string(), - .newBinaryData = data->spirvBinary, - .ext = GLSL_EXTENSION.data(), - }; - SHEventManager::BroadcastEvent(compileShaderEvent, SH_ASSET_COMPILE_EVENT); - return CompileShaderSourceToBinary(path, *data); } diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index b66b670c..d8bedfd3 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -28,6 +28,8 @@ #include "Filesystem/SHFileSystem.h" #include +#include "Assets/Events/SHAssetManagerEvents.h" +#include "Events/SHEventManager.hpp" namespace SHADE { @@ -458,6 +460,14 @@ namespace SHADE else { target = GetAssetIDFromPath(path); + // send compile asset event + SHCompileAssetEvent compileShaderEvent + { + .assetName = newPath.filename().stem().string(), + .assetID = id, + .assetType = AssetType::SHADER, + }; + SHEventManager::BroadcastEvent(compileShaderEvent, SH_ASSET_COMPILE_EVENT); } //TODO SEND EVENT HERE diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index c2a6d010..70a7d34f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -893,13 +893,19 @@ namespace SHADE { auto const& EVENT_DATA = reinterpret_cast*>(eventPtr.get())->data; - auto denseIterators = SHVkInstance::GetResourceManager().GetDenseAccess(); - for (auto it = denseIterators.first; it != denseIterators.second; ++it) + // check for asset type + if (EVENT_DATA->assetType == AssetType::SHADER) { - if (it->GetName() == EVENT_DATA->shaderName) + // loop through all shaders + auto denseIterators = SHVkInstance::GetResourceManager().GetDenseAccess(); + for (auto it = denseIterators.first; it != denseIterators.second; ++it) { - it->OnChange(); - break; + if (it->GetName() == EVENT_DATA->assetName) + { + auto* shaderAsset = SHAssetManager::GetData(EVENT_DATA->assetID); + it->OnChange(shaderAsset->spirvBinary); + break; + } } } diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp index 973ae72f..77559de3 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp @@ -235,6 +235,9 @@ namespace SHADE , pipelineLayout { inPipelineLayout } , created {false} { + if (pipelineLayout) + pipelineLayout->AddCallback([this]() {ConstructPipeline();}); + // We want to create a pipeline if (state != nullptr) { diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp index 6a6ef879..e08be902 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp @@ -450,6 +450,15 @@ namespace SHADE } else SHVulkanDebugUtil::ReportVkSuccess("Successfully created Pipeline Layout. "); + + // Call callbacks + for (auto& callback : onChangeCallbacks) + callback(); + } + + void SHVkPipelineLayout::AddCallback(ChangeCallback&& callback) noexcept + { + onChangeCallbacks.emplace_back(std::move(callback)); } std::vector> const& SHVkPipelineLayout::GetShaderModules(void) const noexcept diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.h b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.h index e2af02a9..a856700b 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.h @@ -10,6 +10,9 @@ namespace SHADE class SHVkPipelineLayout { + public: + using ChangeCallback = std::function; + private: /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ @@ -51,6 +54,12 @@ namespace SHADE //! Store for pipeline layout recreation std::vector vkDescriptorSetLayoutsPipeline; + //! When pipeline layout needs to be recreated, this container could serve as an event + //! response to call all the functions that need to be called. Specifically + //! pipelines that need to use the new pipeline layout + std::vector onChangeCallbacks; + + /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ @@ -73,6 +82,7 @@ namespace SHADE /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ void RecreateIfNeeded (void) noexcept; + void AddCallback(ChangeCallback&& callback) noexcept; /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ diff --git a/SHADE_Engine/src/Graphics/Shaders/SHVkShaderModule.cpp b/SHADE_Engine/src/Graphics/Shaders/SHVkShaderModule.cpp index 9cf01b6b..030909af 100644 --- a/SHADE_Engine/src/Graphics/Shaders/SHVkShaderModule.cpp +++ b/SHADE_Engine/src/Graphics/Shaders/SHVkShaderModule.cpp @@ -7,20 +7,16 @@ namespace SHADE { - SHVkShaderModule::SHVkShaderModule(Handle const& inLogicalDeviceHdl, std::vector const& binaryData, std::string inEntryPoint, vk::ShaderStageFlagBits stage, std::string const& name) noexcept - : logicalDeviceHdl {inLogicalDeviceHdl} - , shaderStage {stage} - , entryPoint {inEntryPoint} - , vkShaderModule {nullptr} - , spirvBinary{} - , shaderName {name} - , reflectedData {} + void SHVkShaderModule::Recompile(void) noexcept { + if (vkShaderModule) + logicalDeviceHdl->GetVkLogicalDevice().destroyShaderModule(vkShaderModule, nullptr); + // Prepare the create info vk::ShaderModuleCreateInfo moduleCreateInfo { - .codeSize = binaryData.size() * sizeof (uint32_t), - .pCode = binaryData.data(), + .codeSize = spirvBinary.size() * sizeof(uint32_t), + .pCode = spirvBinary.data(), }; if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createShaderModule(&moduleCreateInfo, nullptr, &vkShaderModule); result != vk::Result::eSuccess) @@ -30,10 +26,18 @@ namespace SHADE } else SHVulkanDebugUtil::ReportVkSuccess("Successfully created shader module."); + } - // TODO: Right now, this is doing a copy, we need to figure out if its better to just move from the resource management (source library) instead. The hope is that - // shader modules only need 1 of themselves. - spirvBinary = binaryData; + SHVkShaderModule::SHVkShaderModule(Handle const& inLogicalDeviceHdl, std::vector const& binaryData, std::string inEntryPoint, vk::ShaderStageFlagBits stage, std::string const& name) noexcept + : logicalDeviceHdl {inLogicalDeviceHdl} + , shaderStage {stage} + , entryPoint {inEntryPoint} + , vkShaderModule {nullptr} + , spirvBinary{binaryData} + , shaderName {name} + , reflectedData {} + { + Recompile(); } SHVkShaderModule::SHVkShaderModule(SHVkShaderModule&& rhs) noexcept @@ -81,13 +85,18 @@ namespace SHADE } } - void SHVkShaderModule::OnChange(void) noexcept + void SHVkShaderModule::OnChange(std::vector const& newBinaryData) noexcept { + // assign new binary data and recompile shader + spirvBinary = newBinaryData; + + Recompile(); + for (auto& callback : onChangeCallbacks) callback(); } - void SHVkShaderModule::AddCallback(SHShaderChangeCallback&& callback) noexcept + void SHVkShaderModule::AddCallback(ChangeCallback&& callback) noexcept { onChangeCallbacks.emplace_back(std::move(callback)); } diff --git a/SHADE_Engine/src/Graphics/Shaders/SHVkShaderModule.h b/SHADE_Engine/src/Graphics/Shaders/SHVkShaderModule.h index e0e1a2fb..341b1706 100644 --- a/SHADE_Engine/src/Graphics/Shaders/SHVkShaderModule.h +++ b/SHADE_Engine/src/Graphics/Shaders/SHVkShaderModule.h @@ -16,7 +16,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* TYPE DEFINITIONS */ /*-----------------------------------------------------------------------*/ - using SHShaderChangeCallback = std::function; + using ChangeCallback = std::function; private: /*-----------------------------------------------------------------------*/ @@ -47,12 +47,13 @@ namespace SHADE //! response to call all the functions that need to be called. Specifically //! pipeline layouts that need to re-parse the newly reflected data and create //! descriptor set layouts and push constant ranges. - std::vector onChangeCallbacks; + std::vector onChangeCallbacks; // #NoteToSelf: From Tomas module, pipeline shader stage create info isn't created here // because the struct allows specialization info which should not be part of a module itself. // This struct should be created in the pipeline instead. + void Recompile (void) noexcept; public: /*-----------------------------------------------------------------------*/ @@ -67,8 +68,8 @@ namespace SHADE /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ void Reflect (void) noexcept; - void OnChange (void) noexcept; - void AddCallback (SHShaderChangeCallback&& callback) noexcept; + void OnChange (std::vector const& newBinaryData) noexcept; + void AddCallback (ChangeCallback&& callback) noexcept; /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */