Auto stash before merge of "SP3-1-Rendering" and "origin/SP3-1-Rendering"

WIP Hot reload
This commit is contained in:
Brandon Mak 2023-02-22 19:51:50 +08:00
parent ff76704a86
commit 4dd496a6e8
9 changed files with 78 additions and 39 deletions

View File

@ -7,14 +7,14 @@ namespace SHADE
{ {
struct SHCompileAssetEvent struct SHCompileAssetEvent
{ {
//! Name of the shader. Should just contain stem from file path. //! Name of the asset (where applicable)
std::string shaderName; std::string assetName;
//! NEw binary data for shader module to use //! asset ID of the asset
std::vector<uint32_t> newBinaryData; AssetID assetID;
//! Extension to check for type //! type of the asset
std::string ext; AssetType assetType;
}; };
} }

View File

@ -11,7 +11,6 @@
#include "SHpch.h" #include "SHpch.h"
#include "SHShaderSourceCompiler.h" #include "SHShaderSourceCompiler.h"
#include "shaderc/shaderc.hpp" #include "shaderc/shaderc.hpp"
#include "Assets/Events/SHAssetManagerEvents.h"
#include "Events/SHEventManager.hpp" #include "Events/SHEventManager.hpp"
#include <fstream> #include <fstream>
@ -142,14 +141,6 @@ namespace SHADE
return{}; return{};
} }
SHCompileAssetEvent compileShaderEvent
{
.shaderName = std::filesystem::path (data->name).stem().string(),
.newBinaryData = data->spirvBinary,
.ext = GLSL_EXTENSION.data(),
};
SHEventManager::BroadcastEvent<SHCompileAssetEvent>(compileShaderEvent, SH_ASSET_COMPILE_EVENT);
return CompileShaderSourceToBinary(path, *data); return CompileShaderSourceToBinary(path, *data);
} }

View File

