WIP
This commit is contained in:
parent
e8073bb67f
commit
cc6e2189fa
|
@ -62,6 +62,7 @@ namespace SHADE
|
||||||
system->editorCamera.position -= UP * dt * camera.movementSpeed;
|
system->editorCamera.position -= UP * dt * camera.movementSpeed;
|
||||||
system->editorCamera.dirtyView = true;
|
system->editorCamera.dirtyView = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
system->UpdateCameraComponent(system->editorCamera);
|
system->UpdateCameraComponent(system->editorCamera);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,14 @@ namespace SHADE
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
static constexpr uint32_t PER_INSTANCE = 3;
|
static constexpr uint32_t PER_INSTANCE = 3;
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
DescriptorSet Index for render graph resources.
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr uint32_t RENDERGRAPH_RESOURCE = 4;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -115,6 +115,23 @@ namespace SHADE
|
||||||
graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
|
graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
|
||||||
transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||||
graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: This is VERY temporarily here until a more solid resource management system is implemented
|
||||||
|
shaderSourceLibrary.Init("../../TempShaderFolder/");
|
||||||
|
|
||||||
|
shaderSourceLibrary.LoadShader(0, "TestCubeVs.glsl", SH_SHADER_TYPE::VERTEX, true);
|
||||||
|
shaderSourceLibrary.LoadShader(1, "TestCubeFs.glsl", SH_SHADER_TYPE::FRAGMENT, true);
|
||||||
|
|
||||||
|
shaderSourceLibrary.LoadShader(2, "GreyscaleCs.glsl", SH_SHADER_TYPE::COMPUTE, true);
|
||||||
|
|
||||||
|
shaderModuleLibrary.ImportFromSourceLibrary(device, shaderSourceLibrary);
|
||||||
|
auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl");
|
||||||
|
auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl");
|
||||||
|
auto greyscale = shaderModuleLibrary.GetShaderModule("GreyscaleCs.glsl");
|
||||||
|
cubeVS->Reflect();
|
||||||
|
cubeFS->Reflect();
|
||||||
|
greyscale->Reflect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept
|
void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept
|
||||||
|
@ -166,6 +183,13 @@ namespace SHADE
|
||||||
gBufferWriteSubpass->AddColorOutput("Entity ID");
|
gBufferWriteSubpass->AddColorOutput("Entity ID");
|
||||||
gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL);
|
gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL);
|
||||||
|
|
||||||
|
auto greyscale = shaderModuleLibrary.GetShaderModule("GreyscaleCs.glsl");
|
||||||
|
|
||||||
|
auto greyscaleSubpass = node->AddSubpass("Greyscale Subpass");
|
||||||
|
greyscaleSubpass->AddGeneralInput("Scene");
|
||||||
|
greyscaleSubpass->AddSubpassCompute(greyscale);
|
||||||
|
|
||||||
|
|
||||||
// We do this to just transition our scene layout to shader read
|
// We do this to just transition our scene layout to shader read
|
||||||
auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition");
|
auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition");
|
||||||
sceneLayoutTransitionSubpass->AddInput("Scene");
|
sceneLayoutTransitionSubpass->AddInput("Scene");
|
||||||
|
@ -177,20 +201,11 @@ namespace SHADE
|
||||||
worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
|
worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
|
||||||
worldRenderer->SetCamera(worldCamera);
|
worldRenderer->SetCamera(worldCamera);
|
||||||
|
|
||||||
|
|
||||||
// TODO: This is VERY temporarily here until a more solid resource management system is implemented
|
|
||||||
shaderSourceLibrary.Init("../../TempShaderFolder/");
|
|
||||||
|
|
||||||
shaderSourceLibrary.LoadShader(0, "TestCubeVs.glsl", SH_SHADER_TYPE::VERTEX, true);
|
|
||||||
shaderSourceLibrary.LoadShader(1, "TestCubeFs.glsl", SH_SHADER_TYPE::FRAGMENT, true);
|
|
||||||
|
|
||||||
shaderModuleLibrary.ImportFromSourceLibrary(device, shaderSourceLibrary);
|
|
||||||
auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl");
|
auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl");
|
||||||
auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl");
|
auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl");
|
||||||
cubeVS->Reflect();
|
|
||||||
cubeFS->Reflect();
|
|
||||||
|
|
||||||
defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferWriteSubpass);
|
defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferWriteSubpass);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::InitMiddleEnd(void) noexcept
|
void SHGraphicsSystem::InitMiddleEnd(void) noexcept
|
||||||
|
|
|
@ -171,6 +171,29 @@ namespace SHADE
|
||||||
|
|
||||||
void SHVkPipeline::CreateComputePipeline(void) noexcept
|
void SHVkPipeline::CreateComputePipeline(void) noexcept
|
||||||
{
|
{
|
||||||
|
auto shaderModule = pipelineLayout->GetShaderModules()[0];
|
||||||
|
|
||||||
|
vk::PipelineShaderStageCreateInfo shaderStageCreateInfo
|
||||||
|
{
|
||||||
|
.stage = vk::ShaderStageFlagBits::eCompute,
|
||||||
|
.module = shaderModule->GetVkShaderModule(),
|
||||||
|
.pName = shaderModule->GetEntryPoint().c_str(),
|
||||||
|
};
|
||||||
|
|
||||||
|
vk::ComputePipelineCreateInfo cpCreateInfo
|
||||||
|
{
|
||||||
|
.flags = {},
|
||||||
|
.stage = shaderStageCreateInfo,
|
||||||
|
.layout = pipelineLayout->GetVkPipelineLayout(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createComputePipelines({}, 1, &cpCreateInfo, nullptr, &vkPipeline); result != vk::Result::eSuccess)
|
||||||
|
SHVulkanDebugUtil::ReportVkError(result, "Failed to create Compute Pipeline. ");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHVulkanDebugUtil::ReportVkSuccess("Successfully created a Compute Pipeline. ");
|
||||||
|
created = true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,4 +12,5 @@ namespace SHADE
|
||||||
DEPTH_STENCIL = 0x10,
|
DEPTH_STENCIL = 0x10,
|
||||||
INPUT = 0x20
|
INPUT = 0x20
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "Tools/SHLogger.h"
|
#include "Tools/SHLogger.h"
|
||||||
#include "SHAttachmentDescInitParams.h"
|
#include "SHAttachmentDescInitParams.h"
|
||||||
#include "SHRenderGraphStorage.h"
|
#include "SHRenderGraphStorage.h"
|
||||||
|
#include "Graphics/RenderGraph/SHSubpassCompute.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -78,36 +79,48 @@ namespace SHADE
|
||||||
|
|
||||||
for (uint32_t i = 0; auto& node : nodes)
|
for (uint32_t i = 0; auto& node : nodes)
|
||||||
{
|
{
|
||||||
// key is handle ID, value is pair (first is initial layout, second is final layout).
|
// key is handle ID, value is final layout.
|
||||||
std::unordered_map<uint32_t, vk::ImageLayout> resourceAttLayouts;
|
std::unordered_map<uint32_t, vk::ImageLayout> resourceAttFinalLayouts;
|
||||||
if (node->subpasses.empty())
|
if (node->subpasses.empty())
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Node does not contain a subpass. Cannot configure attachment descriptions as a result. ");
|
SHLOG_ERROR("Node does not contain a subpass. Cannot configure attachment descriptions as a result. ");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// attempt to get all final layouts for all resources
|
||||||
for (auto& subpass : node->subpasses)
|
for (auto& subpass : node->subpasses)
|
||||||
{
|
{
|
||||||
for (auto& color : subpass->colorReferences)
|
for (auto& color : subpass->colorReferences)
|
||||||
{
|
{
|
||||||
|
// If final renderpass and attachment is a COLOR_PRESENT resource, make resource transition to present after last subpass
|
||||||
if (i == nodes.size() - 1 && (node->attResources[color.attachment]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)))
|
if (i == nodes.size() - 1 && (node->attResources[color.attachment]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)))
|
||||||
resourceAttLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR;
|
resourceAttFinalLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR;
|
||||||
else
|
else
|
||||||
resourceAttLayouts[color.attachment] = color.layout;
|
resourceAttFinalLayouts[color.attachment] = color.layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& depth : subpass->depthReferences)
|
for (auto& depth : subpass->depthReferences)
|
||||||
resourceAttLayouts[depth.attachment] = depth.layout;
|
resourceAttFinalLayouts[depth.attachment] = depth.layout;
|
||||||
|
|
||||||
for (auto& input : subpass->inputReferences)
|
for (auto& input : subpass->inputReferences)
|
||||||
resourceAttLayouts[input.attachment] = input.layout;
|
resourceAttFinalLayouts[input.attachment] = input.layout;
|
||||||
|
|
||||||
|
// Go through all subpass computes and initialize final layouts to GENERAL when a resource is detected to be used in it
|
||||||
|
//for (auto sbCompute : subpass->subpassComputes)
|
||||||
|
//{
|
||||||
|
// auto const& indices = sbCompute->attachmentDescriptionIndices;
|
||||||
|
// for (auto& index : indices)
|
||||||
|
// {
|
||||||
|
// resourceAttFinalLayouts[index] = vk::ImageLayout::eGeneral;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t j = 0; j < node->attachmentDescriptions.size(); ++j)
|
for (uint32_t j = 0; j < node->attachmentDescriptions.size(); ++j)
|
||||||
{
|
{
|
||||||
auto& att = node->attachmentDescriptions[j];
|
auto& att = node->attachmentDescriptions[j];
|
||||||
att.initialLayout = vk::ImageLayout::eUndefined;
|
att.initialLayout = vk::ImageLayout::eUndefined;
|
||||||
att.finalLayout = resourceAttLayouts[j];
|
att.finalLayout = resourceAttFinalLayouts[j];
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
@ -175,7 +188,7 @@ namespace SHADE
|
||||||
// Now we want to loop through all attachments in all subpasses in the node and query
|
// Now we want to loop through all attachments in all subpasses in the node and query
|
||||||
// the resources being used. For each resource we want to query the type and record it
|
// the resources being used. For each resource we want to query the type and record it
|
||||||
// in bit fields (1 bit for each subpass).
|
// in bit fields (1 bit for each subpass).
|
||||||
uint32_t colorRead = 0, colorWrite = 0, depthRead = 0, depthWrite = 0, inputDependencies = 0;
|
uint32_t colorRead = 0, colorWrite = 0, depthRead = 0, depthWrite = 0, inputDependencies = 0, descriptorDependencies = 0;
|
||||||
|
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
|
|
||||||
|
@ -214,6 +227,9 @@ namespace SHADE
|
||||||
if (subpass->inputReferences.size())
|
if (subpass->inputReferences.size())
|
||||||
inputDependencies |= (1 << i);
|
inputDependencies |= (1 << i);
|
||||||
|
|
||||||
|
if (!subpass->subpassComputes.empty())
|
||||||
|
descriptorDependencies |= (1 << i);
|
||||||
|
|
||||||
// Input attachments can be any type, so we need to check what type it is
|
// Input attachments can be any type, so we need to check what type it is
|
||||||
for (auto& inputAtt : subpass->inputReferences)
|
for (auto& inputAtt : subpass->inputReferences)
|
||||||
{
|
{
|
||||||
|
@ -279,6 +295,12 @@ namespace SHADE
|
||||||
dstAccess |= vk::AccessFlagBits::eInputAttachmentRead;
|
dstAccess |= vk::AccessFlagBits::eInputAttachmentRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (descriptorDependencies & (1 << i))
|
||||||
|
{
|
||||||
|
dstStage |= vk::PipelineStageFlagBits::eComputeShader;
|
||||||
|
dstAccess |= vk::AccessFlagBits::eShaderWrite | vk::AccessFlagBits::eShaderRead;
|
||||||
|
}
|
||||||
|
|
||||||
//// If subpass of first renderpass, stage flag should be bottom of pipe
|
//// If subpass of first renderpass, stage flag should be bottom of pipe
|
||||||
//if (&node == &nodes.front() && i == 0)
|
//if (&node == &nodes.front() && i == 0)
|
||||||
// srcStage = vk::PipelineStageFlagBits::eBottomOfPipe;
|
// srcStage = vk::PipelineStageFlagBits::eBottomOfPipe;
|
||||||
|
@ -293,6 +315,9 @@ namespace SHADE
|
||||||
dep.dstAccessMask = dstAccess;
|
dep.dstAccessMask = dstAccess;
|
||||||
|
|
||||||
dep.srcStageMask = srcStage;
|
dep.srcStageMask = srcStage;
|
||||||
|
|
||||||
|
// initialize the barriers
|
||||||
|
//node->subpasses[i]->InitComputeBarriers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -353,6 +378,8 @@ namespace SHADE
|
||||||
|
|
||||||
renderGraphStorage->resourceManager = resourceManager;
|
renderGraphStorage->resourceManager = resourceManager;
|
||||||
renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools();
|
renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools();
|
||||||
|
|
||||||
|
renderGraphStorage->ptrToResources = &graphResources;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -459,7 +486,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes.emplace_back(resourceManager->Create<SHRenderGraphNode>(renderGraphStorage, std::move(descInitParams), std::move(predecessors), &graphResources));
|
nodes.emplace_back(resourceManager->Create<SHRenderGraphNode>(renderGraphStorage, std::move(descInitParams), std::move(predecessors)));
|
||||||
nodeIndexing.emplace(nodeName, static_cast<uint32_t>(nodes.size()) - 1u);
|
nodeIndexing.emplace(nodeName, static_cast<uint32_t>(nodes.size()) - 1u);
|
||||||
return nodes.at(nodeIndexing[nodeName]);
|
return nodes.at(nodeIndexing[nodeName]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,10 +57,6 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
//Handle<SHVkLogicalDevice> logicalDeviceHdl;
|
|
||||||
|
|
||||||
//! swapchain used for querying image count
|
|
||||||
//Handle<SHVkSwapchain> swapchainHdl;
|
|
||||||
|
|
||||||
Handle<SHRenderGraphStorage> renderGraphStorage;
|
Handle<SHRenderGraphStorage> renderGraphStorage;
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,11 @@ namespace SHADE
|
||||||
|
|
||||||
framebuffers[i]->HandleResize(renderpass, imageViews, fbWidth, fbHeight);
|
framebuffers[i]->HandleResize(renderpass, imageViews, fbWidth, fbHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& subpass : subpasses)
|
||||||
|
{
|
||||||
|
subpass->HandleResize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -105,7 +110,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHRenderGraphNode::SHRenderGraphNode(Handle<SHRenderGraphStorage> renderGraphStorage, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
|
SHRenderGraphNode::SHRenderGraphNode(Handle<SHRenderGraphStorage> renderGraphStorage, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors) noexcept
|
||||||
: graphStorage{ renderGraphStorage}
|
: graphStorage{ renderGraphStorage}
|
||||||
, renderpass{}
|
, renderpass{}
|
||||||
, framebuffers{}
|
, framebuffers{}
|
||||||
|
@ -116,7 +121,6 @@ namespace SHADE
|
||||||
, subpasses{}
|
, subpasses{}
|
||||||
, executed{ false }
|
, executed{ false }
|
||||||
, configured{ false }
|
, configured{ false }
|
||||||
, ptrToResources{ resources }
|
|
||||||
{
|
{
|
||||||
// pipeline library initialization
|
// pipeline library initialization
|
||||||
pipelineLibrary.Init(graphStorage->logicalDevice);
|
pipelineLibrary.Init(graphStorage->logicalDevice);
|
||||||
|
@ -173,7 +177,6 @@ namespace SHADE
|
||||||
, subpassIndexing{ std::move(rhs.subpassIndexing) }
|
, subpassIndexing{ std::move(rhs.subpassIndexing) }
|
||||||
, configured{ rhs.configured }
|
, configured{ rhs.configured }
|
||||||
, executed{ rhs.executed }
|
, executed{ rhs.executed }
|
||||||
, ptrToResources{ rhs.ptrToResources }
|
|
||||||
, pipelineLibrary{ std::move(rhs.pipelineLibrary) }
|
, pipelineLibrary{ std::move(rhs.pipelineLibrary) }
|
||||||
, batcher{ std::move(rhs.batcher) }
|
, batcher{ std::move(rhs.batcher) }
|
||||||
, spDescs{ std::move(rhs.spDescs) }
|
, spDescs{ std::move(rhs.spDescs) }
|
||||||
|
@ -197,7 +200,6 @@ namespace SHADE
|
||||||
subpasses = std::move(rhs.subpasses);
|
subpasses = std::move(rhs.subpasses);
|
||||||
resourceAttachmentMapping = std::move(rhs.resourceAttachmentMapping);
|
resourceAttachmentMapping = std::move(rhs.resourceAttachmentMapping);
|
||||||
subpassIndexing = std::move(rhs.subpassIndexing);
|
subpassIndexing = std::move(rhs.subpassIndexing);
|
||||||
ptrToResources = std::move(rhs.ptrToResources);
|
|
||||||
pipelineLibrary = std::move(rhs.pipelineLibrary);
|
pipelineLibrary = std::move(rhs.pipelineLibrary);
|
||||||
batcher = std::move(rhs.batcher);
|
batcher = std::move(rhs.batcher);
|
||||||
spDescs = std::move(rhs.spDescs);
|
spDescs = std::move(rhs.spDescs);
|
||||||
|
@ -233,7 +235,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add subpass to container and create mapping for it
|
// Add subpass to container and create mapping for it
|
||||||
subpasses.emplace_back(graphStorage->resourceManager->Create<SHSubpass>(graphStorage, GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources));
|
subpasses.emplace_back(graphStorage->resourceManager->Create<SHSubpass>(graphStorage, GetHandle(), subpasses.size(), &resourceAttachmentMapping));
|
||||||
subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u);
|
subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u);
|
||||||
Handle<SHSubpass> subpass = subpasses.back();
|
Handle<SHSubpass> subpass = subpasses.back();
|
||||||
subpass->Init(*graphStorage->resourceManager);
|
subpass->Init(*graphStorage->resourceManager);
|
||||||
|
|
|
@ -64,9 +64,6 @@ namespace SHADE
|
||||||
//! For indexing subpasses
|
//! For indexing subpasses
|
||||||
std::map<std::string, uint32_t> subpassIndexing;
|
std::map<std::string, uint32_t> subpassIndexing;
|
||||||
|
|
||||||
//! Pointer to resources in the render graph (for getting handle IDs)
|
|
||||||
std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources;
|
|
||||||
|
|
||||||
//! Every renderpass will require a pipeline library that will contain pipelines compatible with this renderpass
|
//! Every renderpass will require a pipeline library that will contain pipelines compatible with this renderpass
|
||||||
SHPipelineLibrary pipelineLibrary;
|
SHPipelineLibrary pipelineLibrary;
|
||||||
|
|
||||||
|
@ -89,7 +86,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* CTORS AND DTORS */
|
/* CTORS AND DTORS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
SHRenderGraphNode(Handle<SHRenderGraphStorage> renderGraphStorage, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept;
|
SHRenderGraphNode(Handle<SHRenderGraphStorage> renderGraphStorage, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors) noexcept;
|
||||||
SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept;
|
SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept;
|
||||||
SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept;
|
SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept;
|
||||||
|
|
||||||
|
|
|
@ -308,6 +308,7 @@ namespace SHADE
|
||||||
return resourceFormat;
|
return resourceFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t SHRenderGraphResource::GetWidth(void) const noexcept
|
uint32_t SHRenderGraphResource::GetWidth(void) const noexcept
|
||||||
{
|
{
|
||||||
return width;
|
return width;
|
||||||
|
@ -323,4 +324,14 @@ namespace SHADE
|
||||||
return imageViews [index];
|
return imageViews [index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle<SHVkImage> SHRenderGraphResource::GetImage(uint32_t index /*= NON_SWAPCHAIN_RESOURCE_INDEX*/) const noexcept
|
||||||
|
{
|
||||||
|
return images[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t SHRenderGraphResource::GetMipLevels(void) const noexcept
|
||||||
|
{
|
||||||
|
return mipLevels;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -86,8 +86,11 @@ namespace SHADE
|
||||||
uint32_t GetWidth (void) const noexcept;
|
uint32_t GetWidth (void) const noexcept;
|
||||||
uint32_t GetHeight (void) const noexcept;
|
uint32_t GetHeight (void) const noexcept;
|
||||||
Handle<SHVkImageView> GetImageView (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept;
|
Handle<SHVkImageView> GetImageView (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept;
|
||||||
|
Handle<SHVkImage> GetImage (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept;
|
||||||
|
uint8_t GetMipLevels (void) const noexcept;
|
||||||
|
|
||||||
friend class SHRenderGraphNode;
|
friend class SHRenderGraphNode;
|
||||||
friend class SHRenderGraph;
|
friend class SHRenderGraph;
|
||||||
|
friend class SHSubpass;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,9 @@ namespace SHADE
|
||||||
//! Descriptor pool for the descriptor sets to be created in the subpasses
|
//! Descriptor pool for the descriptor sets to be created in the subpasses
|
||||||
Handle<SHVkDescriptorPool> descriptorPool;
|
Handle<SHVkDescriptorPool> descriptorPool;
|
||||||
|
|
||||||
|
//! For accessing resources anyone in the graph
|
||||||
|
std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources;
|
||||||
|
|
||||||
friend class SHRenderGraph;
|
friend class SHRenderGraph;
|
||||||
friend class SHRenderGraphNode;
|
friend class SHRenderGraphNode;
|
||||||
friend class SHSubpass;
|
friend class SHSubpass;
|
||||||
|
|
|
@ -8,6 +8,10 @@
|
||||||
#include "SHRenderGraphNode.h"
|
#include "SHRenderGraphNode.h"
|
||||||
#include "SHRenderGraphStorage.h"
|
#include "SHRenderGraphStorage.h"
|
||||||
#include "Graphics/RenderGraph/SHSubpassCompute.h"
|
#include "Graphics/RenderGraph/SHSubpassCompute.h"
|
||||||
|
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||||
|
#include "Graphics/Swapchain/SHVkSwapchain.h"
|
||||||
|
#include "Graphics/Images/SHVkSampler.h"
|
||||||
|
#include "SHRenderGraphResource.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -27,9 +31,8 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHSubpass::SHSubpass(Handle<SHRenderGraphStorage> renderGraphStorage, 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(Handle<SHRenderGraphStorage> renderGraphStorage, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping) noexcept
|
||||||
: resourceAttachmentMapping{ mapping }
|
: resourceAttachmentMapping{ mapping }
|
||||||
, ptrToResources{ resources }
|
|
||||||
, parentNode{ parent }
|
, parentNode{ parent }
|
||||||
, subpassIndex{ index }
|
, subpassIndex{ index }
|
||||||
, superBatch{}
|
, superBatch{}
|
||||||
|
@ -37,6 +40,8 @@ namespace SHADE
|
||||||
, depthReferences{}
|
, depthReferences{}
|
||||||
, inputReferences{}
|
, inputReferences{}
|
||||||
, graphStorage{ renderGraphStorage }
|
, graphStorage{ renderGraphStorage }
|
||||||
|
, subpassComputes{}
|
||||||
|
, inputImageDescriptors {SHGraphicsConstants::NUM_FRAME_BUFFERS}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,10 +64,10 @@ namespace SHADE
|
||||||
, depthReferences{ std::move(rhs.depthReferences) }
|
, depthReferences{ std::move(rhs.depthReferences) }
|
||||||
, inputReferences{ std::move(rhs.inputReferences) }
|
, inputReferences{ std::move(rhs.inputReferences) }
|
||||||
, resourceAttachmentMapping{ rhs.resourceAttachmentMapping }
|
, resourceAttachmentMapping{ rhs.resourceAttachmentMapping }
|
||||||
, ptrToResources{ rhs.ptrToResources }
|
|
||||||
, descriptorSetLayout{ rhs.descriptorSetLayout }
|
, descriptorSetLayout{ rhs.descriptorSetLayout }
|
||||||
, exteriorDrawCalls{ std::move(rhs.exteriorDrawCalls) }
|
, exteriorDrawCalls{ std::move(rhs.exteriorDrawCalls) }
|
||||||
, graphStorage{ std::move(rhs.graphStorage) }
|
, graphStorage{ std::move(rhs.graphStorage) }
|
||||||
|
, subpassComputes{std::move (rhs.subpassComputes)}
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -90,10 +95,10 @@ namespace SHADE
|
||||||
depthReferences = std::move(rhs.depthReferences);
|
depthReferences = std::move(rhs.depthReferences);
|
||||||
inputReferences = std::move(rhs.inputReferences);
|
inputReferences = std::move(rhs.inputReferences);
|
||||||
resourceAttachmentMapping = rhs.resourceAttachmentMapping;
|
resourceAttachmentMapping = rhs.resourceAttachmentMapping;
|
||||||
ptrToResources = rhs.ptrToResources;
|
|
||||||
descriptorSetLayout = rhs.descriptorSetLayout;
|
descriptorSetLayout = rhs.descriptorSetLayout;
|
||||||
exteriorDrawCalls = std::move(rhs.exteriorDrawCalls);
|
exteriorDrawCalls = std::move(rhs.exteriorDrawCalls);
|
||||||
graphStorage = std::move(rhs.graphStorage);
|
graphStorage = std::move(rhs.graphStorage);
|
||||||
|
subpassComputes = std::move(rhs.subpassComputes);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -112,7 +117,7 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void 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 });
|
colorReferences.push_back({ resourceAttachmentMapping->at(graphStorage->ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eColorAttachmentOptimal });
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -149,7 +154,7 @@ namespace SHADE
|
||||||
//Invalid
|
//Invalid
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
depthReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), imageLayout });
|
depthReferences.push_back({ resourceAttachmentMapping->at(graphStorage->ptrToResources->at(resourceToReference).GetId().Raw), imageLayout });
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -166,7 +171,15 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void 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 });
|
inputReferences.push_back({ resourceAttachmentMapping->at(graphStorage->ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal });
|
||||||
|
|
||||||
|
inputNames.push_back(resourceToReference);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSubpass::AddGeneralInput(std::string resourceToReference) noexcept
|
||||||
|
{
|
||||||
|
inputReferences.push_back({ resourceAttachmentMapping->at(graphStorage->ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eGeneral });
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
|
void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
|
||||||
|
@ -182,6 +195,17 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
drawCall(commandBuffer);
|
drawCall(commandBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if there are subpass computes, transition all to GENERAL layout first
|
||||||
|
for (auto& sbCompute : subpassComputes)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSubpass::HandleResize(void) noexcept
|
||||||
|
{
|
||||||
|
UpdateWriteDescriptors();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSubpass::AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept
|
void SHSubpass::AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept
|
||||||
|
@ -189,9 +213,27 @@ namespace SHADE
|
||||||
exteriorDrawCalls.push_back(newDrawCall);
|
exteriorDrawCalls.push_back(newDrawCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHSubpassCompute> SHSubpass::ActivateSubpassCompute(Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources) noexcept
|
Handle<SHSubpassCompute> SHSubpass::AddSubpassCompute(Handle<SHVkShaderModule> computeShaderModule/*, std::initializer_list<std::string> resources*/) noexcept
|
||||||
{
|
{
|
||||||
subpassCompute = graphStorage->resourceManager->Create<SHSubpassCompute>(graphStorage, computeShaderModule, resources);
|
//// for the subpass compute to store indices to the resources, see member comments
|
||||||
|
//std::unordered_set<uint32_t> attDescIndices{};
|
||||||
|
//attDescIndices.reserve (resources.size());
|
||||||
|
|
||||||
|
//// Look for the required resources in the graph
|
||||||
|
//std::vector<Handle<SHRenderGraphResource>> subpassComputeResources{};
|
||||||
|
//subpassComputeResources.reserve(resources.size());
|
||||||
|
|
||||||
|
//for (auto& resourceName : resources)
|
||||||
|
//{
|
||||||
|
// auto resource = graphStorage->ptrToResources->at(resourceName);
|
||||||
|
// subpassComputeResources.push_back(resource);
|
||||||
|
// attDescIndices.emplace(resourceAttachmentMapping->at (resource.GetId().Raw));
|
||||||
|
//}
|
||||||
|
|
||||||
|
// Create the subpass compute with the resources
|
||||||
|
auto subpassCompute = graphStorage->resourceManager->Create<SHSubpassCompute>(graphStorage, computeShaderModule/*, std::move(subpassComputeResources), std::move (attDescIndices)*/);
|
||||||
|
subpassComputes.push_back(subpassCompute);
|
||||||
|
|
||||||
return subpassCompute;
|
return subpassCompute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,6 +243,145 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHSubpass::CreateInputDescriptors(void) noexcept
|
||||||
|
{
|
||||||
|
//std::vector<SHVkDescriptorSetLayout::Binding> bindings{};
|
||||||
|
|
||||||
|
//for (auto& input : inputReferences)
|
||||||
|
//{
|
||||||
|
// SHVkDescriptorSetLayout::Binding newBinding
|
||||||
|
// {
|
||||||
|
// .Type = (input.layout == vk::ImageLayout::eShaderReadOnlyOptimal) ? vk::DescriptorType::eInputAttachment : vk::DescriptorType::eStorageImage,
|
||||||
|
// .Stage = vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eCompute,
|
||||||
|
// .BindPoint = static_cast<uint32_t>(bindings.size()),
|
||||||
|
// .DescriptorCount = 1,
|
||||||
|
// .flags = {},
|
||||||
|
// };
|
||||||
|
|
||||||
|
// bindings.push_back(newBinding);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//// We build a new descriptor set layout to store our images
|
||||||
|
//inputDescriptorLayout = graphStorage->logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, bindings);
|
||||||
|
|
||||||
|
//// we store a sampler if its an input attachment. if it is storage image, no need sampler, store an empty handle.
|
||||||
|
//for (uint32_t i = 0; i < bindings.size(); ++i)
|
||||||
|
//{
|
||||||
|
// if (bindings[i].Type == vk::DescriptorType::eInputAttachment)
|
||||||
|
// {
|
||||||
|
// auto newSampler = graphStorage->logicalDevice->CreateSampler(SHVkSamplerParams
|
||||||
|
// {
|
||||||
|
// .minFilter = vk::Filter::eLinear,
|
||||||
|
// .magFilter = vk::Filter::eLinear,
|
||||||
|
// .addressMode = vk::SamplerAddressMode::eRepeat,
|
||||||
|
// .mipmapMode = vk::SamplerMipmapMode::eLinear,
|
||||||
|
// .minLod = -1000,
|
||||||
|
// .maxLod = 1000
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
|
||||||
|
// inputSamplers.push_back(newSampler);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// inputSamplers.push_back({});
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//// maybe do this in handle resize?
|
||||||
|
//UpdateWriteDescriptors();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSubpass::UpdateWriteDescriptors(void) noexcept
|
||||||
|
{
|
||||||
|
//auto const& bindings = inputDescriptorLayout->GetBindings();
|
||||||
|
|
||||||
|
//std::vector<uint32_t> variableCounts{ static_cast<uint32_t>(bindings.size()), 0 };
|
||||||
|
|
||||||
|
//uint32_t i = 0;
|
||||||
|
|
||||||
|
//// For every frame's descriptor set
|
||||||
|
//for (auto& group : inputImageDescriptors)
|
||||||
|
//{
|
||||||
|
// if (group)
|
||||||
|
// group.Free();
|
||||||
|
|
||||||
|
// group = graphStorage->descriptorPool->Allocate({ inputDescriptorLayout }, variableCounts);
|
||||||
|
|
||||||
|
// for (auto& binding : bindings)
|
||||||
|
// {
|
||||||
|
// // get the resource
|
||||||
|
// auto resource = graphStorage->ptrToResources->at(inputNames[binding.BindPoint]);
|
||||||
|
|
||||||
|
// // If resource is swapchain image, get the correct image, if not just get 0.
|
||||||
|
// uint32_t viewIndex = (resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0;
|
||||||
|
|
||||||
|
// // layout is GENERAL if image is meant to be used as storage image, if not use SHADER_READ_ONLY_OPTINAL
|
||||||
|
// vk::ImageLayout descriptorLayout = (binding.Type == vk::DescriptorType::eStorageImage) ? vk::ImageLayout::eGeneral : vk::ImageLayout::eShaderReadOnlyOptimal;
|
||||||
|
|
||||||
|
// // Update descriptor sets
|
||||||
|
// auto args = std::make_tuple(resource->GetImageView(viewIndex), inputSamplers[i], descriptorLayout);
|
||||||
|
// group->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint, std::span{&args, 1});
|
||||||
|
// group->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ++i;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
//void SHSubpass::InitComputeBarriers(void) noexcept
|
||||||
|
//{
|
||||||
|
// std::unordered_set <uint64_t> handleBarriers{};
|
||||||
|
|
||||||
|
// // we will have swapchainNumImages vectors of vector of barriers
|
||||||
|
// subpassComputeBarriers.resize(graphStorage->swapchain->GetNumImages());
|
||||||
|
|
||||||
|
// for (auto sbCompute : subpassComputes)
|
||||||
|
// {
|
||||||
|
// // for every resource the subpass compute is using
|
||||||
|
// for (auto resource : sbCompute->resources)
|
||||||
|
// {
|
||||||
|
// // Get the resource handle
|
||||||
|
// uint64_t resourceRaw = resource.GetId().Raw;
|
||||||
|
|
||||||
|
// // if the barrier is not registered
|
||||||
|
// if (!handleBarriers.contains(resourceRaw))
|
||||||
|
// {
|
||||||
|
// // If the resource is a swapchain image
|
||||||
|
// bool isSwapchainImage = (resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT));
|
||||||
|
// for (uint32_t i = 0; i < graphStorage->swapchain->GetNumImages(); ++i)
|
||||||
|
// {
|
||||||
|
// // if swapchain image, we want the index of the swapchain image, if not take base image
|
||||||
|
// uint32_t imageIndex = isSwapchainImage ? i : 0;
|
||||||
|
|
||||||
|
// // Prepare image barrier
|
||||||
|
// vk::ImageMemoryBarrier imageBarrier
|
||||||
|
// {
|
||||||
|
// .oldLayout = colorReferences[resourceAttachmentMapping->at(resource.GetId().Raw)].layout,
|
||||||
|
// .newLayout = vk::ImageLayout::eGeneral,
|
||||||
|
// .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
// .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
// .image = resource->GetImage(imageIndex)->GetVkImage(),
|
||||||
|
// .subresourceRange =
|
||||||
|
// {
|
||||||
|
// .aspectMask = resource->imageAspectFlags,
|
||||||
|
// .levelCount = resource->GetMipLevels(),
|
||||||
|
// .baseArrayLayer = 0,
|
||||||
|
// .layerCount = 1
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // push the barrier
|
||||||
|
// subpassComputeBarriers[i].push_back(imageBarrier);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Image transition registered
|
||||||
|
// handleBarriers.emplace(resourceRaw);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,12 @@ namespace SHADE
|
||||||
class SHRenderGraphResource;
|
class SHRenderGraphResource;
|
||||||
class SHVkCommandBuffer;
|
class SHVkCommandBuffer;
|
||||||
class SHVkDescriptorSetLayout;
|
class SHVkDescriptorSetLayout;
|
||||||
|
class SHVkDescriptorSetGroup;
|
||||||
class SHVkDescriptorPool;
|
class SHVkDescriptorPool;
|
||||||
class SHRenderGraphStorage;
|
class SHRenderGraphStorage;
|
||||||
class SHSubpassCompute;
|
class SHSubpassCompute;
|
||||||
class SHVkShaderModule;
|
class SHVkShaderModule;
|
||||||
|
class SHVkSampler;
|
||||||
|
|
||||||
class SH_API SHSubpass : public ISelfHandle<SHSubpass>
|
class SH_API SHSubpass : public ISelfHandle<SHSubpass>
|
||||||
{
|
{
|
||||||
|
@ -48,15 +50,29 @@ namespace SHADE
|
||||||
//! Input attachments
|
//! Input attachments
|
||||||
std::vector<vk::AttachmentReference> inputReferences;
|
std::vector<vk::AttachmentReference> inputReferences;
|
||||||
|
|
||||||
|
//! This is mainly for when we want to retrieve resources using names.
|
||||||
|
std::vector<std::string> inputNames;
|
||||||
|
|
||||||
//! For getting attachment reference indices using handles
|
//! For getting attachment reference indices using handles
|
||||||
std::unordered_map<uint64_t, uint32_t> const* resourceAttachmentMapping;
|
std::unordered_map<uint64_t, uint32_t> const* resourceAttachmentMapping;
|
||||||
|
|
||||||
//! Pointer to resources in the render graph (for getting handle IDs)
|
//! Descriptor set group to hold the images for input
|
||||||
std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources;
|
std::vector<Handle<SHVkDescriptorSetGroup>> inputImageDescriptors;
|
||||||
|
|
||||||
|
//! Descriptor set layout for allocating descriptor set for inputs
|
||||||
|
Handle<SHVkDescriptorSetLayout> inputDescriptorLayout;
|
||||||
|
|
||||||
|
std::vector<Handle<SHVkSampler>> inputSamplers;
|
||||||
|
|
||||||
//! Sometimes we want the subpass to do something to the images instead
|
//! Sometimes we want the subpass to do something to the images instead
|
||||||
//! of drawing objects on the image (i.e. compute).
|
//! of drawing objects on the image (i.e. compute).
|
||||||
Handle<SHSubpassCompute> subpassCompute;
|
std::vector<Handle<SHSubpassCompute>> subpassComputes;
|
||||||
|
|
||||||
|
////! subpass compute image barriers. We do this because every frame has a different
|
||||||
|
////! swapchain image. If the resource we want to transition is not a swapchain image,
|
||||||
|
////! we duplicate the barrier anyway, not much memory wasted. ;)
|
||||||
|
//std::vector<std::vector<vk::ImageMemoryBarrier>> subpassComputeBarriers{};
|
||||||
|
|
||||||
|
|
||||||
//! Sometimes there exists entities that we want to render onto a render target
|
//! 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.
|
//! but don't want it to come from the batching system. An example would be ImGUI.
|
||||||
|
@ -71,7 +87,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* CTORS AND DTORS */
|
/* CTORS AND DTORS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
SHSubpass(Handle<SHRenderGraphStorage> renderGraphStorage, 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(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;
|
||||||
|
|
||||||
|
@ -82,15 +98,21 @@ namespace SHADE
|
||||||
void AddColorOutput(std::string resourceToReference) noexcept;
|
void AddColorOutput(std::string resourceToReference) noexcept;
|
||||||
void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType = SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL) noexcept;
|
void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType = SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL) noexcept;
|
||||||
void AddInput(std::string resourceToReference) noexcept;
|
void AddInput(std::string resourceToReference) noexcept;
|
||||||
|
void AddGeneralInput (std::string resourceToReference) noexcept;
|
||||||
|
void AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept;
|
||||||
|
|
||||||
// Runtime functions
|
// Runtime functions
|
||||||
void Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
void Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
||||||
void AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept;
|
void HandleResize (void) noexcept;
|
||||||
|
|
||||||
Handle<SHSubpassCompute> ActivateSubpassCompute(Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources) noexcept;
|
Handle<SHSubpassCompute> AddSubpassCompute(Handle<SHVkShaderModule> computeShaderModule/*, std::initializer_list<std::string> resources*/) noexcept;
|
||||||
|
|
||||||
void Init(ResourceManager& resourceManager) noexcept;
|
void Init(ResourceManager& resourceManager) noexcept;
|
||||||
|
|
||||||
|
//void InitComputeBarriers (void) noexcept;
|
||||||
|
void CreateInputDescriptors (void) noexcept;
|
||||||
|
void UpdateWriteDescriptors (void) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* GETTERS AND SETTERS */
|
/* GETTERS AND SETTERS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -102,5 +124,6 @@ namespace SHADE
|
||||||
|
|
||||||
friend class SHRenderGraphNode;
|
friend class SHRenderGraphNode;
|
||||||
friend class SHRenderGraph;
|
friend class SHRenderGraph;
|
||||||
|
friend class SHSubpass;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,25 +11,43 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
SHSubpassCompute::SHSubpassCompute(Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources) noexcept
|
SHSubpassCompute::SHSubpassCompute(Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule/*, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<uint32_t>&& attDescIndices*/) noexcept
|
||||||
: pipeline{}
|
: pipeline{}
|
||||||
{
|
{
|
||||||
SHPipelineLayoutParams pipelineLayoutParams
|
SHPipelineLayoutParams pipelineLayoutParams
|
||||||
{
|
{
|
||||||
|
.shaderModules = {computeShaderModule},
|
||||||
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts()
|
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts()
|
||||||
};
|
};
|
||||||
|
|
||||||
//pipeline = logicalDevice->CreateComputePipeline()
|
// Create descriptor set from
|
||||||
|
pipelineLayout = graphStorage->logicalDevice->CreatePipelineLayout (pipelineLayoutParams);
|
||||||
|
|
||||||
// Get the descriptor set layouts required to allocate. we will bind a different pipeline layout, one that includes the layout for global.
|
// Create the compute pipeline
|
||||||
auto const& layouts = pipeline->GetPipelineLayout()->GetDescriptorSetLayoutsAllocate();
|
pipeline = graphStorage->logicalDevice->CreateComputePipeline(pipelineLayout);
|
||||||
|
|
||||||
|
pipeline->ConstructPipeline();
|
||||||
|
|
||||||
|
// Get the descriptor set layouts required to allocate. We only want the ones for allocate because
|
||||||
|
// global descriptors are already bound in the main system.
|
||||||
|
//auto const& layouts = pipeline->GetPipelineLayout()->GetDescriptorSetLayoutsAllocate();
|
||||||
|
|
||||||
// Variable counts for the descriptor sets (all should be 1).
|
// Variable counts for the descriptor sets (all should be 1).
|
||||||
std::vector<uint32_t> variableCounts{ static_cast<uint32_t>(layouts.size()) };
|
//std::vector<uint32_t> variableCounts{ static_cast<uint32_t>(layouts.size()) };
|
||||||
std::fill(variableCounts.begin(), variableCounts.end(), 0);
|
//std::fill(variableCounts.begin(), variableCounts.end(), 0);
|
||||||
|
|
||||||
// Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE)
|
//// Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE)
|
||||||
descSetGroup = graphStorage->descriptorPool->Allocate(layouts, variableCounts);
|
//descSetGroup = graphStorage->descriptorPool->Allocate(layouts, variableCounts);
|
||||||
|
|
||||||
|
//// save the resources
|
||||||
|
//resources = std::move (subpassComputeResources);
|
||||||
|
|
||||||
|
//// we save this because when we configure the graph, we want to make sure final layouts
|
||||||
|
//// of attachment descriptions are set to GENERAL. See ConfigureAttachmentDescriptions in SHRenderGraph.cpp.
|
||||||
|
//attachmentDescriptionIndices = std::move (attDescIndices);
|
||||||
|
|
||||||
|
//descSetGroup->ModifyWriteDescImage (SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//SHSubpass
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "Resource/Handle.h"
|
#include "Resource/Handle.h"
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -12,6 +13,7 @@ namespace SHADE
|
||||||
class SHVkLogicalDevice;
|
class SHVkLogicalDevice;
|
||||||
class SHVkPipelineLayout;
|
class SHVkPipelineLayout;
|
||||||
class SHRenderGraphStorage;
|
class SHRenderGraphStorage;
|
||||||
|
class SHRenderGraphResource;
|
||||||
class SHVkShaderModule;
|
class SHVkShaderModule;
|
||||||
|
|
||||||
class SHSubpassCompute
|
class SHSubpassCompute
|
||||||
|
@ -20,18 +22,28 @@ namespace SHADE
|
||||||
//! To run the dispatch command
|
//! To run the dispatch command
|
||||||
Handle<SHVkPipeline> pipeline;
|
Handle<SHVkPipeline> pipeline;
|
||||||
|
|
||||||
//! Pipeline layout for the pipline creation
|
//! Pipeline layout for the pipeline creation
|
||||||
Handle<SHVkPipeline> pipelineLayout;
|
Handle<SHVkPipelineLayout> pipelineLayout;
|
||||||
|
|
||||||
//! Descriptor set group to hold the images for reading (STORAGE_IMAGE)
|
////! Descriptor set group to hold the images for reading (STORAGE_IMAGE)
|
||||||
Handle<SHVkDescriptorSetGroup> descSetGroup;
|
//Handle<SHVkDescriptorSetGroup> descSetGroup;
|
||||||
|
|
||||||
//! Required resources to be used in the descriptors
|
////! Required resources to be used in the descriptors
|
||||||
std::vector<std::string> resourcesRequired;
|
//std::vector<std::string> resourcesRequired;
|
||||||
|
|
||||||
|
////! vector of resources needed by the subpass compute
|
||||||
|
//std::vector<Handle<SHRenderGraphResource>> resources;
|
||||||
|
|
||||||
|
////! we save this because when we configure the graph, we want to make sure final layouts
|
||||||
|
////! of attachment descriptions are set to GENERAL. See ConfigureAttachmentDescriptions in SHRenderGraph.cpp.
|
||||||
|
//std::unordered_set<uint32_t> attachmentDescriptionIndices{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHSubpassCompute(Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources) noexcept;
|
SHSubpassCompute(Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule/*, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<uint32_t>&& attDescIndices*/) noexcept;
|
||||||
|
|
||||||
|
//void ExecuteSubpass (void) noexcept;
|
||||||
|
friend class SHRenderGraph;
|
||||||
|
friend class SHSubpass;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -177,6 +177,9 @@ namespace SHADE
|
||||||
return vk::DescriptorType::eStorageBufferDynamic;
|
return vk::DescriptorType::eStorageBufferDynamic;
|
||||||
case SpvReflectDescriptorType::SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
|
case SpvReflectDescriptorType::SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
|
||||||
return vk::DescriptorType::eInputAttachment;
|
return vk::DescriptorType::eInputAttachment;
|
||||||
|
case SpvReflectDescriptorType::SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
||||||
|
return vk::DescriptorType::eStorageImage;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return vk::DescriptorType::eCombinedImageSampler;
|
return vk::DescriptorType::eCombinedImageSampler;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/* Start Header *****************************************************************/
|
||||||
|
|
||||||
|
/*! \file (e.g. kirsch.comp)
|
||||||
|
|
||||||
|
\author William Zheng, william.zheng, 60001906. Brandon Mak, brandon.hao 390003920.
|
||||||
|
|
||||||
|
\par william.zheng\@digipen.edu. brandon.hao\@digipen.edu.
|
||||||
|
|
||||||
|
\date Sept 20, 2022
|
||||||
|
|
||||||
|
\brief Copyright (C) 20xx DigiPen Institute of Technology.
|
||||||
|
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent of DigiPen Institute of Technology is prohibited. */
|
||||||
|
|
||||||
|
/* End Header *******************************************************************/
|
||||||
|
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(local_size_x = 16, local_size_y = 16) in;
|
||||||
|
layout(set = 4, binding = 0, rgba8) uniform image2D targetImage;
|
||||||
|
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// load the image
|
||||||
|
vec4 color = imageLoad (targetImage, ivec2 (gl_GlobalInvocationID));
|
||||||
|
|
||||||
|
// get the average
|
||||||
|
float average = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
|
||||||
|
|
||||||
|
// store result into result image
|
||||||
|
imageStore(targetImage, ivec2(gl_GlobalInvocationID), vec4(average, average, average, 1.0f));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue