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

This commit is contained in:
Brandon Mak 2022-09-18 22:34:48 +08:00
parent 96ec1afcdd
commit 28a5f8e4e5
20 changed files with 285 additions and 170 deletions

View File

@ -37,6 +37,7 @@ namespace Sandbox
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
SHADE::SHSystemManager::CreateSystem<SHADE::SHGraphicsSystem>();
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::BatcherDispatcherRoutine>(1);
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::BeginRoutine>(1);
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::RenderRoutine>(1);
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::EndRoutine>(1);

View File

@ -486,7 +486,7 @@ namespace SHADE
*/
/***************************************************************************/
Handle<SHVkPipeline> SHVkLogicalDevice::CreatePipeline(Handle<SHVkPipelineLayout> const& pipelineLayoutHdl, SHVkPipelineState const* const state, Handle<SHVkRenderpass> const& renderpassHdl, uint32_t subpass, SH_PIPELINE_TYPE type) noexcept
Handle<SHVkPipeline> SHVkLogicalDevice::CreatePipeline(Handle<SHVkPipelineLayout> const& pipelineLayoutHdl, SHVkPipelineState const* const state, Handle<SHVkRenderpass> const& renderpassHdl, Handle<SHSubpass> subpass, SH_PIPELINE_TYPE type) noexcept
{
return SHVkInstance::GetResourceManager().Create <SHVkPipeline>(GetHandle(), pipelineLayoutHdl, state, renderpassHdl, subpass, type);

View File

@ -39,6 +39,7 @@ namespace SHADE
class SHVkImageView;
class SHShaderBlockInterface;
class SHVkDescriptorSetGroup;
class SHSubpass;
/***************************************************************************/
/*!
@ -167,7 +168,7 @@ namespace SHADE
Handle<SHVkPipelineLayout> const& pipelineLayoutHdl,
SHVkPipelineState const* const state,
Handle<SHVkRenderpass> const& renderpassHdl,
uint32_t subpass,
Handle<SHSubpass> subpass,
SH_PIPELINE_TYPE type
) noexcept;

View File

@ -29,7 +29,7 @@ namespace SHADE
/* SHBatch - Usage Functions */
/*---------------------------------------------------------------------------------*/
SHBatch::SHBatch(Handle<SHVkPipeline> pipeline)
: pipeline { pipeline }
: pipeline{ pipeline }
{
if (!pipeline)
throw std::invalid_argument("Attempted to create a SHBatch with an invalid SHPipeline!");
@ -59,8 +59,8 @@ namespace SHADE
// Check if we have a SubBatch with the same mesh yet
auto subBatch = std::find_if(subBatches.begin(), subBatches.end(), [&](const SHSubBatch& batch)
{
return batch.Mesh == renderable->Mesh;
});
return batch.Mesh == renderable->Mesh;
});
// Attempt to remove if it exists
if (subBatch == subBatches.end())
@ -127,13 +127,13 @@ namespace SHADE
{
// Create command
drawData.emplace_back(vk::DrawIndexedIndirectCommand
{
.indexCount = subBatch.Mesh->IndexCount,
.instanceCount = static_cast<uint32_t>(subBatch.Renderables.size()),
.firstIndex = subBatch.Mesh->FirstIndex,
.vertexOffset = subBatch.Mesh->FirstVertex,
.firstInstance = nextInstanceIndex
});
{
.indexCount = subBatch.Mesh->IndexCount,
.instanceCount = static_cast<uint32_t>(subBatch.Renderables.size()),
.firstIndex = subBatch.Mesh->FirstIndex,
.vertexOffset = subBatch.Mesh->FirstVertex,
.firstInstance = nextInstanceIndex
});
// Fill in buffers (CPU)
for (const SHRenderable* renderable : subBatch.Renderables)

View File

