Renderpass execution and descriptor set writes
This commit is contained in:
parent
8f7d8cd8bc
commit
4ccfd399af
|
@ -128,6 +128,7 @@
|
|||
<ClInclude Include="src\Graphics\Debugging\SHVulkanDebugUtil.h" />
|
||||
<ClInclude Include="src\Graphics\Descriptors\SHDescriptorPoolManager.h" />
|
||||
<ClInclude Include="src\Graphics\Descriptors\SHDescriptorPoolStorage.h" />
|
||||
<ClInclude Include="src\Graphics\Descriptors\SHDescriptorSetUpdater.h" />
|
||||
<ClInclude Include="src\Graphics\Descriptors\SHVkDescriptorPool.h" />
|
||||
<ClInclude Include="src\Graphics\Descriptors\SHVkDescriptorSetGroup.h" />
|
||||
<ClInclude Include="src\Graphics\Descriptors\SHVkDescriptorSetLayout.h" />
|
||||
|
@ -206,6 +207,7 @@
|
|||
<ClCompile Include="src\Graphics\Debugging\SHVulkanDebugUtil.cpp" />
|
||||
<ClCompile Include="src\Graphics\Descriptors\SHDescriptorPoolManager.cpp" />
|
||||
<ClCompile Include="src\Graphics\Descriptors\SHDescriptorPoolStorage.cpp" />
|
||||
<ClCompile Include="src\Graphics\Descriptors\SHDescriptorSetUpdater.cpp" />
|
||||
<ClCompile Include="src\Graphics\Descriptors\SHVkDescriptorPool.cpp" />
|
||||
<ClCompile Include="src\Graphics\Descriptors\SHVkDescriptorSetGroup.cpp" />
|
||||
<ClCompile Include="src\Graphics\Descriptors\SHVkDescriptorSetLayout.cpp" />
|
||||
|
|
|
@ -367,6 +367,7 @@
|
|||
<ClInclude Include="src\Tools\SHLogger.h">
|
||||
<Filter>Tools</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Graphics\Descriptors\SHDescriptorSetUpdater.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\Editor\Backend\SHImGuiVulkanBackend.cpp">
|
||||
|
@ -550,5 +551,6 @@
|
|||
<ClCompile Include="src\Tools\SHLogger.cpp">
|
||||
<Filter>Tools</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Graphics\Descriptors\SHDescriptorSetUpdater.cpp" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -40,7 +40,7 @@ namespace SHADE
|
|||
gl_Position = vec4(aPos * pc.uScale + pc.uTranslate, 0, 1);
|
||||
}
|
||||
*/
|
||||
static uint32_t __glsl_shader_vert_spv[] =
|
||||
static std::vector<uint32_t> __glsl_shader_vert_spv =
|
||||
{
|
||||
0x07230203,0x00010000,0x00080001,0x0000002e,0x00000000,0x00020011,0x00000001,0x0006000b,
|
||||
0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
|
||||
|
@ -97,7 +97,7 @@ namespace SHADE
|
|||
fColor = In.Color * texture(sTexture, In.UV.st);
|
||||
}
|
||||
*/
|
||||
static uint32_t __glsl_shader_frag_spv[] =
|
||||
static std::vector<uint32_t> __glsl_shader_frag_spv =
|
||||
{
|
||||
0x07230203,0x00010000,0x00080001,0x0000001e,0x00000000,0x00020011,0x00000001,0x0006000b,
|
||||
0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
|
||||
|
@ -137,7 +137,7 @@ namespace SHADE
|
|||
std::array<float, 2> translate;
|
||||
};
|
||||
|
||||
void SHImGuiVulkanBackend::CreateInstance(Handle<SHVkLogicalDevice> const& logicalDevice) noexcept
|
||||
void SHImGuiVulkanBackend::CreateInstance(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkRenderpass> const& renderpass, uint32_t subpassIndex) noexcept
|
||||
{
|
||||
if (ImGui::GetCurrentContext() == nullptr)
|
||||
{
|
||||
|
@ -189,7 +189,7 @@ namespace SHADE
|
|||
|
||||
//Initialize instance
|
||||
auto instance = std::make_unique<SHBreachInstance>();
|
||||
instance->InitializePipeline(io);
|
||||
instance->InitializePipeline(io, renderpass, subpassIndex);
|
||||
instance->lastFrameTime = std::chrono::high_resolution_clock::now();
|
||||
io.UserData = instance.release();
|
||||
|
||||
|
@ -303,7 +303,7 @@ namespace SHADE
|
|||
io.Fonts->TexID = nullptr;
|
||||
}
|
||||
|
||||
void SHImGuiVulkanBackend::SHBreachInstance::InitializePipeline(ImGuiIO& io) noexcept
|
||||
void SHImGuiVulkanBackend::SHBreachInstance::InitializePipeline(ImGuiIO& io, Handle<SHVkRenderpass> const& renderpass, uint32_t subpassIndex) noexcept
|
||||
{
|
||||
SHVertexInputState vInputState{};
|
||||
vInputState.AddBinding(false, true,
|
||||
|
@ -314,7 +314,23 @@ namespace SHADE
|
|||
}
|
||||
);
|
||||
|
||||
//Handle<SHVkPipeline> newPipeline = device->CreatePipeline()
|
||||
Handle<SHVkShaderModule> vs = device->CreateShaderModule(__glsl_shader_vert_spv, "main", vk::ShaderStageFlagBits::eVertex, "__glsl_shader_vert_spv");
|
||||
Handle<SHVkShaderModule> fs = device->CreateShaderModule(__glsl_shader_frag_spv, "main", vk::ShaderStageFlagBits::eFragment, "__glsl_shader_frag_spv");
|
||||
|
||||
SHPipelineLayoutParams pipelineLayoutParams
|
||||
{
|
||||
.shaderModules = std::move (std::vector<Handle<SHVkShaderModule>>
|
||||
{
|
||||
vs,
|
||||
fs,
|
||||
}),
|
||||
};
|
||||
|
||||
Handle<SHVkPipelineLayout> pipelineLayouot = device->CreatePipelineLayout(pipelineLayoutParams);
|
||||
Handle<SHVkPipeline> newPipeline = device->CreatePipeline(pipelineLayouot, nullptr, renderpass, subpassIndex, SH_PIPELINE_TYPE::GRAPHICS);
|
||||
newPipeline->GetPipelineState().SetVertexInputState(vInputState);
|
||||
newPipeline->ConstructPipeline();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -41,11 +41,10 @@ namespace SHADE
|
|||
std::vector<uint32_t> fontsMipOffset;
|
||||
public:
|
||||
void CreateFontsTexture (Handle<SHVkImage> image, ImGuiIO& io) noexcept;
|
||||
void InitializeRenderpass (void) noexcept;
|
||||
void InitializePipeline(ImGuiIO& io) noexcept;
|
||||
void InitializePipeline(ImGuiIO& io, Handle<SHVkRenderpass> const& renderpass, uint32_t subpassIndex) noexcept;
|
||||
};
|
||||
public:
|
||||
static void CreateInstance(Handle<SHVkLogicalDevice> const& logicalDevice) noexcept;
|
||||
static void CreateInstance(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkRenderpass> const& renderpass, uint32_t subpassIndex) noexcept;
|
||||
static void Render(void) noexcept;
|
||||
|
||||
|
||||
|
|
|
@ -202,6 +202,11 @@ namespace SHADE
|
|||
vkCommandBuffer.endRenderPass();
|
||||
}
|
||||
|
||||
void SHVkCommandBuffer::NextSubpass(void) noexcept
|
||||
{
|
||||
vkCommandBuffer.nextSubpass(commandBufferType == SH_CMD_BUFFER_TYPE::PRIMARY ? vk::SubpassContents::eInline : vk::SubpassContents::eSecondaryCommandBuffers);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
|
|
|
@ -96,11 +96,12 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------*/
|
||||
void Reset(void);
|
||||
|
||||
// Begins and Ends
|
||||
// Begins, Ends and Nexts
|
||||
void BeginRecording (void) noexcept;
|
||||
void EndRecording (void) noexcept;
|
||||
void BeginRenderpass (Handle<SHVkRenderpass> const& renderpassHdl, Handle<SHVkFramebuffer> const& framebufferHdl, vk::Offset2D offset = {0, 0}, vk::Extent2D extent = {0, 0}) noexcept;
|
||||
void EndRenderpass (void) noexcept;
|
||||
void NextSubpass (void) noexcept;
|
||||
|
||||
// Dynamic State
|
||||
void SetviewportScissor (float vpWidth, float vpHeight, uint32_t sWidth, uint32_t sHeight, float vpX = 0.0f, float vpY = 0.0f, int32_t sX = 0.0f, int32_t sY = 0.0f, float vpMinDepth = 0.0f, float vpMaxDepth = 1.0f) noexcept;
|
||||
|
@ -124,6 +125,7 @@ namespace SHADE
|
|||
std::vector<vk::ImageMemoryBarrier> const& imageMemoryBarriers
|
||||
) const noexcept;
|
||||
|
||||
|
||||
// Push Constant variable setting
|
||||
template <typename T>
|
||||
void SetPushConstantVariable(std::string variableName, T const& data) noexcept
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHDescriptorSetUpdater.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
||||
SHDescriptorWriteInfo::SHDescriptorWriteInfo(SHDescriptorWriteInfo&& rhs) noexcept
|
||||
: descImageInfos{ std::move(rhs.descImageInfos) }
|
||||
, descBufferInfos{ std::move(rhs.descBufferInfos) }
|
||||
, descTexelBufferInfos{std::move (rhs.descTexelBufferInfos)}
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SHDescriptorWriteInfo::SHDescriptorWriteInfo(void) noexcept
|
||||
: descImageInfos{}
|
||||
, descBufferInfos{}
|
||||
, descTexelBufferInfos{}
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
Links the write infos to the vulkan write descriptor sets.
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHDescriptorSetUpdater::LinkInfoToWriteDescSet(void) noexcept
|
||||
{
|
||||
for (uint32_t i = 0; i < writeInfos.size(); ++i)
|
||||
{
|
||||
writeDescSets[i].pImageInfo = writeInfos[i].descImageInfos.data();
|
||||
writeDescSets[i].pBufferInfo = writeInfos[i].descBufferInfos.data();
|
||||
writeDescSets[i].pTexelBufferView = writeInfos[i].descTexelBufferInfos.data();
|
||||
}
|
||||
}
|
||||
|
||||
SHDescriptorWriteInfo& SHDescriptorWriteInfo::operator=(SHDescriptorWriteInfo&& rhs) noexcept
|
||||
{
|
||||
if (&rhs == this)
|
||||
return *this;
|
||||
|
||||
descImageInfos = std::move(rhs.descImageInfos);
|
||||
descBufferInfos = std::move(rhs.descBufferInfos);
|
||||
descTexelBufferInfos = std::move(rhs.descTexelBufferInfos);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
SHDescriptorSetUpdater::SHDescriptorSetUpdater(SHDescriptorSetUpdater&& rhs) noexcept
|
||||
: writeInfos{ std::move(rhs.writeInfos) }
|
||||
, writeHashMap {std::move (rhs.writeHashMap)}
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SHDescriptorSetUpdater::SHDescriptorSetUpdater(void) noexcept
|
||||
: writeInfos{}
|
||||
, writeHashMap{}
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::vector<vk::WriteDescriptorSet> const& SHDescriptorSetUpdater::GetWriteDescriptorSets(void) const noexcept
|
||||
{
|
||||
return writeDescSets;
|
||||
}
|
||||
|
||||
SHDescriptorSetUpdater& SHDescriptorSetUpdater::operator=(SHDescriptorSetUpdater&& rhs) noexcept
|
||||
{
|
||||
if (&rhs == this)
|
||||
return *this;
|
||||
|
||||
writeInfos = std::move (rhs.writeInfos);
|
||||
writeHashMap = std::move (rhs.writeHashMap);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include "Graphics/SHVulkanIncludes.h"
|
||||
#include "Graphics/Shaders/SHShaderReflected.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
// Vulkan doesn't use all of the information when looking at a writeDescriptorSet. It all
|
||||
// depends on the descriptor type. This struct plays it safe by having members that would
|
||||
// accommodate all types of descriptors.
|
||||
class SHDescriptorWriteInfo
|
||||
{
|
||||
//! When we want to update a descriptor that is an image, it goes in here
|
||||
std::vector<vk::DescriptorImageInfo> descImageInfos;
|
||||
|
||||
//! When we want to update a descriptor that is a buffer, it goes in here
|
||||
std::vector<vk::DescriptorBufferInfo> descBufferInfos;
|
||||
|
||||
//! When we want to update a descriptor that is an texel buffer, it goes in here
|
||||
std::vector<vk::BufferView> descTexelBufferInfos;
|
||||
|
||||
public:
|
||||
SHDescriptorWriteInfo (void) noexcept;
|
||||
SHDescriptorWriteInfo (SHDescriptorWriteInfo&& rhs) noexcept;
|
||||
SHDescriptorWriteInfo& operator= (SHDescriptorWriteInfo&& rhs) noexcept;
|
||||
|
||||
friend class SHVkDescriptorSetGroup;
|
||||
friend class SHDescriptorSetUpdater;
|
||||
};
|
||||
|
||||
class SHDescriptorSetUpdater
|
||||
{
|
||||
private:
|
||||
//! When we want to update descriptor sets, this will get passed into vkUpdateDescriptorSets.
|
||||
//! Each write will correspond to a binding from a set. If the binding is a variable
|
||||
//! sized binding, pImageInfo (e.g.) will point to an array of vk::DescriptorImageInfo.
|
||||
std::vector<SHDescriptorWriteInfo> writeInfos;
|
||||
|
||||
//! When we want to update a write, we need to use this to identify the index of the write.
|
||||
std::unordered_map<BindingAndSetHash, uint32_t> writeHashMap;
|
||||
|
||||
//! We keep this here because we want this to be immediately passable to vkUpdateDescriptorSets
|
||||
std::vector<vk::WriteDescriptorSet> writeDescSets;
|
||||
|
||||
void LinkInfoToWriteDescSet(void) noexcept;
|
||||
|
||||
public:
|
||||
SHDescriptorSetUpdater (void) noexcept;
|
||||
SHDescriptorSetUpdater(SHDescriptorSetUpdater&& rhs) noexcept;
|
||||
SHDescriptorSetUpdater& operator= (SHDescriptorSetUpdater&& rhs) noexcept;
|
||||
|
||||
public:
|
||||
std::vector<vk::WriteDescriptorSet> const& GetWriteDescriptorSets (void) const noexcept;
|
||||
|
||||
friend class SHVkDescriptorSetGroup;
|
||||
};
|
||||
}
|
||||
|
|
@ -42,9 +42,11 @@ namespace SHADE
|
|||
{
|
||||
// Create the layout for each concurrent frame
|
||||
std::vector<vk::DescriptorSetLayout> vkLayouts{ layouts.size() };
|
||||
for (auto& layout : layouts)
|
||||
|
||||
//for (auto& layout : layouts)
|
||||
for (uint32_t i = 0; i < layouts.size(); ++i)
|
||||
{
|
||||
vkLayouts.push_back(layout->GetVkHandle());
|
||||
vkLayouts.push_back(layouts[i]->GetVkHandle());
|
||||
}
|
||||
|
||||
// Check for variable descriptor count
|
||||
|
@ -67,6 +69,66 @@ namespace SHADE
|
|||
|
||||
// allocate descriptor sets
|
||||
descSets = device->GetVkLogicalDevice().allocateDescriptorSets(DESC_SET_LAYOUT_CREATE_INFO);
|
||||
|
||||
|
||||
|
||||
// Now we want to prepare the write descriptor sets for writing later.
|
||||
for (uint32_t i = 0; i < layouts.size(); ++i)
|
||||
{
|
||||
auto const& bindings = layouts[i]->GetBindings();
|
||||
for (auto& binding : bindings)
|
||||
{
|
||||
BindingAndSetHash writeHash = binding.BindPoint;
|
||||
writeHash |= static_cast<uint64_t>(i) << 32;
|
||||
|
||||
// new write for the binding
|
||||
updater.writeInfos.emplace_back();
|
||||
updater.writeHashMap.try_emplace(writeHash, updater.writeInfos.size() - 1);
|
||||
auto& writeInfo = updater.writeInfos.back();
|
||||
|
||||
updater.writeDescSets.emplace_back();
|
||||
auto& writeDescSet = updater.writeDescSets.back();
|
||||
|
||||
// Initialize info for write
|
||||
writeDescSet.descriptorType = binding.Type;
|
||||
writeDescSet.dstArrayElement = 0;
|
||||
writeDescSet.dstSet = descSets[i];
|
||||
writeDescSet.dstBinding = binding.BindPoint;
|
||||
|
||||
// Descriptor count for the write descriptor set. Usually this is set to 1, but if binding is variable sized, set to info passed in
|
||||
uint32_t descriptorCount = (binding.flags & vk::DescriptorBindingFlagBits::eVariableDescriptorCount) ? variableDescCounts[i] : 1;
|
||||
writeDescSet.descriptorCount = descriptorCount;
|
||||
|
||||
switch (binding.Type)
|
||||
{
|
||||
//case vk::DescriptorType::eSampler:
|
||||
//case vk::DescriptorType::eSampledImage:
|
||||
case vk::DescriptorType::eCombinedImageSampler:
|
||||
writeInfo.descImageInfos.resize(descriptorCount);
|
||||
break;
|
||||
//case vk::DescriptorType::eStorageImage:
|
||||
// break;
|
||||
case vk::DescriptorType::eUniformTexelBuffer:
|
||||
case vk::DescriptorType::eStorageTexelBuffer:
|
||||
case vk::DescriptorType::eUniformBuffer:
|
||||
case vk::DescriptorType::eStorageBuffer:
|
||||
writeInfo.descImageInfos.resize (descriptorCount);
|
||||
break;
|
||||
//case vk::DescriptorType::eUniformBufferDynamic:
|
||||
// break;
|
||||
//case vk::DescriptorType::eStorageBufferDynamic:
|
||||
// break;
|
||||
//case vk::DescriptorType::eInputAttachment:
|
||||
// break;
|
||||
//case vk::DescriptorType::eInlineUniformBlock:
|
||||
// break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Link all the writeDescSet data for vkUpdateDescriptorSets to write to the linked descriptors
|
||||
updater.LinkInfoToWriteDescSet();
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -82,4 +144,45 @@ namespace SHADE
|
|||
if (!descSets.empty())
|
||||
device->GetVkLogicalDevice().freeDescriptorSets(descPool->GetVkHandle(), descSets);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
Modifies a descriptor write info. #NoteToSelf: This function does NOT
|
||||
need to modify the writeDescSets. Those are already linked before.
|
||||
|
||||
\param imageViewsAndSamplers
|
||||
Image and view samplers
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHVkDescriptorSetGroup::ModifyWriteDescImage(uint32_t set, uint32_t binding, std::vector<std::pair<vk::ImageView, vk::Sampler>> const& imageViewsAndSamplers) noexcept
|
||||
{
|
||||
// Find the target writeDescSet
|
||||
BindingAndSetHash writeHash = binding;
|
||||
writeHash |= static_cast<uint64_t>(set) << 32;
|
||||
auto& writeInfo = updater.writeInfos[updater.writeHashMap.at(writeHash)];
|
||||
|
||||
if (imageViewsAndSamplers.size() > writeInfo.descImageInfos.size())
|
||||
{
|
||||
SHLOG_ERROR("Attempting write too many descriptors into descriptor set. Failed to write to vk::WriteDescriptorSet. ");
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < imageViewsAndSamplers.size(); ++i)
|
||||
{
|
||||
// write sampler and image view
|
||||
auto& ivs = imageViewsAndSamplers[i];
|
||||
writeInfo.descImageInfos[i].imageView = ivs.first;
|
||||
writeInfo.descImageInfos[i].sampler = ivs.second;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SHVkDescriptorSetGroup::UpdateDescriptorSet(void) noexcept
|
||||
{
|
||||
device->UpdateDescriptorSets(updater.GetWriteDescriptorSets());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -3,6 +3,8 @@
|
|||
// Project Includes
|
||||
#include "Graphics/SHVulkanIncludes.h"
|
||||
#include "Resource/Handle.h"
|
||||
#include "Graphics/Shaders/SHShaderReflected.h"
|
||||
#include "SHDescriptorSetUpdater.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -13,6 +15,7 @@ namespace SHADE
|
|||
class SHVkDescriptorPool;
|
||||
class SHVkDescriptorSetLayout;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -50,6 +53,12 @@ namespace SHADE
|
|||
SHVkDescriptorSetGroup& operator=(const SHVkDescriptorSetGroup&) = delete;
|
||||
SHVkDescriptorSetGroup& operator=(SHVkDescriptorSetGroup&& rhs) noexcept = default;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Descriptor set writing */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
void ModifyWriteDescImage (uint32_t set, uint32_t binding, std::vector<std::pair<vk::ImageView, vk::Sampler>> const& imageViewsAndSamplers) noexcept;
|
||||
void UpdateDescriptorSet (void) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Getter Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
@ -59,13 +68,22 @@ namespace SHADE
|
|||
/// <returns>Handle to the Vulkan Descriptor Set.</returns>
|
||||
[[nodiscard]]
|
||||
inline const std::vector<vk::DescriptorSet>& GetVkHandle() { return descSets; }
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
//! Device required to allocate descriptor sets
|
||||
Handle<SHVkLogicalDevice> device;
|
||||
|
||||
//! Descriptor pool to allocate descriptor sets
|
||||
Handle<SHVkDescriptorPool> descPool;
|
||||
|
||||
//! Descriptor sets
|
||||
std::vector<vk::DescriptorSet> descSets;
|
||||
|
||||
//! for updating descriptor sets. We want to cache this so that we don't create the
|
||||
//! write structs at runtime.
|
||||
SHDescriptorSetUpdater updater;
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -85,6 +85,11 @@ namespace SHADE
|
|||
device->GetVkLogicalDevice().destroyDescriptorSetLayout(setLayout);
|
||||
}
|
||||
|
||||
std::vector<SHVkDescriptorSetLayout::Binding> const& SHVkDescriptorSetLayout::GetBindings(void) const noexcept
|
||||
{
|
||||
return layoutDesc;
|
||||
}
|
||||
|
||||
SHVkDescriptorSetLayout& SHVkDescriptorSetLayout::operator=(SHVkDescriptorSetLayout&& rhs) noexcept
|
||||
{
|
||||
if (&rhs == this)
|
||||
|
|
|
@ -96,6 +96,7 @@ namespace SHADE
|
|||
/// </summary>
|
||||
/// <returns>Handle to the Vulkan Descriptor Set Layout handle.</returns>
|
||||
inline const vk::DescriptorSetLayout& GetVkHandle() const { return setLayout; }
|
||||
std::vector<Binding> const& GetBindings (void) const noexcept;
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -552,6 +552,22 @@ namespace SHADE
|
|||
return SHVkInstance::GetResourceManager().Create<SHVkSemaphore>(GetHandle());
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
Writes to descriptor sets.
|
||||
|
||||
\param writeDescSets
|
||||
Descriptor sets to write to.
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHVkLogicalDevice::UpdateDescriptorSets(std::vector<vk::WriteDescriptorSet> const& writeDescSets) noexcept
|
||||
{
|
||||
vkLogicalDevice.updateDescriptorSets(writeDescSets, {});
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ namespace SHADE
|
|||
class SHVkFramebuffer;
|
||||
class SHVkImageView;
|
||||
class SHShaderBlockInterface;
|
||||
class SHVkDescriptorSetGroup;
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
@ -179,6 +180,8 @@ namespace SHADE
|
|||
Handle<SHVkFence> CreateFence (void) const noexcept;
|
||||
Handle<SHVkSemaphore> CreateSemaphore (void) const noexcept;
|
||||
|
||||
void UpdateDescriptorSets (std::vector<vk::WriteDescriptorSet> const& writeDescSets) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* SETTERS AND GETTERS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
|
|
@ -84,8 +84,6 @@ namespace SHADE
|
|||
//commandBuffers[i] = commandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); // works
|
||||
}
|
||||
|
||||
|
||||
|
||||
descPool = device->CreateDescriptorPools();
|
||||
|
||||
|
||||
|
|
|
@ -209,9 +209,10 @@ namespace SHADE
|
|||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
SHRenderGraphNode::SHSubpass::SHSubpass(std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
|
||||
SHRenderGraphNode::SHSubpass::SHSubpass(Handle<SHRenderGraphNode> const& parent, 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 }
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -333,6 +334,38 @@ namespace SHADE
|
|||
inputReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal });
|
||||
}
|
||||
|
||||
void SHRenderGraphNode::SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer) noexcept
|
||||
{
|
||||
// Draw all the batches
|
||||
|
||||
// Draw all the exterior draw calls
|
||||
for (auto& drawCall : exteriorDrawCalls)
|
||||
{
|
||||
drawCall(commandBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void SHRenderGraphNode::SHSubpass::AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept
|
||||
{
|
||||
exteriorDrawCalls.push_back(newDrawCall);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
Getter for parent renderpass.
|
||||
|
||||
\return
|
||||
Returns the parent renderpass the subpass belongs to.
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
Handle<SHRenderGraphNode> const& SHRenderGraphNode::SHSubpass::GetParentNode(void) const noexcept
|
||||
{
|
||||
return parentNode;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
|
@ -512,11 +545,26 @@ namespace SHADE
|
|||
}
|
||||
|
||||
// Add subpass to container and create mapping for it
|
||||
subpasses.emplace_back(resourceManager.Create<SHSubpass>(&resourceAttachmentMapping, ptrToResources));
|
||||
subpassIndexing.try_emplace(subpassName, subpasses.size() - 1);
|
||||
subpasses.emplace_back(resourceManager.Create<SHSubpass>(GetHandle(), &resourceAttachmentMapping, ptrToResources));
|
||||
subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u);
|
||||
return subpasses.at(subpassIndexing[subpassName]);
|
||||
}
|
||||
|
||||
void SHRenderGraphNode::Execute(Handle<SHVkCommandBuffer>& commandBuffer, uint32_t frameIndex) noexcept
|
||||
{
|
||||
commandBuffer->BeginRenderpass(renderpass, framebuffers[frameIndex]);
|
||||
|
||||
for (auto& subpass : subpasses)
|
||||
{
|
||||
subpass->Execute(commandBuffer);
|
||||
|
||||
// Go to next subpass
|
||||
commandBuffer->NextSubpass();
|
||||
}
|
||||
|
||||
commandBuffer->EndRenderpass();
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
|
@ -560,7 +608,7 @@ namespace SHADE
|
|||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHRenderGraph::AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w /*= static_cast<uint32_t>(-1)*/, uint32_t h /*= static_cast<uint32_t>(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint32_t levels /*= 1*/, vk::ImageCreateFlagBits createFlags /*= {}*/)
|
||||
void SHRenderGraph::AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w /*= static_cast<uint32_t>(-1)*/, uint32_t h /*= static_cast<uint32_t>(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageCreateFlagBits createFlags /*= {}*/)
|
||||
{
|
||||
// If we set to
|
||||
if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1))
|
||||
|
@ -832,6 +880,20 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
Configures command pools and command buffers.
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHRenderGraph::ConfigureCommands(void) noexcept
|
||||
{
|
||||
commandPool = logicalDeviceHdl->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
|
||||
commandBuffers.resize(static_cast<std::size_t>(swapchainHdl->GetNumImages()));
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
|
@ -929,7 +991,7 @@ namespace SHADE
|
|||
}
|
||||
|
||||
nodes.emplace_back(resourceManager.Create<SHRenderGraphNode>(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(resources), std::move(predecessors), &graphResources));
|
||||
nodeIndexing.emplace(nodeName, nodes.size() - 1);
|
||||
nodeIndexing.emplace(nodeName, static_cast<uint32_t>(nodes.size()) - 1u);
|
||||
return nodes.at(nodeIndexing[nodeName]);
|
||||
}
|
||||
|
||||
|
@ -952,6 +1014,20 @@ namespace SHADE
|
|||
ConfigureSubpasses();
|
||||
ConfigureRenderpasses();
|
||||
ConfigureFramebuffers();
|
||||
ConfigureCommands();
|
||||
}
|
||||
|
||||
void SHRenderGraph::Execute(uint32_t frameIndex) noexcept
|
||||
{
|
||||
auto& cmdBuffer = commandBuffers[frameIndex];
|
||||
cmdBuffer->BeginRecording();
|
||||
|
||||
for (auto& node : nodes)
|
||||
{
|
||||
node->Execute(commandBuffers[frameIndex], frameIndex);
|
||||
}
|
||||
|
||||
cmdBuffer->EndRenderpass();
|
||||
}
|
||||
|
||||
Handle<SHRenderGraphNode> SHRenderGraph::GetNode(std::string const& nodeName) const noexcept
|
||||
|
|
|
@ -15,6 +15,8 @@ namespace SHADE
|
|||
class SHVkImage;
|
||||
class SHVkImageView;
|
||||
class SHVkFramebuffer;
|
||||
class SHVkCommandPool;
|
||||
class SHVkCommandBuffer;
|
||||
|
||||
// Used for attachment description creation for renderpass node
|
||||
enum class SH_ATT_DESC_TYPE
|
||||
|
@ -72,25 +74,44 @@ namespace SHADE
|
|||
friend class SHRenderGraph;
|
||||
};
|
||||
|
||||
class SHRenderGraphNode
|
||||
class SHRenderGraphNode : public ISelfHandle<SHRenderGraphNode>
|
||||
{
|
||||
public:
|
||||
|
||||
class SHSubpass
|
||||
{
|
||||
public:
|
||||
SHSubpass(std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources) noexcept;
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* CTORS AND DTORS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
SHSubpass(Handle<SHRenderGraphNode> const& parent, 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;
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* PRIVATE MEMBER VARIABLES */
|
||||
/*---------------------------------------------------------------------*/
|
||||
//! The parent renderpass that this subpass belongs to
|
||||
Handle<SHRenderGraphNode> parentNode;
|
||||
|
||||
//! Color attachments
|
||||
std::vector<vk::AttachmentReference> colorReferences;
|
||||
|
||||
|
@ -106,6 +127,14 @@ namespace SHADE
|
|||
//! 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;
|
||||
};
|
||||
|
@ -179,6 +208,7 @@ namespace SHADE
|
|||
/* PUBLIC MEMBER FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
Handle<SHSubpass> AddSubpass (std::string subpassName) noexcept;
|
||||
void Execute (Handle<SHVkCommandBuffer>& commandBuffer, uint32_t frameIndex) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* SETTERS AND GETTERS */
|
||||
|
@ -198,6 +228,7 @@ namespace SHADE
|
|||
void ConfigureSubpasses (void) noexcept;
|
||||
void ConfigureRenderpasses (void) noexcept;
|
||||
void ConfigureFramebuffers (void) noexcept;
|
||||
void ConfigureCommands (void) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* PRIVATE MEMBER VARIABLES */
|
||||
|
@ -219,6 +250,13 @@ namespace SHADE
|
|||
//! Resource library for graph handles
|
||||
ResourceManager resourceManager;
|
||||
|
||||
//! Command pool for the render graph
|
||||
Handle<SHVkCommandPool> commandPool;
|
||||
|
||||
//! Command buffers for the render graph
|
||||
std::vector<Handle<SHVkCommandBuffer>> commandBuffers;
|
||||
|
||||
|
||||
public:
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* CTORS AND DTORS */
|
||||
|
@ -229,9 +267,10 @@ namespace SHADE
|
|||
/* PUBLIC MEMBER FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
void Init (Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain) noexcept;
|
||||
void AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint32_t levels = 1, vk::ImageCreateFlagBits createFlags = {});
|
||||
void AddResource (std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageCreateFlagBits createFlags = {});
|
||||
Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<std::string> resourceNames, std::initializer_list<std::string> predecessorNodes) noexcept;
|
||||
void Generate (void) noexcept;
|
||||
void Execute (uint32_t frameIndex) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* SETTERS AND GETTERS */
|
||||
|
|
|
@ -189,7 +189,7 @@ namespace SHADE
|
|||
|
||||
Handle<SHShaderBlockInterface> SHShaderDescriptorBindingInfo::GetShaderBlockInterface(uint32_t set, uint32_t binding) const noexcept
|
||||
{
|
||||
SHShaderDescriptorBindingInfo::BindingAndSetHash hash = binding;
|
||||
BindingAndSetHash hash = binding;
|
||||
hash |= static_cast<uint64_t>(set) << 32;
|
||||
if (blockInterfaces.contains(hash))
|
||||
return blockInterfaces.at(hash);
|
||||
|
|
|
@ -9,11 +9,10 @@
|
|||
|
||||
namespace SHADE
|
||||
{
|
||||
struct SHShaderDescriptorBindingInfo
|
||||
{
|
||||
public:
|
||||
using BindingAndSetHash = uint64_t;
|
||||
|
||||
struct SHShaderDescriptorBindingInfo
|
||||
{
|
||||
private:
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* PRIVATE MEMBER VARIABLES */
|
||||
|
|
Loading…
Reference in New Issue