From b035582b304fe749349d1221e3692f9c1973cf9c Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 25 Dec 2022 14:32:50 +0800 Subject: [PATCH] Renamed SHGraphicsGlobalData to SHPredefinedData - SHPredefinedData now contains the font data descriptor set layout as well - Added a function for SHPredefinedData to retrieve descriptor sets based on a bitfield - Modified descriptor sets to not be tied to a set index anymore - Descriptor set layout doesn't have a set anymore - Removed desc set index constants from SHGraphicsConstants since they aren't really needed anymore --- .../Descriptors/SHVkDescriptorSetGroup.cpp | 17 +- .../Descriptors/SHVkDescriptorSetGroup.h | 9 +- .../Descriptors/SHVkDescriptorSetLayout.cpp | 256 +++++++++--------- .../Descriptors/SHVkDescriptorSetLayout.h | 194 +++++++------ .../Graphics/Devices/SHVkLogicalDevice.cpp | 4 +- .../src/Graphics/Devices/SHVkLogicalDevice.h | 2 +- .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 4 +- ...icsGlobalData.cpp => SHPredefinedData.cpp} | 77 ++++-- ...raphicsGlobalData.h => SHPredefinedData.h} | 14 +- .../MiddleEnd/Interface/SHGraphicsConstants.h | 133 ++++----- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 33 ++- .../MiddleEnd/Interface/SHRenderer.cpp | 7 +- .../Graphics/MiddleEnd/Interface/SHRenderer.h | 2 +- .../MiddleEnd/Lights/SHLightingSubSystem.cpp | 4 +- .../MiddleEnd/Pipeline/SHPipelineLibrary.cpp | 6 +- .../MiddleEnd/Pipeline/SHPipelineLibrary.h | 2 +- .../MiddleEnd/TextRendering/SHFont.cpp | 2 +- .../SHTextRenderingSubSystem.cpp | 31 +-- .../TextRendering/SHTextRenderingSubSystem.h | 4 +- .../MiddleEnd/Textures/SHTextureLibrary.cpp | 4 +- .../Graphics/RenderGraph/SHRenderGraph.cpp | 2 +- .../src/Graphics/RenderGraph/SHRenderGraph.h | 2 +- .../Graphics/RenderGraph/SHRenderGraphNode.h | 2 +- .../RenderGraph/SHRenderGraphNodeCompute.cpp | 4 +- .../RenderGraph/SHRenderGraphStorage.h | 2 +- .../SHRenderToSwapchainImageSystem.cpp | 4 +- .../src/Tools/Utilities/SHUtilities.h | 67 +++++ 27 files changed, 483 insertions(+), 405 deletions(-) rename SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/{SHGraphicsGlobalData.cpp => SHPredefinedData.cpp} (63%) rename SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/{SHGraphicsGlobalData.h => SHPredefinedData.h} (76%) diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp index adb51586..e77234ca 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp @@ -53,7 +53,6 @@ namespace SHADE for (uint32_t i = 0; i < layouts.size(); ++i) { vkLayouts[i] = layouts[i]->GetVkHandle(); - setIndexing.emplace(layouts[i]->GetSetIndex(), i); } // Check for variable descriptor count @@ -87,7 +86,7 @@ namespace SHADE for (auto& binding : bindings) { BindingAndSetHash writeHash = binding.BindPoint; - writeHash |= static_cast(layouts[i]->GetSetIndex()) << 32; + writeHash |= static_cast(i) << 32; // new write for the binding updater.writeInfos.emplace_back(); @@ -208,16 +207,13 @@ namespace SHADE // Get binding + set hash BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding); - // to index a set - uint32_t setIndex = setIndexing[set]; - // to index a write for a binding uint32_t writeInfoIndex = updater.writeHashMap[bsHash]; // Initialize info for write - writeDescSet.descriptorType = layoutsUsed[setIndex]->GetBindings()[binding].Type; + writeDescSet.descriptorType = layoutsUsed[set]->GetBindings()[binding].Type; writeDescSet.dstArrayElement = 0; - writeDescSet.dstSet = descSets[setIndex]; + writeDescSet.dstSet = descSets[set]; writeDescSet.dstBinding = binding; writeDescSet.pImageInfo = updater.writeInfos[writeInfoIndex].descImageInfos.data(); @@ -233,16 +229,13 @@ namespace SHADE // Get binding + set hash BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding); - // to index a set - uint32_t setIndex = setIndexing[set]; - // to index a write for a binding uint32_t writeInfoIndex = updater.writeHashMap[bsHash]; // Initialize info for write - writeDescSet.descriptorType = layoutsUsed[setIndex]->GetBindings()[binding].Type; + writeDescSet.descriptorType = layoutsUsed[set]->GetBindings()[binding].Type; writeDescSet.dstArrayElement = 0; - writeDescSet.dstSet = descSets[setIndex]; + writeDescSet.dstSet = descSets[set]; writeDescSet.dstBinding = binding; writeDescSet.pBufferInfo = updater.writeInfos[writeInfoIndex].descBufferInfos.data(); diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h index 3f42afcc..a228bc66 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h @@ -21,7 +21,6 @@ namespace SHADE class SHVkImageView; class SHVkBuffer; - /*---------------------------------------------------------------------------------*/ /* Type Definitions */ /*---------------------------------------------------------------------------------*/ @@ -91,10 +90,10 @@ namespace SHADE //! Descriptor pool to allocate descriptor sets Handle descPool; - //! Sometimes when we pass in a layout, the set of the layout used in the - //! shader cannot be used to index into descSets. This is to mitigate that issue - //! when we update descriptor sets. - std::unordered_map setIndexing; + ////! Sometimes when we pass in a layout, the set of the layout used in the + ////! shader cannot be used to index into descSets. This is to mitigate that issue + ////! when we update descriptor sets. + //std::unordered_map setIndexing; //! Descriptor sets std::vector descSets; diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp index 4be8cc9e..9b921411 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp @@ -5,146 +5,138 @@ namespace SHADE { - /*---------------------------------------------------------------------------------*/ - /* Constructor/Destructor */ - /*---------------------------------------------------------------------------------*/ - SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle device, SetIndex set, const std::vector& bindings, bool genImmutableSamplers/* = false*/) - : device { device } - , layoutDesc { bindings } - , setIndex {set} + /*---------------------------------------------------------------------------------*/ + /* Constructor/Destructor */ + /*---------------------------------------------------------------------------------*/ + SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle device, const std::vector& bindings, bool genImmutableSamplers/* = false*/) + : device{ device } + , layoutDesc{ bindings } , immutableSampler{} + { + // Check if auto-binding point calculation configuration is valid + bool autoCalc = false; + for (const auto& binding : bindings) { - // Check if auto-binding point calculation configuration is valid - bool autoCalc = false; - for (const auto& binding : bindings) - { - if (binding.BindPoint == Binding::AUTO_CALC_BINDING) - { - autoCalc = true; - } - else if (autoCalc) - { - throw std::invalid_argument("For auto calculation of bindings, all bindings must be set to AUTO_CALC_BINDING!"); - } - } - - vk::Sampler tempVkSampler = nullptr; - if (genImmutableSamplers) - { - // Create sampler - immutableSampler = device->CreateSampler( - { - .minFilter = vk::Filter::eLinear, - .magFilter = vk::Filter::eLinear, - .addressMode = vk::SamplerAddressMode::eRepeat, - .mipmapMode = vk::SamplerMipmapMode::eLinear, - .minLod = -1000, - .maxLod = 1000 - } - ); - - tempVkSampler = immutableSampler->GetVkSampler(); - } - - - // Fill up VK bindings with auto calculated bind points if needed - std::vector layoutBindings; - layoutBindings.reserve(bindings.size()); - int bindCount = 0; - for (const auto& binding : bindings) - { - const uint32_t CURR_BIND_POINT = autoCalc ? bindCount : binding.BindPoint; - const vk::DescriptorSetLayoutBinding VK_BINDING = - { - .binding = CURR_BIND_POINT, - .descriptorType = binding.Type, - .descriptorCount = binding.DescriptorCount, - .stageFlags = binding.Stage, - .pImmutableSamplers = genImmutableSamplers ? &tempVkSampler : nullptr, - }; - layoutBindings.emplace_back(VK_BINDING); - - // Save for future reference - layoutDesc[bindCount++].BindPoint = CURR_BIND_POINT; - } - - // TODO: Check layout support with physical device - - // Prepare binding flags - std::vector combinedBindings(bindings.size()); - for (uint32_t i = 0; i < bindings.size(); ++i) - combinedBindings[i] = bindings[i].flags; - - const vk::DescriptorSetLayoutBindingFlagsCreateInfo BINDING_FLAGS_CREATE_INFO - { - .bindingCount = static_cast(bindings.size()), // Number of flags = number of bindings - .pBindingFlags = combinedBindings.data(), // address to flags - }; - - // Create the layout - const vk::DescriptorSetLayoutCreateInfo DESC_SET_LAYOUT_CREATE_INFO - { - .pNext = &BINDING_FLAGS_CREATE_INFO, - .flags = {}, - .bindingCount = static_cast(layoutBindings.size()), - .pBindings = layoutBindings.data(), - }; - setLayout = device->GetVkLogicalDevice().createDescriptorSetLayout(DESC_SET_LAYOUT_CREATE_INFO); - } - - SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept - : device {rhs.device} - , setLayout {rhs.setLayout} - , layoutDesc{std::move (rhs.layoutDesc)} - , setIndex{ rhs.setIndex } - , immutableSampler{ rhs.immutableSampler } - { - rhs.setLayout = VK_NULL_HANDLE; - } - - SHVkDescriptorSetLayout::~SHVkDescriptorSetLayout() noexcept - { - // Destroy layout - if (setLayout) - device->GetVkLogicalDevice().destroyDescriptorSetLayout(setLayout); - } - - std::vector const& SHVkDescriptorSetLayout::GetBindings(void) const noexcept - { - return layoutDesc; - } - - SetIndex SHVkDescriptorSetLayout::GetSetIndex(void) const noexcept - { - return setIndex; - } - - uint32_t SHVkDescriptorSetLayout::GetNumDynamicOffsetsRequired(void) const noexcept - { - uint32_t numDynamicBindings = 0; - for (auto& binding : layoutDesc) + if (binding.BindPoint == Binding::AUTO_CALC_BINDING) { - if (binding.Type == vk::DescriptorType::eUniformBufferDynamic || binding.Type == vk::DescriptorType::eStorageBufferDynamic) - ++numDynamicBindings; + autoCalc = true; + } + else if (autoCalc) + { + throw std::invalid_argument("For auto calculation of bindings, all bindings must be set to AUTO_CALC_BINDING!"); } - - return numDynamicBindings; } - SHVkDescriptorSetLayout& SHVkDescriptorSetLayout::operator=(SHVkDescriptorSetLayout&& rhs) noexcept + vk::Sampler tempVkSampler = nullptr; + if (genImmutableSamplers) { - if (&rhs == this) - return *this; + // Create sampler + immutableSampler = device->CreateSampler( + { + .minFilter = vk::Filter::eLinear, + .magFilter = vk::Filter::eLinear, + .addressMode = vk::SamplerAddressMode::eRepeat, + .mipmapMode = vk::SamplerMipmapMode::eLinear, + .minLod = -1000, + .maxLod = 1000 + } + ); - device = rhs.device; - setLayout = rhs.setLayout; - layoutDesc = std::move(rhs.layoutDesc); - setIndex = rhs.setIndex; - immutableSampler = rhs.immutableSampler; - - rhs.setLayout = VK_NULL_HANDLE; - - return *this; + tempVkSampler = immutableSampler->GetVkSampler(); } + + // Fill up VK bindings with auto calculated bind points if needed + std::vector layoutBindings; + layoutBindings.reserve(bindings.size()); + int bindCount = 0; + for (const auto& binding : bindings) + { + const uint32_t CURR_BIND_POINT = autoCalc ? bindCount : binding.BindPoint; + const vk::DescriptorSetLayoutBinding VK_BINDING = + { + .binding = CURR_BIND_POINT, + .descriptorType = binding.Type, + .descriptorCount = binding.DescriptorCount, + .stageFlags = binding.Stage, + .pImmutableSamplers = genImmutableSamplers ? &tempVkSampler : nullptr, + }; + layoutBindings.emplace_back(VK_BINDING); + + // Save for future reference + layoutDesc[bindCount++].BindPoint = CURR_BIND_POINT; + } + + // TODO: Check layout support with physical device + + // Prepare binding flags + std::vector combinedBindings(bindings.size()); + for (uint32_t i = 0; i < bindings.size(); ++i) + combinedBindings[i] = bindings[i].flags; + + const vk::DescriptorSetLayoutBindingFlagsCreateInfo BINDING_FLAGS_CREATE_INFO + { + .bindingCount = static_cast(bindings.size()), // Number of flags = number of bindings + .pBindingFlags = combinedBindings.data(), // address to flags + }; + + // Create the layout + const vk::DescriptorSetLayoutCreateInfo DESC_SET_LAYOUT_CREATE_INFO + { + .pNext = &BINDING_FLAGS_CREATE_INFO, + .flags = {}, + .bindingCount = static_cast(layoutBindings.size()), + .pBindings = layoutBindings.data(), + }; + setLayout = device->GetVkLogicalDevice().createDescriptorSetLayout(DESC_SET_LAYOUT_CREATE_INFO); + } + + SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept + : device{ rhs.device } + , setLayout{ rhs.setLayout } + , layoutDesc{ std::move(rhs.layoutDesc) } + , immutableSampler{ rhs.immutableSampler } + { + rhs.setLayout = VK_NULL_HANDLE; + } + + SHVkDescriptorSetLayout::~SHVkDescriptorSetLayout() noexcept + { + // Destroy layout + if (setLayout) + device->GetVkLogicalDevice().destroyDescriptorSetLayout(setLayout); + } + + std::vector const& SHVkDescriptorSetLayout::GetBindings(void) const noexcept + { + return layoutDesc; + } + + uint32_t SHVkDescriptorSetLayout::GetNumDynamicOffsetsRequired(void) const noexcept + { + uint32_t numDynamicBindings = 0; + for (auto& binding : layoutDesc) + { + if (binding.Type == vk::DescriptorType::eUniformBufferDynamic || binding.Type == vk::DescriptorType::eStorageBufferDynamic) + ++numDynamicBindings; + } + + return numDynamicBindings; + } + + SHVkDescriptorSetLayout& SHVkDescriptorSetLayout::operator=(SHVkDescriptorSetLayout&& rhs) noexcept + { + if (&rhs == this) + return *this; + + device = rhs.device; + setLayout = rhs.setLayout; + layoutDesc = std::move(rhs.layoutDesc); + immutableSampler = rhs.immutableSampler; + + rhs.setLayout = VK_NULL_HANDLE; + + return *this; + } + } diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h index caa3c057..f0e1fe4e 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h @@ -6,109 +6,107 @@ namespace SHADE { - /*---------------------------------------------------------------------------------*/ - /* Forward Declarations */ - /*---------------------------------------------------------------------------------*/ - class SHVkLogicalDevice; - class SHVkSampler; + /*---------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*---------------------------------------------------------------------------------*/ + class SHVkLogicalDevice; + class SHVkSampler; - /*---------------------------------------------------------------------------------*/ - /* Type Definitions */ - /*---------------------------------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + /// + /// RAII wrapper object for a Vulkan Descriptor Set Layout object. + /// + class SHVkDescriptorSetLayout + { + public: + /*-----------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------*/ /// - /// RAII wrapper object for a Vulkan Descriptor Set Layout object. + /// Object that describes how a descriptor binding in a DescriptorSetLayout is + /// structured. /// - class SHVkDescriptorSetLayout + struct Binding { - public: - /*-----------------------------------------------------------------------------*/ - /* Type Definitions */ - /*-----------------------------------------------------------------------------*/ - /// - /// Object that describes how a descriptor binding in a DescriptorSetLayout is - /// structured. - /// - struct Binding - { - /*-------------------------------------------------------------------------*/ - /* Constants */ - /*-------------------------------------------------------------------------*/ - /// - /// If set for the "BindPoint", binding points are automatically calculated. - /// - static constexpr uint32_t AUTO_CALC_BINDING = std::numeric_limits::max(); + /*-------------------------------------------------------------------------*/ + /* Constants */ + /*-------------------------------------------------------------------------*/ + /// + /// If set for the "BindPoint", binding points are automatically calculated. + /// + static constexpr uint32_t AUTO_CALC_BINDING = std::numeric_limits::max(); - /// - /// For use in Binding DescriptorCount. - /// - static constexpr uint32_t VARIABLE_DESCRIPTOR_UPPER_BOUND = 2000; - /*-------------------------------------------------------------------------*/ - /* Data Members */ - /*-------------------------------------------------------------------------*/ - /// - /// Type of element for the descriptor. - /// - vk::DescriptorType Type = {}; - /// - /// Shader stage that this binding is for. - /// - vk::ShaderStageFlags Stage = {}; - /// - /// Binding point for the Descriptor within the Descriptor Set. - /// - uint32_t BindPoint = AUTO_CALC_BINDING; - /// - /// Number of elements in the binding. When VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT - /// is used in VkDescriptorBindingFlagBits, this value represents the upper bound. - /// - uint32_t DescriptorCount = 1; + /// + /// For use in Binding DescriptorCount. + /// + static constexpr uint32_t VARIABLE_DESCRIPTOR_UPPER_BOUND = 2000; + /*-------------------------------------------------------------------------*/ + /* Data Members */ + /*-------------------------------------------------------------------------*/ + /// + /// Type of element for the descriptor. + /// + vk::DescriptorType Type = {}; + /// + /// Shader stage that this binding is for. + /// + vk::ShaderStageFlags Stage = {}; + /// + /// Binding point for the Descriptor within the Descriptor Set. + /// + uint32_t BindPoint = AUTO_CALC_BINDING; + /// + /// Number of elements in the binding. When VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT + /// is used in VkDescriptorBindingFlagBits, this value represents the upper bound. + /// + uint32_t DescriptorCount = 1; - vk::DescriptorBindingFlags flags = {}; - }; - - /*-----------------------------------------------------------------------------*/ - /* Constructor/Destructors */ - /*-----------------------------------------------------------------------------*/ - SHVkDescriptorSetLayout() = delete; - /// - /// Constructs a DescriptorSetLayout with the specified properties and device. - /// - /// - /// - SHVkDescriptorSetLayout(Handle device, SetIndex setIndex, const std::vector& bindings, bool genImmutableSamplers = false); - SHVkDescriptorSetLayout(const SHVkDescriptorSetLayout&) = delete; - SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept; - /// - /// Destructor which will unload and deallocate all resources for this Set. - /// - ~SHVkDescriptorSetLayout() noexcept; - - /*-----------------------------------------------------------------------------*/ - /* Overloaded Operators */ - /*-----------------------------------------------------------------------------*/ - SHVkDescriptorSetLayout& operator=(const SHVkDescriptorSetLayout&) = delete; - SHVkDescriptorSetLayout& operator=(SHVkDescriptorSetLayout&& rhs) noexcept; - - /*-----------------------------------------------------------------------------*/ - /* Getter Functions */ - /*-----------------------------------------------------------------------------*/ - /// - /// Retrieves the handle to the Vulkan Descriptor Set Layout handle. - /// - /// Handle to the Vulkan Descriptor Set Layout handle. - inline const vk::DescriptorSetLayout& GetVkHandle() const { return setLayout; } - std::vector const& GetBindings (void) const noexcept; - SetIndex GetSetIndex (void) const noexcept; - uint32_t GetNumDynamicOffsetsRequired (void) const noexcept; - - private: - /*-----------------------------------------------------------------------------*/ - /* Data Members */ - /*-----------------------------------------------------------------------------*/ - Handle device; - vk::DescriptorSetLayout setLayout; - std::vector layoutDesc; // Stores description of the layout - SetIndex setIndex; // Index of the set - Handle immutableSampler; + vk::DescriptorBindingFlags flags = {}; }; + + /*-----------------------------------------------------------------------------*/ + /* Constructor/Destructors */ + /*-----------------------------------------------------------------------------*/ + SHVkDescriptorSetLayout() = delete; + /// + /// Constructs a DescriptorSetLayout with the specified properties and device. + /// + /// + /// + SHVkDescriptorSetLayout(Handle device, const std::vector& bindings, bool genImmutableSamplers = false); + SHVkDescriptorSetLayout(const SHVkDescriptorSetLayout&) = delete; + SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept; + /// + /// Destructor which will unload and deallocate all resources for this Set. + /// + ~SHVkDescriptorSetLayout() noexcept; + + /*-----------------------------------------------------------------------------*/ + /* Overloaded Operators */ + /*-----------------------------------------------------------------------------*/ + SHVkDescriptorSetLayout& operator=(const SHVkDescriptorSetLayout&) = delete; + SHVkDescriptorSetLayout& operator=(SHVkDescriptorSetLayout&& rhs) noexcept; + + /*-----------------------------------------------------------------------------*/ + /* Getter Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Retrieves the handle to the Vulkan Descriptor Set Layout handle. + /// + /// Handle to the Vulkan Descriptor Set Layout handle. + inline const vk::DescriptorSetLayout& GetVkHandle() const { return setLayout; } + std::vector const& GetBindings(void) const noexcept; + uint32_t GetNumDynamicOffsetsRequired(void) const noexcept; + + private: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + Handle device; + vk::DescriptorSetLayout setLayout; + std::vector layoutDesc; // Stores description of the layout + Handle immutableSampler; + }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp index 95cf2e91..6a6e385f 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp @@ -561,9 +561,9 @@ namespace SHADE } - Handle SHVkLogicalDevice::CreateDescriptorSetLayout(SetIndex setIndex, std::vector const& bindings, bool genImmutableSamplers/* = false*/) noexcept + Handle SHVkLogicalDevice::CreateDescriptorSetLayout(std::vector const& bindings, bool genImmutableSamplers/* = false*/) noexcept { - return SHVkInstance::GetResourceManager().Create (GetHandle(), setIndex, bindings, genImmutableSamplers); + return SHVkInstance::GetResourceManager().Create (GetHandle(), bindings, genImmutableSamplers); } Handle SHVkLogicalDevice::CreateDescriptorPools(const SHVkDescriptorPool::Config& config /*= {}*/) noexcept diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h index ed09b482..6e3bb0ce 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h @@ -190,7 +190,7 @@ namespace SHADE Handle CreateRenderpass (std::span const vkDescriptions, std::vector const& subpasses) noexcept; Handle CreateRenderpass (std::span const vkDescriptions, std::span const spDescs, std::span const spDeps) noexcept; Handle CreateFramebuffer (Handle const& renderpassHdl, std::vector> const& attachments, uint32_t inWidth, uint32_t inHeight) noexcept; - Handle CreateDescriptorSetLayout (SetIndex setIndex, std::vector const& bindings, bool genImmutableSamplers = false) noexcept; + Handle CreateDescriptorSetLayout (std::vector const& bindings, bool genImmutableSamplers = false) noexcept; Handle CreateDescriptorPools (const SHVkDescriptorPool::Config& config = {}) noexcept; Handle CreateDescriptorSetGroup(Handle pool, std::vector> const& layouts, diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 211c50b7..cb2806aa 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -25,7 +25,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "ECS_Base/Managers/SHComponentManager.h" #include "Math/Transform/SHTransformComponent.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/MiddleEnd/GlobalData/SHPredefinedData.h" #include "Graphics/Descriptors/SHVkDescriptorPool.h" #include "Scene/SHSceneManager.h" #include "UI/SHUIComponent.h" @@ -607,7 +607,7 @@ namespace SHADE { matPropsDescSet[frameIndex] = descPool->Allocate ( - { SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE] }, + { SHPredefinedData::GetPredefinedDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE] }, { 0 } ); #ifdef _DEBUG diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHPredefinedData.cpp similarity index 63% rename from SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp rename to SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHPredefinedData.cpp index 87234a6b..d93e073b 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHPredefinedData.cpp @@ -1,30 +1,24 @@ #include "SHpch.h" -#include "SHGraphicsGlobalData.h" +#include "SHPredefinedData.h" #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Pipeline/SHPipelineState.h" #include "Graphics/Pipeline/SHVkPipelineLayout.h" #include "Graphics/Descriptors/SHVkDescriptorSetLayout.h" #include "Graphics/MiddleEnd/Lights/SHLightData.h" -#include "Tools/Utilities/SHUtilities.h" namespace SHADE { /*-----------------------------------------------------------------------------------*/ /* Static Definitions */ /*-----------------------------------------------------------------------------------*/ - std::vector> SHGraphicsGlobalData::globalDescSetLayouts; - SHVertexInputState SHGraphicsGlobalData::defaultVertexInputState; - Handle SHGraphicsGlobalData::dummyPipelineLayout; - - void SHGraphicsGlobalData::InitHighFrequencyGlobalData(void) noexcept - { - - } + std::vector> SHPredefinedData::predefinedLayouts; + SHVertexInputState SHPredefinedData::defaultVertexInputState; + Handle SHPredefinedData::dummyPipelineLayout; /*-----------------------------------------------------------------------------------*/ /* Function Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHGraphicsGlobalData::InitDescSetLayouts(Handle logicalDevice) noexcept + void SHPredefinedData::InitDescSetLayouts(Handle logicalDevice) noexcept { SHVkDescriptorSetLayout::Binding genericDataBinding { @@ -44,7 +38,7 @@ namespace SHADE }; // For global data (generic data and textures) - Handle staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS, { genericDataBinding, texturesBinding }); + Handle staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout({ genericDataBinding, texturesBinding }); SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, staticGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] Static Globals"); @@ -72,8 +66,8 @@ namespace SHADE } // For Dynamic global data (lights) - Handle dynamicGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, lightBindings); - SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, dynamicGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] Dynamic Globals"); + Handle lightDataDescSetLayout = logicalDevice->CreateDescriptorSetLayout(lightBindings); + SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, lightDataDescSetLayout->GetVkHandle(), "[Descriptor Set Layout] Dynamic Globals"); // For High frequency global data (camera) SHVkDescriptorSetLayout::Binding cameraDataBinding @@ -83,7 +77,7 @@ namespace SHADE .BindPoint = SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA, .DescriptorCount = 1, }; - Handle cameraDataGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, { cameraDataBinding }); + Handle cameraDataGlobalLayout = logicalDevice->CreateDescriptorSetLayout({ cameraDataBinding }); SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, cameraDataGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] High Frequency Globals"); // For per instance data (transforms, materials, etc.) @@ -94,21 +88,41 @@ namespace SHADE .BindPoint = SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, .DescriptorCount = 1, }; - Handle materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, { materialDataBinding }); + Handle materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout({ materialDataBinding }); SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, materialDataPerInstanceLayout->GetVkHandle(), "[Descriptor Set Layout] Material Globals"); + // font bitmap data (texture) + SHVkDescriptorSetLayout::Binding fontBitmapBinding + { + .Type = vk::DescriptorType::eCombinedImageSampler, + .Stage = vk::ShaderStageFlagBits::eFragment, + .BindPoint = SHGraphicsConstants::DescriptorSetBindings::FONT_BITMAP_DATA, + .DescriptorCount = 1, + }; + + // font data in the form of matrices + SHVkDescriptorSetLayout::Binding fontMatrixBinding + { + .Type = vk::DescriptorType::eStorageBuffer, + .Stage = vk::ShaderStageFlagBits::eVertex, + .BindPoint = SHGraphicsConstants::DescriptorSetBindings::FONT_MATRIX_DATA, + .DescriptorCount = 1, + }; + + Handle fontDataDescSetLayout = logicalDevice->CreateDescriptorSetLayout({ fontBitmapBinding, fontMatrixBinding }); + SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, fontDataDescSetLayout->GetVkHandle(), "[Descriptor Set Layout] Font Data"); - globalDescSetLayouts.push_back(staticGlobalLayout); - globalDescSetLayouts.push_back(dynamicGlobalLayout); - globalDescSetLayouts.push_back(cameraDataGlobalLayout); - globalDescSetLayouts.push_back(materialDataPerInstanceLayout); + predefinedLayouts.push_back(staticGlobalLayout); + predefinedLayouts.push_back(lightDataDescSetLayout); + predefinedLayouts.push_back(cameraDataGlobalLayout); + predefinedLayouts.push_back(materialDataPerInstanceLayout); + predefinedLayouts.push_back(fontDataDescSetLayout); - - dummyPipelineLayout = logicalDevice->CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy{globalDescSetLayouts}); + dummyPipelineLayout = logicalDevice->CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy{predefinedLayouts}); } - void SHGraphicsGlobalData::InitDefaultVertexInputState(void) noexcept + void SHPredefinedData::InitDefaultVertexInputState(void) noexcept { defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // positions at binding 0 defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_2D) }); // UVs at binding 1 @@ -118,24 +132,31 @@ namespace SHADE defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::UINT32_2D) }); // Instanced integer data at index 8 } - void SHGraphicsGlobalData::Init(Handle logicalDevice) noexcept + void SHPredefinedData::Init(Handle logicalDevice) noexcept { InitDescSetLayouts(logicalDevice); InitDefaultVertexInputState(); } - std::vector> const& SHGraphicsGlobalData::GetDescSetLayouts(void) noexcept + std::vector> SHPredefinedData::GetPredefinedDescSetLayouts(SHEnumWrapper types) noexcept { - return globalDescSetLayouts; + std::vector> layoutsFound; + for (uint8_t i = 0; i < SHGraphicsConstants::numPredefinedDescSetLayoutTypes; ++i) + { + if (types & (static_cast(1) << i)) + layoutsFound.push_back(predefinedLayouts[i]); + } + + return layoutsFound; } - SHVertexInputState const& SHGraphicsGlobalData::GetDefaultViState(void) noexcept + SHVertexInputState const& SHPredefinedData::GetDefaultViState(void) noexcept { return defaultVertexInputState; } - Handle SHGraphicsGlobalData::GetDummyPipelineLayout(void) noexcept + Handle SHPredefinedData::GetDummyPipelineLayout(void) noexcept { return dummyPipelineLayout; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHPredefinedData.h similarity index 76% rename from SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h rename to SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHPredefinedData.h index 439acba5..5f13a100 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHPredefinedData.h @@ -3,6 +3,7 @@ #include "SH_API.h" #include "Graphics/Pipeline/SHPipelineState.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" +#include "Tools/Utilities/SHUtilities.h" namespace SHADE { @@ -11,11 +12,11 @@ namespace SHADE class SHVkDescriptorSetGroup; class SHVkPipelineLayout; - class SH_API SHGraphicsGlobalData + class SH_API SHPredefinedData { private: //! Global descriptor set layouts. Used to allocate descriptor sets - static std::vector> globalDescSetLayouts; + static std::vector> predefinedLayouts; //! Default vertex input state (used by everything). static SHVertexInputState defaultVertexInputState; @@ -24,7 +25,6 @@ namespace SHADE //! we create a dummy pipeline layout to use it for binding. static Handle dummyPipelineLayout; - static void InitHighFrequencyGlobalData (void) noexcept; static void InitDescSetLayouts (Handle logicalDevice) noexcept; static void InitDefaultVertexInputState (void) noexcept; @@ -32,7 +32,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* Constructors */ /*-----------------------------------------------------------------------*/ - SHGraphicsGlobalData() = delete; + SHPredefinedData() = delete; /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ @@ -42,8 +42,8 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ /*-----------------------------------------------------------------------*/ - static std::vector> const& GetDescSetLayouts (void) noexcept; - static SHVertexInputState const& GetDefaultViState (void) noexcept; - static Handle GetDummyPipelineLayout (void) noexcept; + static std::vector> GetPredefinedDescSetLayouts (SHEnumWrapper types) noexcept; + static SHVertexInputState const& GetDefaultViState (void) noexcept; + static Handle GetDummyPipelineLayout (void) noexcept; }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h index e6051841..e0b76555 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h @@ -25,74 +25,85 @@ namespace SHADE struct SHGraphicsConstants { public: + static constexpr uint8_t numPredefinedDescSetLayoutTypes = 64; + + enum class SHPredefinedDescSetLayoutTypes : uint64_t + { + STATIC_DATA = 0x01, + LIGHTS = 0x02, + CAMERA = 0x04, + MATERIALS = 0x08, + FONT = 0x10, + }; + struct RenderGraphIndices { static constexpr uint32_t WORLD = 0; static constexpr uint32_t EDITOR = 0; }; - struct DescriptorSetIndex - { - /***************************************************************************/ - /*! - \brief - DescriptorSet Index for static global values like generic data, and - texture samplers - */ - /***************************************************************************/ - static constexpr uint32_t STATIC_GLOBALS = 0; - /***************************************************************************/ - /*! - \brief - DescriptorSet Index for dynamic global values like lights. - */ - /***************************************************************************/ - static constexpr uint32_t DYNAMIC_GLOBALS = 1; - /***************************************************************************/ - /*! - \brief - DescriptorSet Index for high frequency changing global values like - camera matrices. - */ - /***************************************************************************/ - static constexpr uint32_t HIGH_FREQUENCY_GLOBALS = 2; - /***************************************************************************/ - /*! - \brief - DescriptorSet Index for per-instance/material changing values. - */ - /***************************************************************************/ - static constexpr uint32_t PER_INSTANCE = 3; - /***************************************************************************/ - /*! - \brief - DescriptorSet Index for render graph resources. Unlike the sets from - 1 to 3 and 6, this set index does not have hard coded bindings and is - NOT part of the layouts included in the global data. - */ - /***************************************************************************/ - static constexpr uint32_t RENDERGRAPH_RESOURCE = 4; - /***************************************************************************/ - /*! - \brief - DescriptorSet Index for render graph node compute resources. For data - that we wish to pass to compute shaders in the render graph, this is - the set to use. Unlike the sets from 1 to 3 and 6, this set index does not have - hard coded bindings and is NOT part of the layouts included in the global - data. - */ - /***************************************************************************/ - static constexpr uint32_t RENDERGRAPH_NODE_COMPUTE_RESOURCE = 5; + //struct DescriptorSetIndex + //{ + // /***************************************************************************/ + // /*! + // \brief + // DescriptorSet Index for static global values like generic data, and + // texture samplers + // */ + // /***************************************************************************/ + // static constexpr uint32_t STATIC_GLOBALS = 0; + // /***************************************************************************/ + // /*! + // \brief + // DescriptorSet Index for dynamic global values like lights. + // */ + // /***************************************************************************/ + // static constexpr uint32_t DYNAMIC_GLOBALS = 1; + // /***************************************************************************/ + // /*! + // \brief + // DescriptorSet Index for high frequency changing global values like + // camera matrices. + // */ + // /***************************************************************************/ + // static constexpr uint32_t HIGH_FREQUENCY_GLOBALS = 2; + // /***************************************************************************/ + // /*! + // \brief + // DescriptorSet Index for per-instance/material changing values. + // */ + // /***************************************************************************/ + // static constexpr uint32_t PER_INSTANCE = 3; + // /***************************************************************************/ + // /*! + // \brief + // DescriptorSet Index for render graph resources. Unlike the sets from + // 1 to 3 and 6, this set index does not have hard coded bindings and is + // NOT part of the layouts included in the global data. + // */ + // /***************************************************************************/ + // static constexpr uint32_t RENDERGRAPH_RESOURCE = 4; + // /***************************************************************************/ + // /*! + // \brief + // DescriptorSet Index for render graph node compute resources. For data + // that we wish to pass to compute shaders in the render graph, this is + // the set to use. Unlike the sets from 1 to 3 and 6, this set index does not have + // hard coded bindings and is NOT part of the layouts included in the global + // data. + // */ + // /***************************************************************************/ + // static constexpr uint32_t RENDERGRAPH_NODE_COMPUTE_RESOURCE = 5; - /***************************************************************************/ - /*! - \brief - To store font data. - - */ - /***************************************************************************/ - static constexpr uint32_t FONT_DATA = 4; - }; + // /***************************************************************************/ + // /*! + // \brief + // To store font data. + // + // */ + // /***************************************************************************/ + // static constexpr uint32_t FONT_DATA = 4; + //}; struct DescriptorSetBindings { diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 9a599a07..c9e7f2d2 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -31,7 +31,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Graphics/MiddleEnd/Batching/SHSuperBatch.h" #include "SHGraphicsConstants.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/MiddleEnd/GlobalData/SHPredefinedData.h" #include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/Images/SHVkSampler.h" #include "Assets/Asset Types/SHTextureAsset.h" @@ -124,6 +124,9 @@ namespace SHADE SHFreetypeInstance::Init(); + SHAssetManager::CompileAsset("../../Assets/Shaders/DebugDraw_VS.glsl", false); + SHAssetManager::CompileAsset("../../Assets/Shaders/DebugDraw_FS.glsl", false); + // Load Built In Shaders static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet(VS_DEFAULT); static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet(FS_DEFAULT); @@ -318,12 +321,12 @@ namespace SHADE /* BIND RENDER GRAPH TO RENDERER */ /*-----------------------------------------------------------------------*/ // Add world renderer to default viewport - worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); + worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHPredefinedData::GetPredefinedDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); worldRenderer->SetCamera(worldCamera); worldRenderer->SetCameraDirector(worldCameraDirector); // Add screen renderer to default viewport - screenRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], screenRenderGraph); + screenRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHPredefinedData::GetPredefinedDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], screenRenderGraph); screenRenderer->SetCamera(screenCamera); screenRenderer->SetCameraDirector(worldCameraDirector); @@ -356,7 +359,7 @@ namespace SHADE void SHGraphicsSystem::InitMiddleEnd(void) noexcept { - SHGraphicsGlobalData::Init(device); + SHPredefinedData::Init(device); InitSceneRenderGraph(); @@ -454,7 +457,7 @@ namespace SHADE editorRenderGraph->Generate(); // Add world renderer to default viewport - editorRenderer = editorViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], editorRenderGraph); + editorRenderer = editorViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHPredefinedData::GetPredefinedDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], editorRenderGraph); editorRenderer->SetCamera(worldCamera); } #endif @@ -567,8 +570,8 @@ namespace SHADE currentCmdBuffer->SetViewportScissor (static_cast(w), static_cast(h), w, h); // Force set the pipeline layout - currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout(), SH_PIPELINE_TYPE::GRAPHICS); - currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout(), SH_PIPELINE_TYPE::COMPUTE); + currentCmdBuffer->ForceSetPipelineLayout(SHPredefinedData::GetDummyPipelineLayout(), SH_PIPELINE_TYPE::GRAPHICS); + currentCmdBuffer->ForceSetPipelineLayout(SHPredefinedData::GetDummyPipelineLayout(), SH_PIPELINE_TYPE::COMPUTE); // Bind all the buffers required for meshes for (auto& [buffer, bindingPoint] : MESH_DATA) @@ -900,7 +903,7 @@ namespace SHADE void SHGraphicsSystem::BuildFonts(void) noexcept { - fontLibrary.BuildFonts(device, graphicsQueue, graphicsCmdPool, descPool, textRenderingSubSystem->GetFontDataDescSetLayout(), resourceManager); + fontLibrary.BuildFonts(device, graphicsQueue, graphicsCmdPool, descPool, SHPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsConstants::SHPredefinedDescSetLayoutTypes::FONT)[0], resourceManager); } #pragma endregion ADD_REMOVE @@ -1044,6 +1047,10 @@ namespace SHADE graphSemaphores[0].Free(); graphSemaphores[1].Free(); + for (auto& semaHandle : graphSemaphores) + semaHandle = device->CreateSemaphore(); + + auto windowDims = window->GetWindowSize(); // Resize the swapchain @@ -1054,6 +1061,12 @@ namespace SHADE worldRenderGraph->HandleResize(resizeWidth, resizeHeight); #ifdef SHEDITOR + + // NOTE: These 2 lines are actually not necessary because the editor viewport is not even used for + // setting dynamic viewport or scissor state. ImGUI takes care of that for us. + //editorViewport->SetWidth(windowDims.first); + //editorViewport->SetHeight(windowDims.second); + editorRenderGraph->HandleResize(windowDims.first, windowDims.second); #endif @@ -1076,8 +1089,6 @@ namespace SHADE #endif - for (auto& semaHandle : graphSemaphores) - semaHandle = device->CreateSemaphore(); } void SHGraphicsSystem::AwaitGraphicsExecution() @@ -1126,7 +1137,7 @@ namespace SHADE device, SHPipelineLayoutParams { .shaderModules = { (instanced ? debugMeshVertShader : debugVertShader) , debugFragShader }, - .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts() + .globalDescSetLayouts = SHPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsConstants::SHPredefinedDescSetLayoutTypes::CAMERA) } ); auto pipeline = resourceManager.Create(device, pipelineLayout, nullptr, renderPass, subpass); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp index e47055df..1136a2c9 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp @@ -51,9 +51,12 @@ namespace SHADE std::array cameraBufferArray{cameraBuffer}; - cameraDescriptorSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA, std::span>{ cameraBufferArray.data(), cameraBufferArray.size()}, 0, sizeof (SHShaderCameraData)); + // We use index 0 because the descriptor set is standalone created from a single desc set layout. What the driver sees is that this set is at index 0 during updating. + static constexpr uint8_t SET_0 = 0; - cameraDescriptorSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA); + cameraDescriptorSet->ModifyWriteDescBuffer(SET_0, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA, std::span>{ cameraBufferArray.data(), cameraBufferArray.size()}, 0, sizeof (SHShaderCameraData)); + + cameraDescriptorSet->UpdateDescriptorSetBuffer(SET_0, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA); } SHRenderer::~SHRenderer(void) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h index 83291700..4bd205be 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h @@ -37,7 +37,7 @@ namespace SHADE class SHVkCommandBuffer; class SHCamera; class SHVkDescriptorSetGroup; - class SHGraphicsGlobalData; + class SHPredefinedData; class SHVkDescriptorPool; class SHVkBuffer; class SHCameraDirector; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp index 3d5a5773..448c3bed 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp @@ -1,6 +1,6 @@ #include "SHpch.h" #include "SHLightingSubSystem.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/MiddleEnd/GlobalData/SHPredefinedData.h" #include "Tools/Utilities/SHUtilities.h" #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Buffers/SHVkBuffer.h" @@ -385,7 +385,7 @@ namespace SHADE std::fill (variableSizes.begin(), variableSizes.end(), 1); // Create the descriptor set - lightingDataDescSet = descPool->Allocate({ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS] }, variableSizes); + lightingDataDescSet = descPool->Allocate({ SHPredefinedData::GetPredefinedDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS] }, variableSizes); #ifdef _DEBUG const auto& CAM_DESC_SETS = lightingDataDescSet->GetVkHandle(); for (int i = 0; i < static_cast(CAM_DESC_SETS.size()); ++i) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp index 05bd8813..9e6f1bd7 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp @@ -1,7 +1,7 @@ #include "SHpch.h" #include "SHPipelineLibrary.h" #include "Graphics/Devices/SHVkLogicalDevice.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/MiddleEnd/GlobalData/SHPredefinedData.h" #include "Graphics/RenderGraph/SHSubpass.h" #include "Graphics/SHVkUtil.h" @@ -13,7 +13,7 @@ namespace SHADE SHPipelineLayoutParams params { .shaderModules = {vsFsPair.first, vsFsPair.second}, - .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts() + .globalDescSetLayouts = SHPredefinedData::GetPredefinedDescSetLayouts() }; // Create the pipeline layout @@ -21,7 +21,7 @@ namespace SHADE // Create the pipeline and configure the default vertex input state auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderpass, subpass); - newPipeline->GetPipelineState().SetVertexInputState(SHGraphicsGlobalData::GetDefaultViState()); + newPipeline->GetPipelineState().SetVertexInputState(SHPredefinedData::GetDefaultViState()); SHColorBlendState colorBlendState{}; colorBlendState.logic_op_enable = VK_FALSE; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h index aeb023c5..389f5fa8 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h @@ -10,7 +10,7 @@ namespace SHADE class SHVkDescriptorSetLayouts; class SHVkPipeline; class SHSubpass; - class SHGraphicsGlobalData; + class SHPredefinedData; // Pipeline library is a PURELY MIDDLE END SYSTEM. It is responsible for only creating pipelines from shaders and caching // them so that they don't need to be recreated again. diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHFont.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHFont.cpp index 3dd54ca5..f0273940 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHFont.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHFont.cpp @@ -1,7 +1,7 @@ #include "SHpch.h" #include "SHFont.h" #include "Graphics/Devices/SHVkLogicalDevice.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/MiddleEnd/GlobalData/SHPredefinedData.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/Images/SHVkSampler.h" diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.cpp index 6748311e..f0e375e6 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.cpp @@ -6,7 +6,7 @@ #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/MiddleEnd/TextRendering/SHFont.h" #include "Graphics/Buffers/SHVkBuffer.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/MiddleEnd/GlobalData/SHPredefinedData.h" #include "Graphics/Pipeline/SHVkPipeline.h" #include "Graphics/SHVkUtil.h" #include "Graphics/RenderGraph/SHSubpass.h" @@ -103,7 +103,7 @@ namespace SHADE SHPipelineLayoutParams plParams { .shaderModules = {textVS, textFS}, - .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts() + .globalDescSetLayouts = SHPredefinedData::GetPredefinedDescSetLayouts() }; pipelineLayout = logicalDevice->CreatePipelineLayout(plParams); @@ -157,24 +157,6 @@ namespace SHADE // Construct pipeline pipeline->ConstructPipeline(); - SHVkDescriptorSetLayout::Binding fontBitmapBinding - { - .Type = vk::DescriptorType::eCombinedImageSampler, - .Stage = vk::ShaderStageFlagBits::eFragment, - .BindPoint = SHGraphicsConstants::DescriptorSetBindings::FONT_BITMAP_DATA, - .DescriptorCount = 1, - }; - - SHVkDescriptorSetLayout::Binding fontMatrixBinding - { - .Type = vk::DescriptorType::eStorageBuffer, - .Stage = vk::ShaderStageFlagBits::eVertex, - .BindPoint = SHGraphicsConstants::DescriptorSetBindings::FONT_MATRIX_DATA, - .DescriptorCount = 1, - }; - - fontDataDescSetLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::FONT_DATA, { fontBitmapBinding, fontMatrixBinding }); - } void SHTextRenderingSubSystem::Run(uint32_t frameIndex) noexcept @@ -209,6 +191,7 @@ namespace SHADE cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::CALCULATED_GLYPH_POSITION, comp.charPositionDataBuffer, 0); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::GLYPH_INDEX, comp.indexingDataBuffer, 0); + // bind camera desc set (again). Necessary because pipeline layout is not compatible. cameraDescSetBind(cmdBuffer, frameIndex); // bind descriptors for font (matrices) @@ -234,9 +217,9 @@ namespace SHADE } - Handle SHTextRenderingSubSystem::GetFontDataDescSetLayout(void) const noexcept - { - return fontDataDescSetLayout; - } + //Handle SHTextRenderingSubSystem::GetFontDataDescSetLayout(void) const noexcept + //{ + // return fontDataDescSetLayout; + //} } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.h index 05ab01da..78b363d4 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.h @@ -41,7 +41,7 @@ namespace SHADE Handle pipelineLayout; //! Descriptor set for font data access in shaders - Handle fontDataDescSetLayout; + //Handle fontDataDescSetLayout; //! Super temporary. Global descriptor set needs to be revamped along with //! entire graphics system. @@ -58,7 +58,7 @@ namespace SHADE void Exit(void) noexcept; - Handle GetFontDataDescSetLayout (void) const noexcept; + //Handle GetFontDataDescSetLayout (void) const noexcept; }; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp index dfb3f3b9..a31f54de 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp @@ -24,7 +24,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "Graphics/Images/SHVkImage.h" #include "Graphics/Images/SHVkImageView.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/MiddleEnd/GlobalData/SHPredefinedData.h" #include "Assets/Asset Types/SHTextureAsset.h" namespace SHADE @@ -168,7 +168,7 @@ namespace SHADE } texDescriptors = descPool->Allocate ( - { SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] }, + { SHPredefinedData::GetPredefinedDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] }, { static_cast(texOrder.size()) } ); #ifdef _DEBUG diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 2ffd6d13..fc029161 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -12,7 +12,7 @@ #include "SHRenderGraphStorage.h" #include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h" #include "Tools/Utilities/SHUtilities.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/MiddleEnd/GlobalData/SHPredefinedData.h" #include "Graphics/RenderGraph/SHRenderToSwapchainImageSystem.h" namespace SHADE diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index 0a9ed376..f892483f 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -29,7 +29,7 @@ namespace SHADE class SHVkCommandPool; class SHVkCommandBuffer; class SHRenderGraphNode; - class SHGraphicsGlobalData; + class SHPredefinedData; class SHVkDescriptorPool; class SHRenderGraphStorage; class SHRenderToSwapchainImageSystem; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index 775d64f7..2311ee0c 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -19,7 +19,7 @@ namespace SHADE class SHVkLogicalDevice; class SHVkRenderpass; class SHVkDescriptorPool; - class SHGraphicsGlobalData; + class SHPredefinedData; class SHRenderGraphStorage; class SHRenderGraphNodeCompute; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp index 2f8fd968..aca987d8 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp @@ -6,7 +6,7 @@ #include "Graphics/Descriptors/SHVkDescriptorSetLayout.h" #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Pipeline/SHVkPipelineLayout.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/MiddleEnd/GlobalData/SHPredefinedData.h" #include "SHRenderGraphStorage.h" #include "SHRenderGraphResource.h" #include "Graphics/Commands/SHVkCommandBuffer.h" @@ -27,7 +27,7 @@ namespace SHADE SHPipelineLayoutParams pipelineLayoutParams { .shaderModules = {computeShaderModule}, - .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts(), + .globalDescSetLayouts = SHPredefinedData::GetPredefinedDescSetLayouts(), .dynamicBufferBindings = std::move(dynamicBufferBindings), }; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h index d02d8d39..d473dd2a 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h @@ -7,7 +7,7 @@ namespace SHADE { class SHVkLogicalDevice; class SHVkSwapchain; - class SHGraphicsGlobalData; + class SHPredefinedData; class SHVkDescriptorPool; class SHRenderGraphResource; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderToSwapchainImageSystem.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderToSwapchainImageSystem.cpp index 770217ee..b8717925 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderToSwapchainImageSystem.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderToSwapchainImageSystem.cpp @@ -1,7 +1,7 @@ #include "SHpch.h" #include "SHRenderToSwapchainImageSystem.h" #include "Graphics/Devices/SHVkLogicalDevice.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/MiddleEnd/GlobalData/SHPredefinedData.h" #include "Graphics/RenderGraph/SHRenderGraphNode.h" #include "Graphics/RenderGraph/SHSubpass.h" #include "Graphics/SHVkUtil.h" @@ -24,7 +24,7 @@ namespace SHADE auto pipelineLayout = logicalDevice->CreatePipelineLayout(SHPipelineLayoutParams { .shaderModules = {shaderModules.first, shaderModules.second}, - .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts(), + .globalDescSetLayouts = SHPredefinedData::GetPredefinedDescSetLayouts(), }); pipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderGraphNode->GetRenderpass(), subpass); diff --git a/SHADE_Engine/src/Tools/Utilities/SHUtilities.h b/SHADE_Engine/src/Tools/Utilities/SHUtilities.h index 6cdd91ee..c3492f13 100644 --- a/SHADE_Engine/src/Tools/Utilities/SHUtilities.h +++ b/SHADE_Engine/src/Tools/Utilities/SHUtilities.h @@ -43,6 +43,73 @@ namespace SHADE static constexpr OutputType ConvertEnum(InputType enumClassMember) noexcept; }; + template + class SHEnumWrapper + { + public: + using UnderlyingType = typename std::underlying_type_t; + + private: + UnderlyingType mask; + + public: + + constexpr SHEnumWrapper(void) noexcept + : mask{ 0 } + { + + }; + + constexpr SHEnumWrapper(BitType bit) noexcept + : mask{ static_cast(bit) } + { + + }; + + constexpr SHEnumWrapper(SHEnumWrapper const& rhs) noexcept = default; + constexpr SHEnumWrapper& operator= (SHEnumWrapper const& rhs) noexcept = default; + + constexpr explicit SHEnumWrapper(UnderlyingType flags) noexcept + : mask{ flags } + { + + }; + + constexpr SHEnumWrapper operator| (SHEnumWrapper const& rhs) const noexcept + { + return static_cast> (mask | rhs.mask); + }; + + constexpr SHEnumWrapper operator& (SHEnumWrapper const& rhs) const noexcept + { + return static_cast> (mask & rhs.mask); + }; + + constexpr operator UnderlyingType() const noexcept + { + return mask; + }; + }; + + template>> + inline BitType operator|(const BitType& left, const BitType& right) + { + return static_cast(static_cast(left) | static_cast(right)); + } + + template>> + inline BitType operator&(const BitType& left, const BitType& right) + { + return static_cast(static_cast(left) & static_cast(right)); + } + + template + std::ostream& operator<<(std::ostream& os, EnumType const& type) + { + os << static_cast(type); + return os; + } + } // namespace SHADE #include "SHUtilities.hpp"