@ -22,16 +22,16 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
#include "Graphics/Pipeline/SHVkPipeline.h"
#include "ECS_Base/Managers/SHComponentManager.h"
#include "Tools/SHLogger.h"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Lifecycle Functions */
/*---------------------------------------------------------------------------------*/
void SHBatcher::Init(const std::vector<SHRenderable>& _renderables, Handle<SHRenderGraph> _renderGraph)
void SHBatcher::Init(Handle<SHRenderGraph> _renderGraph)
{
renderables = &_renderables;
renderGraph = _renderGraph;
renderGraph = _renderGraph;
}
/*---------------------------------------------------------------------------------*/
@ -39,53 +39,56 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
void SHBatcher::PrepareBatches()
{
// Iterate through all renderables and send it into the batching
auto& renderables = SHComponentManager::GetDense<SHRenderable>();
// Iterate through all renderables and send it into the batching
auto& renderables = SHComponentManager::GetDense<SHRenderable>();
for (auto iter = renderables.cbegin(); iter != renderables.cend(); ++iter)
{
AddToBatch(iter->GetHandle());
AddToBatch(&(*iter));
}
}
void SHBatcher::AddToBatch(Handle<SHRenderable> renderable)
void SHBatcher::AddToBatch(SHRenderable const* renderable)
{
// Get Subpass Index for this renderables pipeline
const SHSubPassIndex SUB_PASS_IDX = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpassIndex();
const Handle<SHSubpass> SUBPASS = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass();
// Check if there is a SuperBatch for the specific RenderPass
auto superBatch = std::find_if(superBatches.begin(), superBatches.end(), [&](const SHSuperBatch& superBatch)
// Check if there is a SuperBatch for the specific Subpass
auto superBatch = std::find_if(superBatches.begin(), superBatches.end(), [&](Handle<SHSuperBatch> superBatch)
{
return superBatch.GetSubpassId() == SUB_PASS_IDX;
return superBatch->GetSubpass() == SUBPASS;
});
// Create if it doesn't exist
// Ignore and emit a warning if it doesn't exist
if (superBatch == superBatches.end())
{
superBatches.emplace_back(SUB_PASS_IDX);
superBatch = superBatches.end();
SHLOG_WARNING("A renderable was attempted to be added to a SuperBatch which does not exist.");
return;
}
// Add the Renderable
superBatch->Add(renderable->GetHandle());
(*superBatch)->Add(renderable);
}
void SHBatcher::RemoveFromBatch(Handle<SHRenderable> renderable)
void SHBatcher::RemoveFromBatch(SHRenderable const* renderable)
{
// Get Subpass Index for this renderables pipeline
const SHSubPassIndex SUB_PASS_IDX = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpassIndex();
const Handle<SHSubpass> SUBPASS = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass();
// Check if there is a SuperBatch for the specific RenderPass
auto superBatch = std::find_if(superBatches.begin(), superBatches.end(), [&](const SHSuperBatch& superBatch)
auto superBatch = std::find_if(superBatches.begin(), superBatches.end(), [&](Handle<SHSuperBatch> superBatch)
{
return superBatch.GetSubpassId() == SUB_PASS_IDX;
return superBatch->GetSubpass() == SUBPASS;
});
// Remove if it exists
if (superBatch == superBatches.end())
{
SHLOG_WARNING("A renderable was attempted to be removed from a SuperBatch which does not exist.");
return;
}
superBatch->Remove(renderable);
(*superBatch)->Remove(renderable);
}
void SHBatcher::FinaliseBatches(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer)
@ -93,7 +96,7 @@ namespace SHADE
// Build SuperBatches
for (auto& batch : superBatches)
{
batch.Build(device, cmdBuffer);
batch->Build(device, cmdBuffer);
}
}
@ -101,9 +104,23 @@ namespace SHADE
{
for (auto& batch : superBatches)
{
batch.Clear();
batch->Clear();
}
superBatches.clear();
}
void SHBatcher::RegisterSuperBatch(Handle<SHSuperBatch> superBatch)
{
superBatches.emplace_back(superBatch);
}
void SHBatcher::DeregisterSuperBatch(Handle<SHSuperBatch> superBatch)
{
auto sbIter = std::find(superBatches.begin(), superBatches.end(), superBatch);
if (sbIter == superBatches.end())
return;
superBatches.erase(sbIter);
}
}

View File

@ -43,21 +43,23 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/
/* Lifecycle Functions */
/*-----------------------------------------------------------------------------*/
void Init(const std::vector<SHRenderable>& _renderables, Handle<SHRenderGraph> _renderGraph);
void Init(Handle<SHRenderGraph> _renderGraph);
/*-----------------------------------------------------------------------------*/
/* Usage Functions */
/*-----------------------------------------------------------------------------*/
void PrepareBatches();
void AddToBatch(Handle<SHRenderable> renderable);
void RemoveFromBatch(Handle<SHRenderable> renderable);
void AddToBatch(SHRenderable const* renderable);
void RemoveFromBatch(SHRenderable const* renderable);
void FinaliseBatches(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer);
void ClearBatches();
void RegisterSuperBatch(Handle<SHSuperBatch> superBatch);
void DeregisterSuperBatch(Handle<SHSuperBatch> superBatch);
private:
const std::vector<SHRenderable>* renderables = nullptr;
Handle<SHRenderGraph> renderGraph;
// Children
std::vector<SHSuperBatch> superBatches;
std::vector<Handle<SHSuperBatch>> superBatches;
};
}