@ -28,6 +28,8 @@
#include "Filesystem/SHFileSystem.h" #include "Filesystem/SHFileSystem.h"
#include <rttr/registration.h> #include <rttr/registration.h>
#include "Assets/Events/SHAssetManagerEvents.h"
#include "Events/SHEventManager.hpp"
namespace SHADE namespace SHADE
{ {
@ -458,6 +460,14 @@ namespace SHADE
else else
{ {
target = GetAssetIDFromPath(path); target = GetAssetIDFromPath(path);
// send compile asset event
SHCompileAssetEvent compileShaderEvent
{
.assetName = newPath.filename().stem().string(),
.assetID = id,
.assetType = AssetType::SHADER,
};
SHEventManager::BroadcastEvent<SHCompileAssetEvent>(compileShaderEvent, SH_ASSET_COMPILE_EVENT);
} }
//TODO SEND EVENT HERE //TODO SEND EVENT HERE

View File

@ -893,15 +893,21 @@ namespace SHADE
{ {
auto const& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHCompileAssetEvent>*>(eventPtr.get())->data; auto const& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHCompileAssetEvent>*>(eventPtr.get())->data;
// check for asset type
if (EVENT_DATA->assetType == AssetType::SHADER)
{
// loop through all shaders
auto denseIterators = SHVkInstance::GetResourceManager().GetDenseAccess<SHVkShaderModule>(); auto denseIterators = SHVkInstance::GetResourceManager().GetDenseAccess<SHVkShaderModule>();
for (auto it = denseIterators.first; it != denseIterators.second; ++it) for (auto it = denseIterators.first; it != denseIterators.second; ++it)
{ {
if (it->GetName() == EVENT_DATA->shaderName) if (it->GetName() == EVENT_DATA->assetName)
{ {
it->OnChange(); auto* shaderAsset = SHAssetManager::GetData<SHShaderAsset>(EVENT_DATA->assetID);
it->OnChange(shaderAsset->spirvBinary);
break; break;
} }
} }
}
return eventPtr->handle; return eventPtr->handle;
} }

View File

@ -235,6 +235,9 @@ namespace SHADE
, pipelineLayout { inPipelineLayout } , pipelineLayout { inPipelineLayout }
, created {false} , created {false}
{ {
if (pipelineLayout)
pipelineLayout->AddCallback([this]() {ConstructPipeline();});
// We want to create a pipeline // We want to create a pipeline
if (state != nullptr) if (state != nullptr)
{ {

View File

@ -450,6 +450,15 @@ namespace SHADE
} }
else else
SHVulkanDebugUtil::ReportVkSuccess("Successfully created Pipeline Layout. "); 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<Handle<SHVkShaderModule>> const& SHVkPipelineLayout::GetShaderModules(void) const noexcept std::vector<Handle<SHVkShaderModule>> const& SHVkPipelineLayout::GetShaderModules(void) const noexcept

View File

@ -10,6 +10,9 @@ namespace SHADE
class SHVkPipelineLayout class SHVkPipelineLayout
{ {
public:
using ChangeCallback = std::function<void()>;
private: private:
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */ /* PRIVATE MEMBER VARIABLES */
@ -51,6 +54,12 @@ namespace SHADE
//! Store for pipeline layout recreation //! Store for pipeline layout recreation
std::vector<vk::DescriptorSetLayout> vkDescriptorSetLayoutsPipeline; std::vector<vk::DescriptorSetLayout> 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<ChangeCallback> onChangeCallbacks;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER FUNCTIONS */ /* PRIVATE MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -73,6 +82,7 @@ namespace SHADE
/* PUBLIC MEMBER FUNCTIONS */ /* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
void RecreateIfNeeded (void) noexcept; void RecreateIfNeeded (void) noexcept;
void AddCallback(ChangeCallback&& callback) noexcept;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */ /* SETTERS AND GETTERS */

View File

@ -7,20 +7,16 @@
namespace SHADE namespace SHADE
{ {
SHVkShaderModule::SHVkShaderModule(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, std::vector<uint32_t> const& binaryData, std::string inEntryPoint, vk::ShaderStageFlagBits stage, std::string const& name) noexcept void SHVkShaderModule::Recompile(void) noexcept
: logicalDeviceHdl {inLogicalDeviceHdl}
, shaderStage {stage}
, entryPoint {inEntryPoint}
, vkShaderModule {nullptr}
, spirvBinary{}
, shaderName {name}
, reflectedData {}
{ {
if (vkShaderModule)
logicalDeviceHdl->GetVkLogicalDevice().destroyShaderModule(vkShaderModule, nullptr);
// Prepare the create info // Prepare the create info
vk::ShaderModuleCreateInfo moduleCreateInfo vk::ShaderModuleCreateInfo moduleCreateInfo
{ {
.codeSize = binaryData.size() * sizeof (uint32_t), .codeSize = spirvBinary.size() * sizeof(uint32_t),
.pCode = binaryData.data(), .pCode = spirvBinary.data(),
}; };
if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createShaderModule(&moduleCreateInfo, nullptr, &vkShaderModule); result != vk::Result::eSuccess) if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createShaderModule(&moduleCreateInfo, nullptr, &vkShaderModule); result != vk::Result::eSuccess)
@ -30,10 +26,18 @@ namespace SHADE
} }
else else
SHVulkanDebugUtil::ReportVkSuccess("Successfully created shader module."); 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 SHVkShaderModule::SHVkShaderModule(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, std::vector<uint32_t> const& binaryData, std::string inEntryPoint, vk::ShaderStageFlagBits stage, std::string const& name) noexcept
// shader modules only need 1 of themselves. : logicalDeviceHdl {inLogicalDeviceHdl}
spirvBinary = binaryData; , shaderStage {stage}
, entryPoint {inEntryPoint}
, vkShaderModule {nullptr}
, spirvBinary{binaryData}
, shaderName {name}
, reflectedData {}
{
Recompile();
} }
SHVkShaderModule::SHVkShaderModule(SHVkShaderModule&& rhs) noexcept SHVkShaderModule::SHVkShaderModule(SHVkShaderModule&& rhs) noexcept
@ -81,13 +85,18 @@ namespace SHADE
} }
} }
void SHVkShaderModule::OnChange(void) noexcept void SHVkShaderModule::OnChange(std::vector<uint32_t> const& newBinaryData) noexcept
{ {
// assign new binary data and recompile shader
spirvBinary = newBinaryData;
Recompile();
for (auto& callback : onChangeCallbacks) for (auto& callback : onChangeCallbacks)
callback(); callback();
} }
void SHVkShaderModule::AddCallback(SHShaderChangeCallback&& callback) noexcept void SHVkShaderModule::AddCallback(ChangeCallback&& callback) noexcept
{ {
onChangeCallbacks.emplace_back(std::move(callback)); onChangeCallbacks.emplace_back(std::move(callback));
} }

View File

@ -16,7 +16,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* TYPE DEFINITIONS */ /* TYPE DEFINITIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
using SHShaderChangeCallback = std::function<void()>; using ChangeCallback = std::function<void()>;
private: private:
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -47,12 +47,13 @@ namespace SHADE
//! response to call all the functions that need to be called. Specifically //! 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 //! pipeline layouts that need to re-parse the newly reflected data and create
//! descriptor set layouts and push constant ranges. //! descriptor set layouts and push constant ranges.
std::vector<SHShaderChangeCallback> onChangeCallbacks; std::vector<ChangeCallback> onChangeCallbacks;
// #NoteToSelf: From Tomas module, pipeline shader stage create info isn't created here // #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. // because the struct allows specialization info which should not be part of a module itself.
// This struct should be created in the pipeline instead. // This struct should be created in the pipeline instead.
void Recompile (void) noexcept;
public: public:
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -67,8 +68,8 @@ namespace SHADE
/* PUBLIC MEMBER FUNCTIONS */ /* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
void Reflect (void) noexcept; void Reflect (void) noexcept;
void OnChange (void) noexcept; void OnChange (std::vector<uint32_t> const& newBinaryData) noexcept;
void AddCallback (SHShaderChangeCallback&& callback) noexcept; void AddCallback (ChangeCallback&& callback) noexcept;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */ /* SETTERS AND GETTERS */