diff --git a/SHADE_Application/SHADE_Application.vcxproj b/SHADE_Application/SHADE_Application.vcxproj
index ab1ac84c..c1775b8d 100644
--- a/SHADE_Application/SHADE_Application.vcxproj
+++ b/SHADE_Application/SHADE_Application.vcxproj
@@ -46,6 +46,7 @@
bin-int\Debug_x86_64\SHADE_Application\
SHADE_Application
.exe
+ ..\Dependencies\spdlog\include;$(VULKAN_SDK)\include;..\Dependencies\VMA\include;$(VULKAN_SDK)\Source\SPIRV-Reflect;$(IncludePath)
false
@@ -53,6 +54,7 @@
bin-int\Release_x86_64\SHADE_Application\
SHADE_Application
.exe
+ ..\Dependencies\spdlog\include;$(VULKAN_SDK)\include;..\Dependencies\VMA\include;$(VULKAN_SDK)\Source\SPIRV-Reflect;$(IncludePath)
@@ -60,7 +62,7 @@
SBpch.h
Level4
NOMINMAX;_DEBUG;%(PreprocessorDefinitions)
- ..\Dependencies\spdlog\include;$(VULKAN_SDK)\include;..\Dependencies\VMA\include;$(VULKAN_SDK)\Source\SPIRV-Reflect;..\SHADE_Engine\src;src;%(AdditionalIncludeDirectories)
+ ..\SHADE_Engine\src;src;%(AdditionalIncludeDirectories)
EditAndContinue
Disabled
false
@@ -80,7 +82,7 @@
SBpch.h
Level4
NOMINMAX;_RELEASE;%(PreprocessorDefinitions)
- ..\Dependencies\spdlog\include;$(VULKAN_SDK)\include;..\Dependencies\VMA\include;$(VULKAN_SDK)\Source\SPIRV-Reflect;..\SHADE_Engine\src;src;%(AdditionalIncludeDirectories)
+ ..\SHADE_Engine\src;src;%(AdditionalIncludeDirectories)
Full
true
true
diff --git a/SHADE_Application/premake5.lua b/SHADE_Application/premake5.lua
index 74a3d0de..d6efc890 100644
--- a/SHADE_Application/premake5.lua
+++ b/SHADE_Application/premake5.lua
@@ -22,14 +22,20 @@ project "SHADE_Application"
includedirs
{
- "%{IncludeDir.spdlog}/include",
- "%{IncludeDir.VULKAN}/include",
- "%{IncludeDir.VMA}/include",
- "%{IncludeDir.VULKAN}/Source/SPIRV-Reflect",
"../SHADE_Engine/src",
"src"
}
+
+ externalincludedirs
+ {
+ "%{IncludeDir.spdlog}/include",
+ "%{IncludeDir.VULKAN}/include",
+ "%{IncludeDir.VMA}/include",
+ "%{IncludeDir.VULKAN}/Source/SPIRV-Reflect"
+ }
+ externalwarnings "Off"
+
flags
{
"MultiProcessorCompile"
diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp
index 69662415..a30237dc 100644
--- a/SHADE_Application/src/Application/SBApplication.cpp
+++ b/SHADE_Application/src/Application/SBApplication.cpp
@@ -2,9 +2,10 @@
#include "SBApplication.h"
#include "Engine/ECS_Base/System/SHSystemManager.h"
+#define SHEDITOR
#ifdef SHEDITOR
-#include "Editor/SHEditor.h"
-#include "Scenes/SBEditorScene.h"
+//#include "Editor/SHEditor.h"
+//#include "Scenes/SBEditorScene.h"
#endif // SHEDITOR
#include
@@ -29,8 +30,8 @@ namespace Sandbox
graphicsSystem->SetWindow(&window);
SHADE::SHSystemManager::Init();
-
#ifdef SHEDITOR
+ //SHADE::SHEditor::Initialize(window.GetHWND());
#else
#endif
@@ -43,10 +44,15 @@ namespace Sandbox
//TODO: Change true to window is open
while (!window.WindowShouldClose())
{
+ //#ifdef SHEDITOR
+ //SHADE::SHEditor::PreRender();
+ //#endif
graphicsSystem->BeginRender();
- #ifdef SHEDITOR
- #else
- #endif
+ //#ifdef SHEDITOR
+ //SHADE::SHEditor::PreRender();
+ //SHADE::SHEditor::Update();
+ //SHADE::SHEditor::Render();
+ //#endif
graphicsSystem->EndRender();
}
}
@@ -54,6 +60,7 @@ namespace Sandbox
void SBApplication::Exit(void)
{
+ //SHADE::SHEditor::Exit();
SHADE::SHSystemManager::Exit();
#ifdef SHEDITOR
diff --git a/SHADE_Engine/SHADE_Engine.vcxproj b/SHADE_Engine/SHADE_Engine.vcxproj
index 3d1c506f..0925c31e 100644
--- a/SHADE_Engine/SHADE_Engine.vcxproj
+++ b/SHADE_Engine/SHADE_Engine.vcxproj
@@ -45,12 +45,14 @@
bin-int\Debug_x86_64\SHADE_Engine\
SHADE_Engine
.lib
+ ..\Dependencies\assimp\include;..\Dependencies\imgui;..\Dependencies\imguizmo;..\Dependencies\imnodes;..\Dependencies\msdf;..\Dependencies\msdf\msdfgen;..\Dependencies\spdlog\include;..\Dependencies\tracy;..\Dependencies\VMA\include;..\Dependencies\yamlcpp\include;..\Dependencies\ktx\include;..\Dependencies\RTTR\include;..\Dependencies\reactphysics3d\include;$(VULKAN_SDK)\include;$(VULKAN_SDK)\Source\SPIRV-Reflect;$(IncludePath)
bin\Release_x86_64\SHADE_Engine\
bin-int\Release_x86_64\SHADE_Engine\
SHADE_Engine
.lib
+ ..\Dependencies\assimp\include;..\Dependencies\imgui;..\Dependencies\imguizmo;..\Dependencies\imnodes;..\Dependencies\msdf;..\Dependencies\msdf\msdfgen;..\Dependencies\spdlog\include;..\Dependencies\tracy;..\Dependencies\VMA\include;..\Dependencies\yamlcpp\include;..\Dependencies\ktx\include;..\Dependencies\RTTR\include;..\Dependencies\reactphysics3d\include;$(VULKAN_SDK)\include;$(VULKAN_SDK)\Source\SPIRV-Reflect;$(IncludePath)
@@ -58,7 +60,7 @@
SHpch.h
Level4
_LIB;_GLFW_INCLUDE_NONE;MSDFGEN_USE_CPP11;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)
- src;..\Dependencies\assimp\include;..\Dependencies\imgui;..\Dependencies\imguizmo;..\Dependencies\imnodes;..\Dependencies\msdf;..\Dependencies\msdf\msdfgen;..\Dependencies\spdlog\include;..\Dependencies\tracy;..\Dependencies\VMA\include;..\Dependencies\yamlcpp\include;..\Dependencies\ktx\include;..\Dependencies\RTTR\include;..\Dependencies\reactphysics3d\include;$(VULKAN_SDK)\include;$(VULKAN_SDK)\Source\SPIRV-Reflect;%(AdditionalIncludeDirectories)
+ src;%(AdditionalIncludeDirectories)
EditAndContinue
Disabled
false
@@ -81,7 +83,7 @@
SHpch.h
Level4
_LIB;_GLFW_INCLUDE_NONE;MSDFGEN_USE_CPP11;NOMINMAX;_RELEASE;%(PreprocessorDefinitions)
- src;..\Dependencies\assimp\include;..\Dependencies\imgui;..\Dependencies\imguizmo;..\Dependencies\imnodes;..\Dependencies\msdf;..\Dependencies\msdf\msdfgen;..\Dependencies\spdlog\include;..\Dependencies\tracy;..\Dependencies\VMA\include;..\Dependencies\yamlcpp\include;..\Dependencies\ktx\include;..\Dependencies\RTTR\include;..\Dependencies\reactphysics3d\include;$(VULKAN_SDK)\include;$(VULKAN_SDK)\Source\SPIRV-Reflect;%(AdditionalIncludeDirectories)
+ src;%(AdditionalIncludeDirectories)
Full
true
true
@@ -125,6 +127,7 @@
+
@@ -135,6 +138,7 @@
+
@@ -201,6 +205,7 @@
+
@@ -210,6 +215,7 @@
+
diff --git a/SHADE_Engine/SHADE_Engine.vcxproj.filters b/SHADE_Engine/SHADE_Engine.vcxproj.filters
index ceb9b80f..1810f10f 100644
--- a/SHADE_Engine/SHADE_Engine.vcxproj.filters
+++ b/SHADE_Engine/SHADE_Engine.vcxproj.filters
@@ -177,6 +177,9 @@
Graphics\Descriptors
+
+ Graphics\Descriptors
+
Graphics\Descriptors
@@ -207,6 +210,9 @@
Graphics\Images
+
+ Graphics\Images
+
Graphics\Instance
@@ -399,6 +405,9 @@
Graphics\Descriptors
+
+ Graphics\Descriptors
+
Graphics\Descriptors
@@ -426,6 +435,9 @@
Graphics\Images
+
+ Graphics\Images
+
Graphics\Instance
diff --git a/SHADE_Engine/premake5.lua b/SHADE_Engine/premake5.lua
index fbc800d3..c51b1ca6 100644
--- a/SHADE_Engine/premake5.lua
+++ b/SHADE_Engine/premake5.lua
@@ -21,7 +21,11 @@ project "SHADE_Engine"
includedirs
{
"%{prj.location}/src",
- "%{IncludeDir.assimp}/include",
+ }
+
+ externalincludedirs
+ {
+ "%{IncludeDir.assimp}/include",
"%{IncludeDir.imgui}",
"%{IncludeDir.imguizmo}",
"%{IncludeDir.imnodes}",
@@ -38,6 +42,8 @@ project "SHADE_Engine"
"%{IncludeDir.VULKAN}/Source/SPIRV-Reflect"
}
+ externalwarnings "Off"
+
libdirs
{
"%{prj.location}/libs",
diff --git a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp
index 4158d3c3..7913574c 100644
--- a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp
+++ b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp
@@ -33,6 +33,8 @@ namespace SHADE
};
cmdBufferHdl->GetVkCommandBuffer().copyBuffer(stagingBuffer, vkBuffer, 1, ©Region);
}
+
+ // TODO: Need to destroy staging buffer. Obviously not here but after the command has finished executing.
}
vk::Buffer SHVkBuffer::GetVkBuffer(void) const noexcept
diff --git a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h
index 2ad3e4e9..9df1a1d0 100644
--- a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h
+++ b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h
@@ -48,7 +48,6 @@ namespace SHADE
vk::BufferUsageFlags bufferUsageFlags;
//! Reference to the allocator
- //VmaAllocator const& vmaAllocator;
std::reference_wrapper vmaAllocator;
/*-----------------------------------------------------------------------*/
diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp
index 6a307230..5b2d15fe 100644
--- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp
+++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp
@@ -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);
+ }
+
/***************************************************************************/
/*!
@@ -406,6 +411,31 @@ namespace SHADE
}
+
+ void SHVkCommandBuffer::PipelineBarrier (
+ vk::PipelineStageFlags srcStage,
+ vk::PipelineStageFlags dstStage,
+ vk::DependencyFlags deps,
+ std::vector const& memoryBarriers,
+ std::vector const& bufferMemoryBarriers,
+ std::vector const& imageMemoryBarriers
+ ) const noexcept
+ {
+ vkCommandBuffer.pipelineBarrier (
+ srcStage,
+ dstStage,
+ deps,
+ memoryBarriers,
+ bufferMemoryBarriers,
+ imageMemoryBarriers
+ );
+ }
+
+ //void SHVkCommandBuffer::PipelineBarrier(vk::PipelineStageFlags ) const noexcept
+ //{
+ // //vkCommandBuffer.pipelineBarrier()
+ //}
+
/***************************************************************************/
/*!
diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h
index 08fc45f7..d2171c25 100644
--- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h
+++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h
@@ -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 const& renderpassHdl, Handle 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;
@@ -114,6 +115,17 @@ namespace SHADE
void DrawArrays (uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept;
void DrawIndexed (uint32_t indexCount, uint32_t firstIndex, uint32_t vertexOffset) const noexcept;
+ // memory barriers
+ void PipelineBarrier (
+ vk::PipelineStageFlags srcStage,
+ vk::PipelineStageFlags dstStage,
+ vk::DependencyFlags deps,
+ std::vector const& memoryBarriers,
+ std::vector const& bufferMemoryBarriers,
+ std::vector const& imageMemoryBarriers
+ ) const noexcept;
+
+
// Push Constant variable setting
template
void SetPushConstantVariable(std::string variableName, T const& data) noexcept
diff --git a/SHADE_Engine/src/Graphics/Debugging/SHVulkanDebugUtil.cpp b/SHADE_Engine/src/Graphics/Debugging/SHVulkanDebugUtil.cpp
index d63a65f7..0152e6c9 100644
--- a/SHADE_Engine/src/Graphics/Debugging/SHVulkanDebugUtil.cpp
+++ b/SHADE_Engine/src/Graphics/Debugging/SHVulkanDebugUtil.cpp
@@ -59,7 +59,7 @@ namespace SHADE
*/
/***************************************************************************/
- void SHVulkanDebugUtil::ReportVkWarning(vk::Result vkResult, std::string_view message, std::source_location const& location /*= std::source_location::current()*/) noexcept
+ void SHVulkanDebugUtil::ReportVkWarning(vk::Result vkResult, std::string_view message) noexcept
{
//std::cout << location.file_name() << ": " << location.function_name() << "|" << location.line() << "|" <<
// location.column() << "|: Warning: " << SHDebugUtil::VkResultToString(vkResult) << " | " << message << std::endl;
@@ -88,7 +88,7 @@ namespace SHADE
*/
/***************************************************************************/
- void SHVulkanDebugUtil::ReportVkError(vk::Result vkResult, std::string_view message, std::source_location const& location /*= std::source_location::current()*/) noexcept
+ void SHVulkanDebugUtil::ReportVkError(vk::Result vkResult, std::string_view message) noexcept
{
std::string toLogger = "Vulkan Warning: " + std::string(SHVulkanDebugUtil::VkResultToString(vkResult)) + " | " + std::string(message);
@@ -96,7 +96,7 @@ namespace SHADE
}
- void SHVulkanDebugUtil::ReportVkSuccess(std::string_view message, std::source_location const& location /*= std::source_location::current()*/) noexcept
+ void SHVulkanDebugUtil::ReportVkSuccess(std::string_view message) noexcept
{
SHLOGV_INFO(message);
}
diff --git a/SHADE_Engine/src/Graphics/Debugging/SHVulkanDebugUtil.h b/SHADE_Engine/src/Graphics/Debugging/SHVulkanDebugUtil.h
index 7bf583bb..af4ca3ef 100644
--- a/SHADE_Engine/src/Graphics/Debugging/SHVulkanDebugUtil.h
+++ b/SHADE_Engine/src/Graphics/Debugging/SHVulkanDebugUtil.h
@@ -15,9 +15,9 @@ namespace SHADE
public:
static VKAPI_ATTR VkBool32 VKAPI_CALL GenericDebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageSeverityFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData);
- static void ReportVkWarning(vk::Result vkResult, std::string_view message, std::source_location const& location = std::source_location::current()) noexcept;
- static void ReportVkError(vk::Result vkResult, std::string_view message, std::source_location const& location = std::source_location::current()) noexcept;
- static void ReportVkSuccess(std::string_view message, std::source_location const& location = std::source_location::current()) noexcept;
+ static void ReportVkWarning(vk::Result vkResult, std::string_view message) noexcept;
+ static void ReportVkError(vk::Result vkResult, std::string_view message) noexcept;
+ static void ReportVkSuccess(std::string_view message) noexcept;
};
diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.cpp
new file mode 100644
index 00000000..a1b1cbc2
--- /dev/null
+++ b/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.cpp
@@ -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 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;
+ }
+
+}
\ No newline at end of file
diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.h b/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.h
new file mode 100644
index 00000000..7a5ae967
--- /dev/null
+++ b/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.h
@@ -0,0 +1,60 @@
+#pragma once
+
+#include
+#include
+#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 descImageInfos;
+
+ //! When we want to update a descriptor that is a buffer, it goes in here
+ std::vector descBufferInfos;
+
+ //! When we want to update a descriptor that is an texel buffer, it goes in here
+ std::vector 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 writeInfos;
+
+ //! When we want to update a write, we need to use this to identify the index of the write.
+ std::unordered_map writeHashMap;
+
+ //! We keep this here because we want this to be immediately passable to vkUpdateDescriptorSets
+ std::vector writeDescSets;
+
+ void LinkInfoToWriteDescSet(void) noexcept;
+
+ public:
+ SHDescriptorSetUpdater (void) noexcept;
+ SHDescriptorSetUpdater(SHDescriptorSetUpdater&& rhs) noexcept;
+ SHDescriptorSetUpdater& operator= (SHDescriptorSetUpdater&& rhs) noexcept;
+
+ public:
+ std::vector const& GetWriteDescriptorSets (void) const noexcept;
+
+ friend class SHVkDescriptorSetGroup;
+ };
+}
+
diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp
index 6bdc5601..16143aa5 100644
--- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp
+++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp
@@ -42,9 +42,11 @@ namespace SHADE
{
// Create the layout for each concurrent frame
std::vector 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(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> const& imageViewsAndSamplers) noexcept
+ {
+ // Find the target writeDescSet
+ BindingAndSetHash writeHash = binding;
+ writeHash |= static_cast(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());
+ }
+
+
}
\ No newline at end of file
diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h
index b95859bb..9e311e9a 100644
--- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h
+++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h
@@ -1,71 +1,89 @@
- #pragma once
+#pragma once
// Project Includes
#include "Graphics/SHVulkanIncludes.h"
#include "Resource/Handle.h"
+#include "Graphics/Shaders/SHShaderReflected.h"
+#include "SHDescriptorSetUpdater.h"
namespace SHADE
{
- /*---------------------------------------------------------------------------------*/
- /* Forward Declarations */
- /*---------------------------------------------------------------------------------*/
- class SHVkLogicalDevice;
- class SHVkDescriptorPool;
- class SHVkDescriptorSetLayout;
+ /*---------------------------------------------------------------------------------*/
+ /* Forward Declarations */
+ /*---------------------------------------------------------------------------------*/
+ class SHVkLogicalDevice;
+ class SHVkDescriptorPool;
+ class SHVkDescriptorSetLayout;
- /*---------------------------------------------------------------------------------*/
- /* Type Definitions */
- /*---------------------------------------------------------------------------------*/
+
+ /*---------------------------------------------------------------------------------*/
+ /* Type Definitions */
+ /*---------------------------------------------------------------------------------*/
+ ///
+ ///
+ ///
+ class SHVkDescriptorSetGroup
+ {
+ public:
+ /*-----------------------------------------------------------------------------*/
+ /* Constructor/Destructors */
+ /*-----------------------------------------------------------------------------*/
///
- ///
+ /// Constructs a Descriptor Set with the specified layout using the specified
+ /// pool meant for use with the specified surface. This Set will be created with
+ /// multiple Vulkan Descriptor Set objects based on the max number of concurrent
+ /// frames for the specified surface.
///
- class SHVkDescriptorSetGroup
- {
- public:
- /*-----------------------------------------------------------------------------*/
- /* Constructor/Destructors */
- /*-----------------------------------------------------------------------------*/
- ///
- /// Constructs a Descriptor Set with the specified layout using the specified
- /// pool meant for use with the specified surface. This Set will be created with
- /// multiple Vulkan Descriptor Set objects based on the max number of concurrent
- /// frames for the specified surface.
- ///
- /// Vulkan logical device used to create the Set.
- /// Descriptor Pool used to create the Set.
- /// Descriptor Set Layout to create the Set with.
- SHVkDescriptorSetGroup(Handle deviceHdl, Handle pool,
- std::vector> const& layouts,
- std::vector const& variableDescCounts);
- SHVkDescriptorSetGroup(const SHVkDescriptorSetGroup&) = delete;
- SHVkDescriptorSetGroup(SHVkDescriptorSetGroup&& rhs) noexcept = default;
- ///
- /// Destructor which will unload and deallocate all resources for this Descriptor Set.
- ///
- ~SHVkDescriptorSetGroup() noexcept;
+ /// Vulkan logical device used to create the Set.
+ /// Descriptor Pool used to create the Set.
+ /// Descriptor Set Layout to create the Set with.
+ SHVkDescriptorSetGroup(Handle deviceHdl, Handle pool,
+ std::vector> const& layouts,
+ std::vector const& variableDescCounts);
+ SHVkDescriptorSetGroup(const SHVkDescriptorSetGroup&) = delete;
+ SHVkDescriptorSetGroup(SHVkDescriptorSetGroup&& rhs) noexcept = default;
+ ///
+ /// Destructor which will unload and deallocate all resources for this Descriptor Set.
+ ///
+ ~SHVkDescriptorSetGroup() noexcept;
- /*-----------------------------------------------------------------------------*/
- /* Overloaded Operators */
- /*-----------------------------------------------------------------------------*/
- SHVkDescriptorSetGroup& operator=(const SHVkDescriptorSetGroup&) = delete;
- SHVkDescriptorSetGroup& operator=(SHVkDescriptorSetGroup&& rhs) noexcept = default;
+ /*-----------------------------------------------------------------------------*/
+ /* Overloaded Operators */
+ /*-----------------------------------------------------------------------------*/
+ SHVkDescriptorSetGroup& operator=(const SHVkDescriptorSetGroup&) = delete;
+ SHVkDescriptorSetGroup& operator=(SHVkDescriptorSetGroup&& rhs) noexcept = default;
- /*-----------------------------------------------------------------------------*/
- /* Getter Functions */
- /*-----------------------------------------------------------------------------*/
- ///
- /// Retrieves the handle to the Vulkan Descriptor Set handle.
- ///
- /// Handle to the Vulkan Descriptor Set.
- [[nodiscard]]
- inline const std::vector& GetVkHandle() { return descSets; }
+ /*-----------------------------------------------------------------------------*/
+ /* Descriptor set writing */
+ /*-----------------------------------------------------------------------------*/
+ void ModifyWriteDescImage (uint32_t set, uint32_t binding, std::vector> const& imageViewsAndSamplers) noexcept;
+ void UpdateDescriptorSet (void) noexcept;
- private:
- /*-----------------------------------------------------------------------------*/
- /* Data Members */
- /*-----------------------------------------------------------------------------*/
- Handle device;
- Handle descPool;
- std::vector descSets;
- };
+ /*-----------------------------------------------------------------------------*/
+ /* Getter Functions */
+ /*-----------------------------------------------------------------------------*/
+ ///
+ /// Retrieves the handle to the Vulkan Descriptor Set handle.
+ ///
+ /// Handle to the Vulkan Descriptor Set.
+ [[nodiscard]]
+ inline const std::vector& GetVkHandle() { return descSets; }
+ private:
+ /*-----------------------------------------------------------------------------*/
+ /* Data Members */
+ /*-----------------------------------------------------------------------------*/
+ //! Device required to allocate descriptor sets
+ Handle device;
+
+ //! Descriptor pool to allocate descriptor sets
+ Handle descPool;
+
+ //! Descriptor sets
+ std::vector descSets;
+
+ //! for updating descriptor sets. We want to cache this so that we don't create the
+ //! write structs at runtime.
+ SHDescriptorSetUpdater updater;
+
+ };
}
diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp
index 36eaa8e8..da1a3645 100644
--- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp
+++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp
@@ -85,6 +85,11 @@ namespace SHADE
device->GetVkLogicalDevice().destroyDescriptorSetLayout(setLayout);
}
+ std::vector const& SHVkDescriptorSetLayout::GetBindings(void) const noexcept
+ {
+ return layoutDesc;
+ }
+
SHVkDescriptorSetLayout& SHVkDescriptorSetLayout::operator=(SHVkDescriptorSetLayout&& rhs) noexcept
{
if (&rhs == this)
diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h
index 590fd787..1acba189 100644
--- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h
+++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h
@@ -96,6 +96,7 @@ namespace SHADE
///
/// Handle to the Vulkan Descriptor Set Layout handle.
inline const vk::DescriptorSetLayout& GetVkHandle() const { return setLayout; }
+ std::vector const& GetBindings (void) const noexcept;
private:
/*-----------------------------------------------------------------------------*/
diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp
index 0fa1c864..da4947f2 100644
--- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp
+++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp
@@ -418,7 +418,12 @@ namespace SHADE
/***************************************************************************/
Handle SHVkLogicalDevice::CreateImage(uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) const noexcept
{
- return SHVkInstance::GetResourceManager().Create(std::cref(vmaAllocator), w, h, levels, format, usage, create);
+ return SHVkInstance::GetResourceManager().Create(&vmaAllocator, w, h, levels, format, usage, create);
+ }
+
+ Handle SHVkLogicalDevice::CreateImage(SHImageCreateParams const& imageDetails, unsigned char* data, uint32_t dataSize, std::span inMipOffsets, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags) noexcept
+ {
+ return SHVkInstance::GetResourceManager().Create(&vmaAllocator, imageDetails, data, dataSize, inMipOffsets, memUsage, allocFlags);
}
/***************************************************************************/
@@ -547,6 +552,22 @@ namespace SHADE
return SHVkInstance::GetResourceManager().Create(GetHandle());
}
+ /***************************************************************************/
+ /*!
+
+ \brief
+ Writes to descriptor sets.
+
+ \param writeDescSets
+ Descriptor sets to write to.
+
+ */
+ /***************************************************************************/
+ void SHVkLogicalDevice::UpdateDescriptorSets(std::vector const& writeDescSets) noexcept
+ {
+ vkLogicalDevice.updateDescriptorSets(writeDescSets, {});
+ }
+
/***************************************************************************/
/*!
diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h
index 78108b94..c359d1d3 100644
--- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h
+++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h
@@ -19,6 +19,7 @@
#include "vk_mem_alloc.h"
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
+#include "Graphics/Images/SHVkImage.h"
namespace SHADE
{
@@ -29,7 +30,6 @@ namespace SHADE
class SHVkSurface;
class SHVkSwapchain;
class SHVkBuffer;
- class SHVkImage;
class SHVkFence;
class SHVkSemaphore;
class SHVkShaderModule;
@@ -38,6 +38,7 @@ namespace SHADE
class SHVkFramebuffer;
class SHVkImageView;
class SHShaderBlockInterface;
+ class SHVkDescriptorSetGroup;
/***************************************************************************/
/*!
@@ -138,14 +139,23 @@ namespace SHADE
) const noexcept;
Handle CreateImage (
- uint32_t w,
- uint32_t h,
- uint8_t levels,
- vk::Format format,
- vk::ImageUsageFlags usage,
- vk::ImageCreateFlags create
+ uint32_t w,
+ uint32_t h,
+ uint8_t levels,
+ vk::Format format,
+ vk::ImageUsageFlags usage,
+ vk::ImageCreateFlags create
) const noexcept;
-
+
+ Handle CreateImage (
+ SHImageCreateParams const& imageDetails,
+ unsigned char* data,
+ uint32_t dataSize,
+ std::span inMipOffsets,
+ VmaMemoryUsage memUsage,
+ VmaAllocationCreateFlags allocFlags
+ ) noexcept;
+
Handle CreateShaderModule (
std::vector const& binaryData,
std::string entryPoint,
@@ -170,6 +180,8 @@ namespace SHADE
Handle CreateFence (void) const noexcept;
Handle CreateSemaphore (void) const noexcept;
+ void UpdateDescriptorSets (std::vector const& writeDescSets) noexcept;
+
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/
diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp b/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp
index 11fbe5dd..f3d5a7b5 100644
--- a/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp
+++ b/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp
@@ -5,14 +5,88 @@
#include "Tools/SHLogger.h"
#include "SHVkImageView.h"
#include "Graphics/Instance/SHVkInstance.h"
+#include "Graphics/Buffers/SHVkBuffer.h"
namespace SHADE
{
+ /***************************************************************************/
+ /*!
+
+ \brief
+ If an image is a GPU only resource, we need to prep a staging buffer
+ to use for transferring data to the GPU. #NoteToSelf: I don't really
+ like this because its duplicate code. Should try to find a way to utilize
+ the logical device for this.
+
+ \param data
+ Data to transfer.
+
+ \param srcSize
+ Size in bytes of the data.
+
+ */
+ /***************************************************************************/
+ void SHVkImage::PrepStagingBuffer(void* data, uint32_t srcSize) noexcept
+ {
+ // For creation of buffer
+ vk::BufferCreateInfo bufferInfo{};
+
+ // size stored same as GPU buffer
+ bufferInfo.size = srcSize;
+
+ // We just want to set the transfer bit
+ bufferInfo.usage = vk::BufferUsageFlagBits::eTransferSrc;
+
+ // sharing mode exclusive
+ bufferInfo.sharingMode = vk::SharingMode::eExclusive;
+
+ // Set to auto detect bits
+ VmaAllocationCreateInfo allocCreateInfo{};
+ allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
+
+ // We want to just write all at once. Using random access bit could make this slow
+ allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
+
+ // parameters of a vmaAllocation retrieved via vmaGetAllocationInfo
+ VmaAllocationInfo allocInfo;
+
+ // results of allocation
+ VmaAllocation stagingAlloc;
+
+ // To get around VMA's usage for C version of vulkan, create a temp first...,
+ VkBuffer tempBuffer{};
+
+ // Create the buffer...
+ vmaCreateBuffer(*vmaAllocator,
+ &bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use renderdoc to check buffer variables?)
+ &allocCreateInfo,
+ &tempBuffer, &stagingAlloc, &allocInfo);
+
+ // then assign it to the hpp version
+ stagingBuffer = tempBuffer;
+
+ // Just map, copy then unmap
+ void* stagingBufferMappedPtr = nullptr;
+ vmaMapMemory(*vmaAllocator, stagingAlloc, &stagingBufferMappedPtr);
+
+ if (stagingBufferMappedPtr)
+ std::memcpy(static_cast(stagingBufferMappedPtr), static_cast(data), srcSize);
+
+ const VkDeviceSize offsets = 0;
+ const VkDeviceSize sizes = srcSize;
+ vmaFlushAllocations(*vmaAllocator, 1, &stagingAlloc, &offsets, &sizes);
+
+ vmaUnmapMemory(*vmaAllocator, stagingAlloc);
+ }
+
SHVkImage::SHVkImage(
- VmaAllocator const& vmaAllocator,
- SHImageCreateParams const& imageDetails,
- VmaMemoryUsage memUsage,
- VmaAllocationCreateFlags allocFlags
+ VmaAllocator const* allocator,
+ SHImageCreateParams const& imageDetails,
+ unsigned char* data,
+ uint32_t dataSize,
+ std::span inMipOffsets,
+ VmaMemoryUsage memUsage,
+ VmaAllocationCreateFlags allocFlags
) noexcept
: imageType { imageDetails.imageType }
, width{ imageDetails.width }
@@ -23,12 +97,14 @@ namespace SHADE
, imageFormat{ imageDetails.imageFormat }
, usageFlags{}
, createFlags{}
+ , vmaAllocator{allocator}
+ , mipOffsets { inMipOffsets }
+ , boundToCoherent{false}
+ , randomAccessOptimized {false}
+ , mappedPtr{nullptr}
{
- for (auto& bit : imageDetails.usageBits)
- usageFlags |= bit;
-
- for (auto& bit : imageDetails.createBits)
- createFlags |= bit;
+ usageFlags = imageDetails.usageFlags;
+ createFlags = imageDetails.createFlags;
// If marked as 2D array compatible, image type MUST be 3D
if (createFlags & vk::ImageCreateFlagBits::e2DArrayCompatible)
@@ -64,58 +140,52 @@ namespace SHADE
VmaAllocationInfo allocInfo{};
VkImage tempImage;
- vmaCreateImage(vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo&(), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
+ auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo&(), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
+
+ if (result != VK_SUCCESS)
+ SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
+ else
+ SHVulkanDebugUtil::ReportVkSuccess("Successfully created image. ");
+
vkImage = tempImage;
- //if (allocFlags & )
+ // At this point the image and device memory have been created.
+
+ if (allocFlags & VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)
+ randomAccessOptimized = true;
+
+ // TODO: This constructor can only create a GPU only resource for now. Due to time constraint, I was trying to create a ctor
+ // fast to finish up the ImGUI backend. In the future, there definitely needs to be more versatility to the constructor.
+
+ // Get the memory property flags
+ VkMemoryPropertyFlags memPropFlags;
+ vmaGetAllocationMemoryProperties(*vmaAllocator, alloc, &memPropFlags);
+
+ // mainly host visible. Can be cached (need to flush/invalidate), uncached (always coherent) and coherent (virtual).
+ //if (memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
+ //{
+ // // If memory is marked to be coherent between CPU and GPU (no need flush/invalidate) (TODO: Verify if VMA_ALLOCATION_CREATE_MAPPED_BIT is used when VMA_MEMORY_USAGE_AUTO is set)
+ // // TODO: also verify that coherent bit = pointer is already mapped
+ // if (memPropFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
+ // {
+ // boundToCoherent = true;
+ // mappedPtr = allocInfo.pMappedData;
+ // }
+ // else
+ // mappedPtr = nullptr;
+
+ // if (data)
+ // MapWriteUnmap(data, srcSize, 0, 0);
+ //}
+ //else
+ //{
+ // We can prep first so that we can do transfers later via 1 cmd buffer recording
+ PrepStagingBuffer(data, dataSize);
+
+ //}
}
- /***************************************************************************/
- /*!
-
- \brief
- This is mainly used for images that aren't created internally because
- they cannot be created in the traditional way (e.g. swapchain images).
-
- \param inVkImage
- Image already created outside
-
- \param width
- Width of the image
-
- \param height
- Height of the image
-
- \param depth
- Depth of the image
-
- \param levels
- Number of levels in the image
-
- \param arrayLayers
- if the image is an array, this value will be > 1.
-
- \param imageFormat
- Format of the image
-
- */
- /***************************************************************************/
- SHVkImage::SHVkImage(vk::Image inVkImage, vk::ImageType type, uint32_t inWidth, uint32_t inHeight, uint32_t inDepth, uint32_t arrayLayers, uint8_t levels, vk::Format format, vk::ImageUsageFlags flags) noexcept
- : vkImage (inVkImage)
- , width{ inWidth }
- , height{ inHeight }
- , depth{ inDepth }
- , mipLevelCount{ levels }
- , layerCount{ arrayLayers }
- , imageFormat{ format }
- , usageFlags{flags}
- , alloc{}
- , imageType{type}
- , createFlags{}
- {
- }
-
- SHVkImage::SHVkImage(VmaAllocator const& vmaAllocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept
+ SHVkImage::SHVkImage(VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept
: width {w}
, height{h}
, depth {1}
@@ -124,6 +194,7 @@ namespace SHADE
, imageFormat{format}
, usageFlags{usage}
, createFlags {create}
+ , vmaAllocator {allocator}
{
vk::ImageCreateInfo imageCreateInfo{};
imageCreateInfo.imageType = vk::ImageType::e2D;
@@ -149,7 +220,7 @@ namespace SHADE
VmaAllocationInfo allocInfo{};
VkImage tempImage;
- auto result = vmaCreateImage(vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
+ auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
vkImage = tempImage;
if (result != VK_SUCCESS)
@@ -163,6 +234,86 @@ namespace SHADE
return SHVkInstance::GetResourceManager().Create(inLogicalDeviceHdl, parent, createParams);
}
+ void SHVkImage::TransferToDeviceResource(Handle const& cmdBufferHdl) noexcept
+ {
+ // prepare copy regions
+ std::vector copyRegions{mipOffsets.size()};
+
+ for (uint32_t i = 0; i < mipOffsets.size(); ++i)
+ {
+ copyRegions[i].bufferOffset = mipOffsets[i];
+ copyRegions[i].bufferRowLength = 0; // for padding
+ copyRegions[i].bufferImageHeight = 0; // for padding
+ copyRegions[i].imageSubresource.aspectMask = vk::ImageAspectFlagBits::eColor; // TODO: Need to change this to base it off image format.
+ copyRegions[i].imageSubresource.mipLevel = i;
+ copyRegions[i].imageSubresource.baseArrayLayer = 0; // TODO: Array textures not supported yet
+ copyRegions[i].imageSubresource.layerCount = layerCount;
+ copyRegions[i].imageOffset = vk::Offset3D{ 0,0,0 };
+ copyRegions[i].imageExtent = vk::Extent3D{ width >> i, height >> i, 1 };
+ }
+
+ }
+
+ /***************************************************************************/
+ /*!
+
+ \brief
+ Does not perform any image transitions but prepares a barrier for image
+ transitioning. Pipeline barrier will be issued outside this call after
+ this preparation function, or at least, it should be.
+
+ \param oldLayout
+ Old layout of the image.
+
+ \param newLayout
+ new layout of the image to transition to.
+
+ \param barrier
+ Barrier to modify to prepare the image for transitioning.
+
+ */
+ /***************************************************************************/
+ void SHVkImage::PrepareImageTransition(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept
+ {
+ barrier.oldLayout = oldLayout;
+ barrier.newLayout = newLayout;
+ barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ barrier.image = vkImage;
+ barrier.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor; // TODO: Need to change this to base it off image format.
+ barrier.subresourceRange.baseMipLevel = 0;
+ barrier.subresourceRange.levelCount = mipLevelCount;
+ barrier.subresourceRange.baseArrayLayer = 0;
+ barrier.subresourceRange.layerCount = layerCount;
+
+ vk::PipelineStageFlagBits srcStage = vk::PipelineStageFlagBits::eTopOfPipe;
+ vk::PipelineStageFlagBits dstStage = vk::PipelineStageFlagBits::eTopOfPipe;
+
+ if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eTransferDstOptimal)
+ {
+ srcStage = vk::PipelineStageFlagBits::eTopOfPipe;
+ dstStage = vk::PipelineStageFlagBits::eTransfer;
+
+ barrier.srcAccessMask = vk::AccessFlagBits::eNone;
+ barrier.dstAccessMask = vk::AccessFlagBits::eTransferWrite;
+ }
+ else if (oldLayout == vk::ImageLayout::eTransferDstOptimal && newLayout == vk::ImageLayout::eShaderReadOnlyOptimal)
+ {
+ srcStage = vk::PipelineStageFlagBits::eTransfer;
+
+ // TODO, what if we want to access in compute shader
+ dstStage = vk::PipelineStageFlagBits::eFragmentShader;
+
+ barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite;
+ barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead;
+ }
+ else
+ {
+ SHLOG_ERROR("Image layouts are invalid. ");
+ }
+
+ }
+
void SHVkImage::LinkWithExteriorImage(vk::Image inVkImage, vk::ImageType type, uint32_t inWidth, uint32_t inHeight, uint32_t inDepth, uint32_t layers, uint8_t levels, vk::Format format, vk::ImageUsageFlags flags) noexcept
{
vkImage = inVkImage;
diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImage.h b/SHADE_Engine/src/Graphics/Images/SHVkImage.h
index 53066075..a30b90e6 100644
--- a/SHADE_Engine/src/Graphics/Images/SHVkImage.h
+++ b/SHADE_Engine/src/Graphics/Images/SHVkImage.h
@@ -10,6 +10,7 @@ namespace SHADE
{
class SHVkLogicalDevice;
class SHVkImageView;
+ class SHVkCommandBuffer;
struct SHImageCreateParams
{
@@ -35,10 +36,10 @@ namespace SHADE
vk::Format imageFormat;
//! Image usage bits
- std::span usageBits;
+ vk::ImageUsageFlags usageFlags;
//! Image create flags
- std::span createBits;
+ vk::ImageCreateFlags createFlags;
};
class SHVkImage
@@ -47,6 +48,12 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */
/*-----------------------------------------------------------------------*/
+ //! Pointer to the vma allocator. #NoteToSelf: Not super proud of this being a pointer.
+ //! The only reason why this is a pointer is because a reference_wrapper cannot be default constructed.
+ //! And the reason why we want a default constructor is because sometimes we don't want to create images
+ //! but merely link them from outside (swapchain images)
+ VmaAllocator const* vmaAllocator;
+
//! 1D, 2D or 3D
vk::ImageType imageType = vk::ImageType::e2D;
@@ -80,22 +87,46 @@ namespace SHADE
//! allocation object containing details of an allocation
VmaAllocation alloc{};
+ //! Whether or not this image is HOST_VISIBLE and random access optimized
+ bool randomAccessOptimized;
+
+ //! Whether or not the memory the image is bound to is memory coherent (updates on CPU can be seen on GPU without flushing cache)
+ bool boundToCoherent;
+
+ //! Persistently mapped pointer if applicable (will be void if image is
+ //! not created with the correct flags). Note that this is only used for
+ //! persistent mapping. One time updates do not use this pointer.
+ void* mappedPtr;
+
+ //! Staging buffer for images purely in the GPU
+ vk::Buffer stagingBuffer;
+
+ //! Mipmap offsets for initializing the vk::BufferImageCopy during transfer to GPU resource
+ std::span mipOffsets;
+
+ /*-----------------------------------------------------------------------*/
+ /* PRIVATE MEMBER FUNCTIONS */
+ /*-----------------------------------------------------------------------*/
+ void PrepStagingBuffer(void* data, uint32_t srcSize) noexcept;
+
+
public:
/*-----------------------------------------------------------------------*/
/* CTOR AND DTOR */
/*-----------------------------------------------------------------------*/
SHVkImage(void) noexcept = default;
- // TODO: Might need to add flags to parameters
SHVkImage(
- VmaAllocator const& vmaAllocator,
- SHImageCreateParams const& imageDetails,
- VmaMemoryUsage memUsage,
- VmaAllocationCreateFlags allocFlags
+ VmaAllocator const* allocator,
+ SHImageCreateParams const& imageDetails,
+ unsigned char* data,
+ uint32_t dataSize,
+ std::span inMipOffsets,
+ VmaMemoryUsage memUsage,
+ VmaAllocationCreateFlags allocFlags
) noexcept;
- SHVkImage(vk::Image inVkImage, vk::ImageType type, uint32_t inWidth, uint32_t inHeight, uint32_t inDepth, uint32_t arrayLayers, uint8_t levels, vk::Format format, vk::ImageUsageFlags flags) noexcept;
- SHVkImage(VmaAllocator const& vmaAllocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept;
+ SHVkImage(VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept;
SHVkImage(SHVkImage&& rhs) noexcept = default;
SHVkImage& operator=(SHVkImage && rhs) noexcept = default;
@@ -103,7 +134,9 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
- Handle CreateImageView(Handle const& inLogicalDeviceHdl, Handle const& parent, SHImageViewDetails const& createParams) const noexcept;
+ Handle CreateImageView (Handle const& inLogicalDeviceHdl, Handle const& parent, SHImageViewDetails const& createParams) const noexcept;
+ void TransferToDeviceResource (Handle const& cmdBufferHdl) noexcept;
+ void PrepareImageTransition (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept;
/*-----------------------------------------------------------------------*/
/* GETTERS AND SETTERS */
diff --git a/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp b/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp
new file mode 100644
index 00000000..e7a97126
--- /dev/null
+++ b/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp
@@ -0,0 +1,7 @@
+#include "SHpch.h"
+#include "SHVkSampler.h"
+
+namespace SHADE
+{
+
+}
\ No newline at end of file
diff --git a/SHADE_Engine/src/Graphics/Images/SHVkSampler.h b/SHADE_Engine/src/Graphics/Images/SHVkSampler.h
new file mode 100644
index 00000000..d58edb8f
--- /dev/null
+++ b/SHADE_Engine/src/Graphics/Images/SHVkSampler.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include "Graphics/SHVulkanIncludes.h"
+
+namespace SHADE
+{
+ struct SHVkSamplerParams
+ {
+ vk::Filter minFilter;
+ vk::Filter maxFilter;
+ //vk::Filter maxFilter;
+ };
+
+ class SHVkSampler
+ {
+ private:
+ //! The vulkan sampler handler
+ vk::Sampler vkSampler;
+
+ public:
+ SHVkSampler () noexcept;
+ SHVkSampler (SHVkSampler&& rhs) noexcept;
+ SHVkSampler&& operator=(SHVkSampler&& rhs) noexcept;
+
+ };
+}
+
diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp
index d9761adf..4d4ca4f4 100644
--- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp
+++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp
@@ -84,8 +84,6 @@ namespace SHADE
//commandBuffers[i] = commandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); // works
}
-
-
descPool = device->CreateDescriptorPools();
diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.cpp
index 8179444f..6094958e 100644
--- a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.cpp
+++ b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.cpp
@@ -117,7 +117,7 @@ namespace SHADE
dirty = isDirty;
}
- std::tuple SHVertexInputState::GetInfoFromAttribFormat(SHAttribFormat attribFormat) const noexcept
+ std::tuple SHVertexInputState::GetInfoFromAttribFormat(SHAttribFormat attribFormat) const noexcept
{
switch (attribFormat)
{
@@ -138,6 +138,9 @@ namespace SHADE
case SHAttribFormat::MAT_4D:
return std::make_tuple(4, 16, vk::Format::eR32G32B32A32Sfloat);
break;
+
+ case SHAttribFormat::UINT32_1D:
+ return std::make_tuple(1, 4, vk::Format::eR32Uint);
}
return std::make_tuple(0, 0, vk::Format::eR32Sfloat);
}
diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp
index 4ad29f73..71bac1e6 100644
--- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp
+++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp
@@ -182,12 +182,12 @@ namespace SHADE
}
/***************************************************************************/
- /*!
-
+ /*!
+
\brief
Destructor for resource.
-
- */
+
+ */
/***************************************************************************/
SHRenderGraphResource::~SHRenderGraphResource(void) noexcept
{
@@ -195,37 +195,38 @@ namespace SHADE
}
/***************************************************************************/
- /*!
-
+ /*!
+
\brief
Subpass non-default constructor. Simply initializes variables.
-
+
\param mapping
Mapping from a resource handle to an attachment reference referencing
the resource.
\param resources
A mapping from string to render graph resource.
-
- */
+
+ */
/***************************************************************************/
- SHRenderGraphNode::SHSubpass::SHSubpass(std::unordered_map const* mapping, std::unordered_map> const* resources) noexcept
+ SHRenderGraphNode::SHSubpass::SHSubpass(Handle const& parent, std::unordered_map const* mapping, std::unordered_map> const* resources) noexcept
: resourceAttachmentMapping{ mapping }
, ptrToResources{ resources }
+ , parentNode{ parent }
{
}
/***************************************************************************/
- /*!
-
+ /*!
+
\brief
Move constructor for subpass.
-
+
\param rhs
The subpass the move from.
-
- */
+
+ */
/***************************************************************************/
SHRenderGraphNode::SHSubpass::SHSubpass(SHSubpass&& rhs) noexcept
: colorReferences{ std::move(rhs.colorReferences) }
@@ -238,15 +239,15 @@ namespace SHADE
}
/***************************************************************************/
- /*!
-
+ /*!
+
\brief
Move assignment operator for subpass.
-
+
\param rhs
subpass to move from.
-
- */
+
+ */
/***************************************************************************/
SHRenderGraphNode::SHSubpass& SHRenderGraphNode::SHSubpass::operator=(SHSubpass&& rhs) noexcept
{
@@ -263,16 +264,16 @@ namespace SHADE
}
/***************************************************************************/
- /*!
-
+ /*!
+
\brief
- Adds a color output to a subpass. Takes in a string and finds the
+ Adds a color output to a subpass. Takes in a string and finds the
attachment index to create the vk::SubpassReference.
-
+
\param resourceToReference
Resource name to find resource to attach.
-
- */
+
+ */
/***************************************************************************/
void SHRenderGraphNode::SHSubpass::AddColorOutput(std::string resourceToReference) noexcept
{
@@ -280,8 +281,8 @@ namespace SHADE
}
/***************************************************************************/
- /*!
-
+ /*!
+
\brief
Adds a depth output to a subpass. Takes in a string and finds the
attachment index to create the vk::SubpassReference.
@@ -292,8 +293,8 @@ namespace SHADE
\param attachmentDescriptionType
Depending on the type of the resource, initialize the image layout
appropriately.
-
- */
+
+ */
/***************************************************************************/
void SHRenderGraphNode::SHSubpass::AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType) noexcept
{
@@ -317,8 +318,8 @@ namespace SHADE
}
/***************************************************************************/
- /*!
-
+ /*!
+
\brief
Adds a input output to a subpass. Takes in a string and finds the
attachment index to create the vk::SubpassReference.
@@ -326,21 +327,53 @@ namespace SHADE
\param resourceToReference
Resource name to find resource to attach.
- */
+ */
/***************************************************************************/
void SHRenderGraphNode::SHSubpass::AddInput(std::string resourceToReference) noexcept
{
inputReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal });
}
+ void SHRenderGraphNode::SHSubpass::Execute(Handle& commandBuffer) noexcept
+ {
+ // Draw all the batches
+
+ // Draw all the exterior draw calls
+ for (auto& drawCall : exteriorDrawCalls)
+ {
+ drawCall(commandBuffer);
+ }
+ }
+
+ void SHRenderGraphNode::SHSubpass::AddExteriorDrawCalls(std::function&)> const& newDrawCall) noexcept
+ {
+ exteriorDrawCalls.push_back(newDrawCall);
+ }
+
/***************************************************************************/
- /*!
-
+ /*!
+
\brief
- Creates a renderpass for the node. Uses subpass and attachment
+ Getter for parent renderpass.
+
+ \return
+ Returns the parent renderpass the subpass belongs to.
+
+ */
+ /***************************************************************************/
+ Handle const& SHRenderGraphNode::SHSubpass::GetParentNode(void) const noexcept
+ {
+ return parentNode;
+ }
+
+ /***************************************************************************/
+ /*!
+
+ \brief
+ Creates a renderpass for the node. Uses subpass and attachment
descriptions already configured beforehand in the render graph.
-
- */
+
+ */
/***************************************************************************/
void SHRenderGraphNode::CreateRenderpass(void) noexcept
{
@@ -348,12 +381,12 @@ namespace SHADE
}
/***************************************************************************/
- /*!
-
+ /*!
+
\brief
Creates a framebuffer from the images used in the renderpass.
-
- */
+
+ */
/***************************************************************************/
void SHRenderGraphNode::CreateFramebuffer(void) noexcept
{
@@ -489,18 +522,18 @@ namespace SHADE
}
/***************************************************************************/
- /*!
-
+ /*!
+
\brief
Add subpasses to the renderpass and returns a reference to it.
-
+
\param subpassName
Name of the subpass.
-
+
\return
Handle to the new subpass.
-
- */
+
+ */
/***************************************************************************/
Handle SHRenderGraphNode::AddSubpass(std::string subpassName) noexcept
{
@@ -512,20 +545,35 @@ namespace SHADE
}
// Add subpass to container and create mapping for it
- subpasses.emplace_back(resourceManager.Create(&resourceAttachmentMapping, ptrToResources));
- subpassIndexing.try_emplace(subpassName, subpasses.size() - 1);
+ subpasses.emplace_back(resourceManager.Create(GetHandle(), &resourceAttachmentMapping, ptrToResources));
+ subpassIndexing.try_emplace(subpassName, static_cast(subpasses.size()) - 1u);
return subpasses.at(subpassIndexing[subpassName]);
}
+ void SHRenderGraphNode::Execute(Handle& 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();
+ }
+
/***************************************************************************/
/*!
-
+
\brief
Get the renderpass from the node.
-
- \return
+
+ \return
Handle to the renderpass.
-
+
*/
/***************************************************************************/
Handle SHRenderGraphNode::GetRenderpass(void) const noexcept
@@ -560,7 +608,7 @@ namespace SHADE
*/
/***************************************************************************/
- void SHRenderGraph::AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w /*= static_cast(-1)*/, uint32_t h /*= static_cast(-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(-1)*/, uint32_t h /*= static_cast(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageCreateFlagBits createFlags /*= {}*/)
{
// If we set to
if (w == static_cast(-1) && h == static_cast(-1))
@@ -663,16 +711,16 @@ namespace SHADE
}
/***************************************************************************/
- /*!
-
+ /*!
+
\brief
Configures the supasses; mainly the subpass descriptions and the
subpass dependencies involved between subpasses.
-
-
- \return
-
- */
+
+
+ \return
+
+ */
/***************************************************************************/
void SHRenderGraph::ConfigureSubpasses(void) noexcept
{
@@ -801,12 +849,12 @@ namespace SHADE
}
/***************************************************************************/
- /*!
-
+ /*!
+
\brief
Simply loops through all nodes and create renderpasses.
-
- */
+
+ */
/***************************************************************************/
void SHRenderGraph::ConfigureRenderpasses(void) noexcept
{
@@ -817,12 +865,12 @@ namespace SHADE
}
/***************************************************************************/
- /*!
-
+ /*!
+
\brief
Simply loops through all nodes and create framebuffers.
-
- */
+
+ */
/***************************************************************************/
void SHRenderGraph::ConfigureFramebuffers(void) noexcept
{
@@ -836,7 +884,21 @@ namespace SHADE
/*!
\brief
- Init function. Doesn't do much except initialize device and swapchain
+ 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(swapchainHdl->GetNumImages()));
+ }
+
+ /***************************************************************************/
+ /*!
+
+ \brief
+ Init function. Doesn't do much except initialize device and swapchain
handle. Graph should start out empty.
\param swapchain
@@ -854,15 +916,15 @@ namespace SHADE
}
/***************************************************************************/
- /*!
-
+ /*!
+
\brief
Default ctor, doesn't do much.
-
-
- \return
-
- */
+
+
+ \return
+
+ */
/***************************************************************************/
SHRenderGraph::SHRenderGraph(void) noexcept
: logicalDeviceHdl{ }
@@ -929,7 +991,7 @@ namespace SHADE
}
nodes.emplace_back(resourceManager.Create(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(resources), std::move(predecessors), &graphResources));
- nodeIndexing.emplace(nodeName, nodes.size() - 1);
+ nodeIndexing.emplace(nodeName, static_cast(nodes.size()) - 1u);
return nodes.at(nodeIndexing[nodeName]);
}
@@ -952,14 +1014,20 @@ namespace SHADE
ConfigureSubpasses();
ConfigureRenderpasses();
ConfigureFramebuffers();
+ ConfigureCommands();
}
- void SHRenderGraph::Execute(void) noexcept
+ 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 SHRenderGraph::GetNode(std::string const& nodeName) const noexcept
diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h
index 7ba49e84..ea913baa 100644
--- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h
+++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h
@@ -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
{
public:
class SHSubpass
{
public:
- SHSubpass(std::unordered_map const* mapping, std::unordered_map> const* ptrToResources) noexcept;
+ /*-----------------------------------------------------------------------*/
+ /* CTORS AND DTORS */
+ /*-----------------------------------------------------------------------*/
+ SHSubpass(Handle const& parent, std::unordered_map const* mapping, std::unordered_map> 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& commandBuffer) noexcept;
+ void AddExteriorDrawCalls (std::function&)> const& newDrawCall) noexcept;
+
+ /*-----------------------------------------------------------------------*/
+ /* GETTERS AND SETTERS */
+ /*-----------------------------------------------------------------------*/
+ Handle const& GetParentNode (void) const noexcept;
private:
/*---------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */
/*---------------------------------------------------------------------*/
+ //! The parent renderpass that this subpass belongs to
+ Handle parentNode;
+
//! Color attachments
std::vector colorReferences;
@@ -106,6 +127,14 @@ namespace SHADE
//! Pointer to resources in the render graph (for getting handle IDs)
std::unordered_map> 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&)>> exteriorDrawCalls;
+
friend class SHRenderGraphNode;
friend class SHRenderGraph;
};
@@ -179,6 +208,7 @@ namespace SHADE
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
Handle AddSubpass (std::string subpassName) noexcept;
+ void Execute (Handle& 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 commandPool;
+
+ //! Command buffers for the render graph
+ std::vector> commandBuffers;
+
+
public:
/*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */
@@ -229,10 +267,10 @@ namespace SHADE
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
void Init (Handle const& logicalDevice, Handle const& swapchain) noexcept;
- void AddResource (std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w = static_cast(-1), uint32_t h = static_cast(-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(-1), uint32_t h = static_cast(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageCreateFlagBits createFlags = {});
Handle AddNode (std::string nodeName, std::initializer_list resourceNames, std::initializer_list predecessorNodes) noexcept;
void Generate (void) noexcept;
- void Execute (void) noexcept;
+ void Execute (uint32_t frameIndex) noexcept;
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */
diff --git a/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.cpp b/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.cpp
index 8beb7d98..1e5fb074 100644
--- a/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.cpp
+++ b/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.cpp
@@ -189,7 +189,7 @@ namespace SHADE
Handle SHShaderDescriptorBindingInfo::GetShaderBlockInterface(uint32_t set, uint32_t binding) const noexcept
{
- SHShaderDescriptorBindingInfo::BindingAndSetHash hash = binding;
+ BindingAndSetHash hash = binding;
hash |= static_cast(set) << 32;
if (blockInterfaces.contains(hash))
return blockInterfaces.at(hash);
diff --git a/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.h b/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.h
index 1250b54f..88c7a2e1 100644
--- a/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.h
+++ b/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.h
@@ -9,11 +9,10 @@
namespace SHADE
{
+ using BindingAndSetHash = uint64_t;
+
struct SHShaderDescriptorBindingInfo
{
- public:
- using BindingAndSetHash = uint64_t;
-
private:
/*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */
diff --git a/SHADE_Engine/src/Graphics/VertexDescriptors/SHVertexAttribute.h b/SHADE_Engine/src/Graphics/VertexDescriptors/SHVertexAttribute.h
index fd8ee3d1..b216f5f4 100644
--- a/SHADE_Engine/src/Graphics/VertexDescriptors/SHVertexAttribute.h
+++ b/SHADE_Engine/src/Graphics/VertexDescriptors/SHVertexAttribute.h
@@ -18,7 +18,10 @@ namespace SHADE
// that a mat2 can be interpreted as (x, y, x, y), (o, o, o, o) instead of (x, y, o, o), (o, o, o, o)?
MAT_2D,
MAT_3D,
- MAT_4D
+ MAT_4D,
+
+ // integer formats
+ UINT32_1D,
};
struct SHVertexAttribute
diff --git a/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp b/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp
index 6ac6672b..957ffc34 100644
--- a/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp
+++ b/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp
@@ -222,7 +222,7 @@ namespace SHADE
return true;
{
MSG Message;
- while (PeekMessageW(&Message, NULL, 0, 0, PM_REMOVE))
+ while (PeekMessageW(&Message, wndHWND, 0, 0, PM_REMOVE))
{
if (WM_QUIT == Message.message)
{