View File

@ -23,8 +23,8 @@ namespace SHADE
/* Constructor/Destructors */
/*---------------------------------------------------------------------------------*/
SHSuperBatch::SHSuperBatch(SHSubPassIndex subPass)
: subpassIndex { subPass }
SHSuperBatch::SHSuperBatch(Handle<SHSubpass> sp)
: subpass { sp }
{}
/*---------------------------------------------------------------------------------*/

View File

@ -47,7 +47,7 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/
/* Constructor/Destructors */
/*-----------------------------------------------------------------------------*/
SHSuperBatch(SHSubPassIndex subPass);
SHSuperBatch(Handle<SHSubpass> sp);
/*-----------------------------------------------------------------------------*/
/* Usage Functions */
@ -61,16 +61,15 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/
/* Getter Functions */
/*-----------------------------------------------------------------------------*/
SHSubPassIndex GetSubpassId() const noexcept { return subpassIndex; };
Handle<SHSubpass> GetSubpass() const noexcept { return subpass; };
private:
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
// Batch Properties
SHSubPassIndex subpassIndex;
Handle<SHSubpass> subpass;
// Children
std::vector<SHBatch> batches;
};
}

View File

@ -24,6 +24,9 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/Pipeline/SHVkPipeline.h"
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
#include "ECS_Base/Managers/SHComponentManager.h"
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Graphics/MiddleEnd/Batching/SHSuperBatch.h"
namespace SHADE
{
@ -322,7 +325,7 @@ namespace SHADE
viewports.erase(iter);
}
Handle<SHMaterial> SHGraphicsSystem::AddMaterial(Handle<SHVkShaderModule> vertShader, Handle<SHVkShaderModule> fragShader, Handle<SHRenderGraphNode::SHSubpass> subpass)
Handle<SHMaterial> SHGraphicsSystem::AddMaterial(Handle<SHVkShaderModule> vertShader, Handle<SHVkShaderModule> fragShader, Handle<SHSubpass> subpass)
{
// Retrieve pipeline from pipeline storage or create if unavailable
auto shaderPair = std::make_pair(vertShader, fragShader);
@ -331,7 +334,7 @@ namespace SHADE
auto mat = resourceManager.Create<SHMaterial>();
auto renderGraphNode = subpass->GetParentNode();
auto pipeline = renderGraphNode->GetOrCreatePipeline(std::make_pair(vertShader, fragShader), subpass->GetIndex());
auto pipeline = renderGraphNode->GetOrCreatePipeline(std::make_pair(vertShader, fragShader), subpass);
mat->SetPipeline(pipeline);
@ -449,10 +452,27 @@ namespace SHADE
{
reinterpret_cast<SHGraphicsSystem*>(system)->Run(dt);
}
void SHGraphicsSystem::EndRoutine::Execute(double) noexcept
{
reinterpret_cast<SHGraphicsSystem*>(system)->EndRender();
}
void SHGraphicsSystem::BatcherDispatcherRoutine::Execute(double) noexcept
{
auto& renderables = SHComponentManager::GetDense<SHRenderable>();
for (auto& renderable : renderables)
{
if (!renderable.WasMaterialChanged())
continue;
// Remove from old material's SuperBatch
Handle<SHSuperBatch> oldSuperBatch = renderable.GetPrevMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch();
oldSuperBatch->Remove(&renderable);
// Add to new SuperBatch
Handle<SHSuperBatch> newSuperBatch = renderable.GetMaterial()->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch();
newSuperBatch->Add(&renderable);
}
}
}

View File

@ -75,6 +75,11 @@ namespace SHADE
public:
virtual void Execute(double dt) noexcept override final;
};
class SH_API BatcherDispatcherRoutine final : public SHSystemRoutine
{
public:
virtual void Execute(double dt) noexcept override final;
};
public:
/*-----------------------------------------------------------------------------*/
@ -110,7 +115,7 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/
/* Material Creation Functions */
/*-----------------------------------------------------------------------------*/
Handle<SHMaterial> AddMaterial(Handle<SHVkShaderModule> vertShader, Handle<SHVkShaderModule> fragShader, Handle<SHRenderGraphNode::SHSubpass> subpass);
Handle<SHMaterial> AddMaterial(Handle<SHVkShaderModule> vertShader, Handle<SHVkShaderModule> fragShader, Handle<SHSubpass> subpass);
void RemoveMaterial(Handle<SHMaterial> material);;
Handle<SHMaterialInstance> AddMaterialInstance(Handle<SHMaterial> material);
void RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance);

View File

@ -18,7 +18,19 @@ of DigiPen Institute of Technology is prohibited.
namespace SHADE
{
void SHRenderable::SetMaterial(Handle<SHMaterialInstance> materialInstance)
/*-----------------------------------------------------------------------------------*/
/* SHComponent Lifecycle Functions */
/*-----------------------------------------------------------------------------------*/
void SHRenderable::OnCreate()
{
materialChanged = true;
sharedMaterial = {};
material = {};
oldMaterial = {};
}
void SHRenderable::OnDestroy()
{
if (material)
{
@ -26,7 +38,33 @@ namespace SHADE
material = {};
}
sharedMaterial = materialInstance;
// Remove from SuperBatch
Handle<SHSuperBatch> superBatch = sharedMaterial->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch();
superBatch->Remove(this);
}
/*-----------------------------------------------------------------------------------*/
/* Material Functions */
/*-----------------------------------------------------------------------------------*/
void SHRenderable::SetMaterial(Handle<SHMaterialInstance> materialInstance)
{
// Ignore if same material set
if (!material && sharedMaterial == materialInstance)
return;
// Free copies of materials if any
if (material)
{
material.Free();
material = {};
}
// Flag that material was changed
materialChanged = true;
oldMaterial = sharedMaterial->GetBaseMaterial();
// Update the material
sharedMaterial = materialInstance;
}
Handle<SHMaterialInstance> SHRenderable::GetMaterial() const

View File

@ -23,6 +23,7 @@ namespace SHADE
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHMaterialInstance;
class SHMaterial;
class SHMesh;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
@ -33,16 +34,28 @@ namespace SHADE
Represents an object that should be rendered.
*/
/*************************************************************************************/
class SHRenderable : public SHComponent, public ISelfHandle<SHRenderable>
class SHRenderable final : public SHComponent
{
public:
/*-------------------------------------------------------------------------------*/
/* Usage Functions */
/* SHComponent Lifecycle Functions */
/*-------------------------------------------------------------------------------*/
void SetMaterial(Handle<SHMaterialInstance> materialInstance);
void OnCreate() override final;
void OnDestroy() override final;
/*-------------------------------------------------------------------------------*/
/* Material Functions */
/*-------------------------------------------------------------------------------*/
void SetMaterial(Handle<SHMaterialInstance> materialInstance);
Handle<SHMaterialInstance> GetMaterial() const;
Handle<SHMaterialInstance> GetModifiableMaterial();
/*-------------------------------------------------------------------------------*/
/* Getter Functions */
/*-------------------------------------------------------------------------------*/
bool WasMaterialChanged() const noexcept { return materialChanged; }
Handle<SHMaterial> GetPrevMaterial() const noexcept { return oldMaterial; }
/*-------------------------------------------------------------------------------*/
/* Data Members */
/*-------------------------------------------------------------------------------*/
@ -55,6 +68,8 @@ namespace SHADE
/*-------------------------------------------------------------------------------*/
Handle<SHMaterialInstance> sharedMaterial;
Handle<SHMaterialInstance> material;
bool materialChanged = true;
Handle<SHMaterial> oldMaterial;
};
}

View File

@ -5,7 +5,7 @@
namespace SHADE
{
Handle<SHVkPipeline> SHPipelineLibrary::CreateDrawPipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHVkRenderpass> renderpass, uint32_t subpass) noexcept
Handle<SHVkPipeline> SHPipelineLibrary::CreateDrawPipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHVkRenderpass> renderpass, Handle<SHSubpass> subpass) noexcept
{
SHPipelineLayoutParams params
{

View File

@ -9,6 +9,7 @@ namespace SHADE
class SHVRenderpass;
class SHVkDescriptorSetLayouts;
class SHVkPipeline;
class SHSubpass;
// Pipeline library is a PURELY MIDDLE END SYSTEM. It is responsible for only creating pipelines from shaders and caching
@ -37,7 +38,7 @@ namespace SHADE
Handle<SHVkPipeline> CreateDrawPipeline (
std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair,
Handle<SHVkRenderpass> renderpass,
uint32_t subpass
Handle<SHSubpass> subpass
) noexcept;
Handle<SHVkPipeline> GetDrawPipline (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
bool CheckDrawPipelineExistence (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;

View File

@ -1,5 +1,6 @@
#include "SHPch.h"
#include "SHPipelineState.h"
#include "Graphics/RenderGraph/SHRenderGraph.h"
namespace SHADE
{
@ -61,10 +62,10 @@ namespace SHADE
renderpassHdl = inRenderpassHdl;
}
void SHVkPipelineState::SetSubpassIndex(uint32_t index) noexcept
void SHVkPipelineState::SetSubpass(Handle<SHSubpass> sp) noexcept
{
dirty = true;
subpassIndex = index;
subpass = sp;
}
SHVertexInputState const& SHVkPipelineState::GetVertexInputState(void) const noexcept
@ -107,9 +108,9 @@ namespace SHADE
return renderpassHdl;
}
SHSubPassIndex SHVkPipelineState::GetSubpassIndex(void) const noexcept
Handle<SHSubpass> SHVkPipelineState::GetSubpass(void) noexcept
{
return subpassIndex;
return subpass;
}
void SHVkPipelineState::SetDirty(bool isDirty) noexcept

View File

@ -8,6 +8,8 @@
namespace SHADE
{
class SHSubpass;
// This is mainly for non-interleaved attributes where we have a separate buffer for
// each vertex attribute.
struct SHVertexInputState
@ -152,31 +154,31 @@ namespace SHADE
bool dirty{ false };
//! Vertex input state
SHVertexInputState vertexInputState;
SHVertexInputState vertexInputState;
//! Input assembly
SHInputAssemblyState inputAssemblyState;
SHInputAssemblyState inputAssemblyState;
//! Rasterization state
SHRasterizationState rasterizationState;
SHRasterizationState rasterizationState;
//! Viewport state
SHViewportState viewportState;
SHViewportState viewportState;
//! Multisample state
SHMultisampleState multisampleState;
SHMultisampleState multisampleState;
//! Depth Stencil state
SHDepthStencilState depthStencilState;
SHDepthStencilState depthStencilState;
//! Color blend state
SHColorBlendState colorBlendState;
SHColorBlendState colorBlendState;
//! Renderpass that is compatible with the pipeline
Handle<SHVkRenderpass> renderpassHdl;
Handle<SHVkRenderpass> renderpassHdl;
//! Subpass index
uint32_t subpassIndex;
Handle<SHSubpass> subpass;
friend class SHVkPipeline;
public:
@ -198,17 +200,17 @@ namespace SHADE
void SetDepthStencilState (SHDepthStencilState const& state) noexcept;
void SetColorBlenState (SHColorBlendState const& state) noexcept;
void SetRenderpass (Handle<SHVkRenderpass> const& inRenderpassHdl) noexcept;
void SetSubpassIndex (uint32_t index) noexcept;
void SetSubpass (Handle<SHSubpass> sp) noexcept;
SHVertexInputState const& GetVertexInputState (void) const noexcept;
SHInputAssemblyState const& GetInputAssemblyState (void) const noexcept;
SHRasterizationState const& GetRasterizationState (void) const noexcept;
SHViewportState const& GetViewportState (void) const noexcept;
SHMultisampleState const& GetMultisampleState (void) const noexcept;
SHDepthStencilState const& GetDepthStencilState (void) const noexcept;
SHColorBlendState const& GetColorBlenState (void) const noexcept;
Handle<SHVkRenderpass> const& GetRenderpass (void) const noexcept;
SHSubPassIndex GetSubpassIndex (void) const noexcept;
SHVertexInputState const& GetVertexInputState (void) const noexcept;
SHInputAssemblyState const& GetInputAssemblyState (void) const noexcept;
SHRasterizationState const& GetRasterizationState (void) const noexcept;
SHViewportState const& GetViewportState (void) const noexcept;
SHMultisampleState const& GetMultisampleState (void) const noexcept;
SHDepthStencilState const& GetDepthStencilState (void) const noexcept;
SHColorBlendState const& GetColorBlenState (void) const noexcept;
Handle<SHVkRenderpass> const& GetRenderpass (void) const noexcept;
Handle<SHSubpass> GetSubpass (void) noexcept;
void SetDirty(bool isDirty) noexcept;
};

View File

@ -3,6 +3,7 @@
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/Shaders/SHVkShaderModule.h"
#include "Graphics/Debugging/SHVulkanDebugUtil.h"
#include "Graphics/RenderGraph/SHRenderGraph.h"
namespace SHADE
{
@ -154,7 +155,7 @@ namespace SHADE
gpCreateInfo.layout = pipelineLayout->GetVkPipelineLayout();
gpCreateInfo.renderPass = pipelineState.GetRenderpass()->GetVkRenderpass();
gpCreateInfo.subpass = pipelineState.GetSubpassIndex();
gpCreateInfo.subpass = pipelineState.GetSubpass()->GetIndex();
gpCreateInfo.basePipelineHandle = VK_NULL_HANDLE;
gpCreateInfo.basePipelineIndex = -1;
@ -204,7 +205,7 @@ namespace SHADE
*/
/***************************************************************************/
SHVkPipeline::SHVkPipeline(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkPipelineLayout> const& inPipelineLayout, SHVkPipelineState const* const state, Handle<SHVkRenderpass> const& renderpassHdl, uint32_t subpass, SH_PIPELINE_TYPE type) noexcept
SHVkPipeline::SHVkPipeline(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkPipelineLayout> const& inPipelineLayout, SHVkPipelineState const* const state, Handle<SHVkRenderpass> const& renderpassHdl, Handle<SHSubpass> subpass, SH_PIPELINE_TYPE type) noexcept
: pipelineState{ } // copy the pipeline state
, pipelineType {type}
, vkPipeline {VK_NULL_HANDLE}
@ -222,8 +223,8 @@ namespace SHADE
}
else
{
pipelineState.SetRenderpass(renderpassHdl);
pipelineState.SetSubpassIndex(subpass);
pipelineState.SetRenderpass (renderpassHdl);
pipelineState.SetSubpass (subpass);
}
}

View File

@ -9,6 +9,7 @@
namespace SHADE
{
class SHVkLogicalDevice;
class SHSubpass;
class SHVkPipeline
{
@ -50,7 +51,7 @@ namespace SHADE
Handle<SHVkPipelineLayout> const& inPipelineLayout,
SHVkPipelineState const* const state,
Handle<SHVkRenderpass> const& renderpassHdl,
uint32_t subpass,
Handle<SHSubpass> subpass,
SH_PIPELINE_TYPE type) noexcept;
SHVkPipeline (SHVkPipeline&& rhs) noexcept;

View File

@ -209,13 +209,13 @@ namespace SHADE
*/
/***************************************************************************/
SHRenderGraphNode::SHSubpass::SHSubpass(Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
SHSubpass::SHSubpass(ResourceManager& rm, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
: resourceAttachmentMapping{ mapping }
, ptrToResources{ resources }
, parentNode{ parent }
, subpassIndex {index}
{
superBatch = rm.Create<SHSuperBatch>(GetHandle());
}
/***************************************************************************/
@ -229,7 +229,7 @@ namespace SHADE
*/
/***************************************************************************/
SHRenderGraphNode::SHSubpass::SHSubpass(SHSubpass&& rhs) noexcept
SHSubpass::SHSubpass(SHSubpass&& rhs) noexcept
: colorReferences{ std::move(rhs.colorReferences) }
, depthReferences{ std::move(rhs.depthReferences) }
, inputReferences{ std::move(rhs.inputReferences) }
@ -250,7 +250,7 @@ namespace SHADE
*/
/***************************************************************************/
SHRenderGraphNode::SHSubpass& SHRenderGraphNode::SHSubpass::operator=(SHSubpass&& rhs) noexcept
SHSubpass& SHSubpass::operator=(SHSubpass&& rhs) noexcept
{
if (this == &rhs)
return *this;
@ -276,7 +276,7 @@ namespace SHADE
*/
/***************************************************************************/
void SHRenderGraphNode::SHSubpass::AddColorOutput(std::string resourceToReference) noexcept
void SHSubpass::AddColorOutput(std::string resourceToReference) noexcept
{
colorReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eColorAttachmentOptimal });
}
@ -297,7 +297,7 @@ namespace SHADE
*/
/***************************************************************************/
void SHRenderGraphNode::SHSubpass::AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType) noexcept
void SHSubpass::AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType) noexcept
{
vk::ImageLayout imageLayout;
switch (attachmentDescriptionType)
@ -330,12 +330,12 @@ namespace SHADE
*/
/***************************************************************************/
void SHRenderGraphNode::SHSubpass::AddInput(std::string resourceToReference) noexcept
void SHSubpass::AddInput(std::string resourceToReference) noexcept
{
inputReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal });
}
void SHRenderGraphNode::SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer) noexcept
void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer) noexcept
{
// Draw all the batches
@ -346,7 +346,7 @@ namespace SHADE
}
}
void SHRenderGraphNode::SHSubpass::AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept
void SHSubpass::AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept
{
exteriorDrawCalls.push_back(newDrawCall);
}
@ -362,16 +362,21 @@ namespace SHADE
*/
/***************************************************************************/
Handle<SHRenderGraphNode> const& SHRenderGraphNode::SHSubpass::GetParentNode(void) const noexcept
Handle<SHRenderGraphNode> const& SHSubpass::GetParentNode(void) const noexcept
{
return parentNode;
}
SHADE::SHSubPassIndex SHRenderGraphNode::SHSubpass::GetIndex() const noexcept
SHADE::SHSubPassIndex SHSubpass::GetIndex() const noexcept
{
return subpassIndex;
}
Handle<SHSuperBatch> SHSubpass::GetSuperBatch(void) const noexcept
{
return superBatch;
}
/***************************************************************************/
/*!
@ -544,7 +549,7 @@ namespace SHADE
*/
/***************************************************************************/
Handle<SHRenderGraphNode::SHSubpass> SHRenderGraphNode::AddSubpass(std::string subpassName) noexcept
Handle<SHSubpass> SHRenderGraphNode::AddSubpass(std::string subpassName) noexcept
{
// if subpass already exists, don't add.
if (subpassIndexing.contains(subpassName))
@ -554,7 +559,7 @@ namespace SHADE
}
// Add subpass to container and create mapping for it
subpasses.emplace_back(resourceManager.Create<SHSubpass>(GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources));
subpasses.emplace_back(resourceManager.Create<SHSubpass>(resourceManager, GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources));
subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u);
return subpasses.at(subpassIndexing[subpassName]);
}
@ -576,10 +581,10 @@ namespace SHADE
commandBuffer->EndRenderpass();
}
Handle<SHVkPipeline> SHRenderGraphNode::GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, uint32_t subpassIndex) noexcept
Handle<SHVkPipeline> SHRenderGraphNode::GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept
{
// verify subpass exists
if (subpassIndex >= subpasses.size() - 1)
if (subpass->GetIndex() >= subpasses.size() - 1)
{
SHLOG_ERROR("Subpass index passed in is not valid. RenderGraphNode does not have that many passes. ");
return {};
@ -592,7 +597,7 @@ namespace SHADE
(
vsFsPair,
renderpass,
subpassIndex
subpass
);
}
@ -615,7 +620,7 @@ namespace SHADE
return renderpass;
}
Handle<SHRenderGraphNode::SHSubpass> SHRenderGraphNode::GetSubpass(std::string_view subpassName) const noexcept
Handle<SHSubpass> SHRenderGraphNode::GetSubpass(std::string_view subpassName) const noexcept
{
return subpasses[subpassIndexing.at(subpassName.data())];
}

View File

@ -5,6 +5,7 @@
#include "Resource/ResourceLibrary.h"
#include "SH_API.h"
#include "Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h"
#include "Graphics/MiddleEnd/Batching/SHSuperBatch.h"
#include <string>
#include <map>
@ -19,6 +20,7 @@ namespace SHADE
class SHVkFramebuffer;
class SHVkCommandPool;
class SHVkCommandBuffer;
class SHRenderGraphNode;
// Used for attachment description creation for renderpass node
enum class SH_ATT_DESC_TYPE
@ -30,6 +32,7 @@ namespace SHADE
DEPTH_STENCIL,
};
class SH_API SHRenderGraphResource
{
private:
@ -70,7 +73,78 @@ namespace SHADE
SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageCreateFlagBits createFlags) noexcept;
SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept;
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
~SHRenderGraphResource (void) noexcept;
~SHRenderGraphResource(void) noexcept;
friend class SHRenderGraphNode;
friend class SHRenderGraph;
};
class SH_API SHSubpass : public ISelfHandle<SHSubpass>
{
private:
/*---------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */
/*---------------------------------------------------------------------*/
//! The index of the subpass in the render graph
uint32_t subpassIndex;
//! The parent renderpass that this subpass belongs to
Handle<SHRenderGraphNode> parentNode;
//!
Handle<SHSuperBatch> superBatch;
//! Color attachments
std::vector<vk::AttachmentReference> colorReferences;
//! Depth attachments
std::vector<vk::AttachmentReference> depthReferences;
//! Input attachments
std::vector<vk::AttachmentReference> inputReferences;
//! For getting attachment reference indices using handles
std::unordered_map<uint64_t, uint32_t> const* resourceAttachmentMapping;
//! Pointer to resources in the render graph (for getting handle IDs)
std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources;
//! Sometimes there exists entities that we want to render onto a render target
//! but don't want it to come from the batching system. An example would be ImGUI.
//! For these entities we want to link a function from the outside and draw them
//! after we draw everything from the batch. Because of this, these draw calls
//! are always the last things drawn, so DO NOT USE THIS FUNCTIONALITY FOR ANYTHING
//! COMPLEX.
std::vector<std::function<void(Handle<SHVkCommandBuffer>&)>> exteriorDrawCalls;
public:
/*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/
SHSubpass(ResourceManager& rm, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources) noexcept;
SHSubpass(SHSubpass&& rhs) noexcept;
SHSubpass& operator=(SHSubpass&& rhs) noexcept;
/*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
// Preparation functions
void AddColorOutput(std::string resourceToReference) noexcept;
void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType = SH_ATT_DESC_TYPE::DEPTH_STENCIL) noexcept;
void AddInput(std::string resourceToReference) noexcept;
// Runtime functions
void Execute(Handle<SHVkCommandBuffer>& commandBuffer) noexcept;
void AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept;
/*-----------------------------------------------------------------------*/
/* GETTERS AND SETTERS */
/*-----------------------------------------------------------------------*/
Handle<SHRenderGraphNode> const& GetParentNode(void) const noexcept;
SHSubPassIndex GetIndex() const noexcept;
Handle<SHSuperBatch> GetSuperBatch (void) const noexcept;
friend class SHRenderGraphNode;
friend class SHRenderGraph;
@ -78,74 +152,6 @@ namespace SHADE
class SH_API SHRenderGraphNode : public ISelfHandle<SHRenderGraphNode>
{
public:
class SH_API SHSubpass
{
public:
/*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/
SHSubpass(Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources) noexcept;
SHSubpass(SHSubpass&& rhs) noexcept;
SHSubpass& operator=(SHSubpass&& rhs) noexcept;
/*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
// Preparation functions
void AddColorOutput (std::string resourceToReference) noexcept;
void AddDepthOutput (std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType = SH_ATT_DESC_TYPE::DEPTH_STENCIL) noexcept;
void AddInput (std::string resourceToReference) noexcept;
// Runtime functions
void Execute (Handle<SHVkCommandBuffer>& commandBuffer) noexcept;
void AddExteriorDrawCalls (std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept;
/*-----------------------------------------------------------------------*/
/* GETTERS AND SETTERS */
/*-----------------------------------------------------------------------*/
Handle<SHRenderGraphNode> const& GetParentNode (void) const noexcept;
SHSubPassIndex GetIndex() const noexcept;
private:
/*---------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */
/*---------------------------------------------------------------------*/
//! The index of the subpass in the render graph
uint32_t subpassIndex;
//! The parent renderpass that this subpass belongs to
Handle<SHRenderGraphNode> parentNode;
//! Color attachments
std::vector<vk::AttachmentReference> colorReferences;
//! Depth attachments
std::vector<vk::AttachmentReference> depthReferences;
//! Input attachments
std::vector<vk::AttachmentReference> inputReferences;
//! For getting attachment reference indices using handles
std::unordered_map<uint64_t, uint32_t> const* resourceAttachmentMapping;
//! Pointer to resources in the render graph (for getting handle IDs)
std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources;
//! Sometimes there exists entities that we want to render onto a render target
//! but don't want it to come from the batching system. An example would be ImGUI.
//! For these entities we want to link a function from the outside and draw them
//! after we draw everything from the batch. Because of this, these draw calls
//! are always the last things drawn, so DO NOT USE THIS FUNCTIONALITY FOR ANYTHING
//! COMPLEX.
std::vector<std::function<void(Handle<SHVkCommandBuffer>&)>> exteriorDrawCalls;
friend class SHRenderGraphNode;
friend class SHRenderGraph;
};
private:
/*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */
@ -219,7 +225,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
Handle<SHSubpass> AddSubpass (std::string subpassName) noexcept;
void Execute (Handle<SHVkCommandBuffer>& commandBuffer, uint32_t frameIndex) noexcept;
Handle<SHVkPipeline> GetOrCreatePipeline (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, uint32_t subpassIndex) noexcept;
Handle<SHVkPipeline> GetOrCreatePipeline (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept;
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */