diff --git a/dependencies/imgui b/dependencies/imgui index fdc084f..b4c9635 160000 --- a/dependencies/imgui +++ b/dependencies/imgui @@ -1 +1 @@ -Subproject commit fdc084f532189fda8474079f79e74fa5e3541c9f +Subproject commit b4c96355c9b51b54c4deb52e7d7cdfc7bf79bc2f diff --git a/src/engine/EngineContext.cpp b/src/engine/EngineContext.cpp index 2bc8bd3..063c29a 100644 --- a/src/engine/EngineContext.cpp +++ b/src/engine/EngineContext.cpp @@ -18,6 +18,7 @@ #include "engine/assets/transfer/TransferManager.hpp" #include "engine/math/Average.hpp" #include "engine/math/literals/size.hpp" +#include "engine/rendering/pipelines/v2/Pipeline.hpp" namespace fgl::engine { diff --git a/src/engine/FrameInfo.cpp b/src/engine/FrameInfo.cpp index 329a576..7ab6e1d 100644 --- a/src/engine/FrameInfo.cpp +++ b/src/engine/FrameInfo.cpp @@ -21,7 +21,7 @@ namespace fgl::engine return camera->getDescriptor( frame_idx ); } - void FrameInfo::bindCamera( internal::Pipeline& pipeline ) + void FrameInfo::bindCamera( [[maybe_unused]] internal::Pipeline& pipeline ) { //TODO: This } diff --git a/src/engine/FrameInfo.hpp b/src/engine/FrameInfo.hpp index 9cc6eee..089aceb 100644 --- a/src/engine/FrameInfo.hpp +++ b/src/engine/FrameInfo.hpp @@ -42,29 +42,28 @@ namespace fgl::engine alignas( 16 ) int num_lights { 0 }; }; - //using GlobalDescriptorSet = descriptors::DescriptorSetLayout< 0, descriptors::EmptyDescriptor< 0 > >; + constexpr descriptors::Descriptor texture_descriptor { 0, + vk::DescriptorType::eCombinedImageSampler, + vk::ShaderStageFlagBits::eAllGraphics, + 512, + vk::DescriptorBindingFlagBits::eUpdateAfterBind + | vk::DescriptorBindingFlagBits::ePartiallyBound }; - using TextureDescriptor = descriptors::Descriptor< - 0, - vk::DescriptorType::eCombinedImageSampler, - vk::ShaderStageFlagBits::eAllGraphics, - 512, - vk::DescriptorBindingFlagBits::eUpdateAfterBind | vk::DescriptorBindingFlagBits::ePartiallyBound >; + inline static descriptors::DescriptorSetLayout texture_descriptor_set { 2, texture_descriptor }; - using TextureDescriptorSet = descriptors::DescriptorSetLayout< 2, TextureDescriptor >; + constexpr vk::ShaderStageFlags FRAG_STAGE { vk::ShaderStageFlagBits::eFragment }; - using PositionDescriptor = descriptors::AttachmentDescriptor< 0, vk::ShaderStageFlagBits::eFragment >; - using NormalDescriptor = descriptors::AttachmentDescriptor< 1, vk::ShaderStageFlagBits::eFragment >; - using AlbedoDescriptor = descriptors::AttachmentDescriptor< 2, vk::ShaderStageFlagBits::eFragment >; + constexpr descriptors::AttachmentDescriptor position_descriptor { 0, FRAG_STAGE }; + constexpr descriptors::AttachmentDescriptor normal_descriptor { 1, FRAG_STAGE }; + constexpr descriptors::AttachmentDescriptor albedo_descriptor { 2, FRAG_STAGE }; - static_assert( is_descriptor< PositionDescriptor > ); + inline static descriptors::DescriptorSetLayout gbuffer_set { + 0, position_descriptor, normal_descriptor, albedo_descriptor + }; - using GBufferDescriptorSet = - descriptors::DescriptorSetLayout< 0, PositionDescriptor, NormalDescriptor, AlbedoDescriptor >; + constexpr descriptors::AttachmentDescriptor input_descriptor { 0, vk::ShaderStageFlagBits::eFragment }; - using InputDescriptor = descriptors::AttachmentDescriptor< 0, vk::ShaderStageFlagBits::eFragment >; - - using GuiInputDescriptorSet = descriptors::DescriptorSetLayout< 0, InputDescriptor >; + inline static descriptors::DescriptorSetLayout gui_descriptor_set { 0, input_descriptor }; class OctTreeNode; diff --git a/src/engine/assets/image/ImageView.cpp b/src/engine/assets/image/ImageView.cpp index 7937dfa..00b88b0 100644 --- a/src/engine/assets/image/ImageView.cpp +++ b/src/engine/assets/image/ImageView.cpp @@ -52,6 +52,24 @@ namespace fgl::engine return info; } + ImageView::~ImageView() + { + } + + void ImageView::setName( const std::string str ) + { + m_name = str; + m_sampler.setName( str + " Sampler" ); + m_resource->setName( str + " Resource" ); + + vk::DebugUtilsObjectNameInfoEXT info {}; + info.objectType = vk::ObjectType::eImageView; + info.pObjectName = str.c_str(); + info.setObjectHandle( reinterpret_cast< std::uint64_t >( static_cast< VkImageView >( *m_image_view ) ) ); + + Device::getInstance().setDebugUtilsObjectName( info ); + } + vk::ImageView ImageView::getVkView() { return *m_image_view; @@ -62,11 +80,6 @@ namespace fgl::engine return m_resource->extent(); } - void ImageView::setName( const std::string& str ) - { - m_resource->setName( str ); - } - bool ImageView::ready() { return m_resource->ready(); diff --git a/src/engine/assets/image/ImageView.hpp b/src/engine/assets/image/ImageView.hpp index 31a973f..7a04578 100644 --- a/src/engine/assets/image/ImageView.hpp +++ b/src/engine/assets/image/ImageView.hpp @@ -21,11 +21,12 @@ namespace fgl::engine vk::raii::ImageView m_image_view; Sampler m_sampler; + std::string m_name; + + [[nodiscard]] static vk::raii::ImageView createImageView( const std::shared_ptr< ImageHandle >& img ); public: - void setName( const std::string& str ); - //! Returns true if the resource has been staged bool ready(); @@ -39,8 +40,6 @@ namespace fgl::engine ImageView( ImageView&& other ) = default; ImageView& operator=( ImageView&& other ) = default; - [[nodiscard]] static vk::raii::ImageView createImageView( const std::shared_ptr< ImageHandle >& img ); - [[nodiscard]] vk::Extent2D getExtent() const; [[nodiscard]] vk::ImageView getVkView(); @@ -49,10 +48,16 @@ namespace fgl::engine [[nodiscard]] VkImage getVkImage() { return m_resource->getVkImage(); } + void setSampler( Sampler&& sampler ) { m_sampler = std::forward< Sampler >( sampler ); } + [[nodiscard]] Sampler& getSampler() { return m_sampler; }; vk::DescriptorImageInfo descriptorInfo( vk::Sampler sampler, vk::ImageLayout layout ) const; vk::DescriptorImageInfo descriptorInfo( vk::ImageLayout layout ) const; + + ~ImageView(); + + void setName( std::string str ); }; } // namespace fgl::engine diff --git a/src/engine/assets/image/Sampler.cpp b/src/engine/assets/image/Sampler.cpp index 5750e77..3895f2b 100644 --- a/src/engine/assets/image/Sampler.cpp +++ b/src/engine/assets/image/Sampler.cpp @@ -12,12 +12,12 @@ namespace fgl::engine { vk::raii::Sampler createSampler( - vk::Filter min_filter, - vk::Filter mag_filter, - vk::SamplerMipmapMode mipmode, - vk::SamplerAddressMode sampler_wrap_u, - vk::SamplerAddressMode sampler_wrap_v, - vk::SamplerAddressMode sampler_wrap_w ) + const vk::Filter min_filter, + const vk::Filter mag_filter, + const vk::SamplerMipmapMode mipmode, + const vk::SamplerAddressMode sampler_wrap_u, + const vk::SamplerAddressMode sampler_wrap_v, + const vk::SamplerAddressMode sampler_wrap_w ) { vk::SamplerCreateInfo info; @@ -95,7 +95,7 @@ namespace fgl::engine * @param wraps x wrap * @param wrapt y wrap */ - Sampler::Sampler( int min_filter, int mag_filter, int wraps, int wrapt ) : + Sampler::Sampler( const int min_filter, const int mag_filter, const int wraps, const int wrapt ) : Sampler( gl::filterToVk( min_filter ), gl::filterToVk( mag_filter ), diff --git a/src/engine/assets/image/Sampler.hpp b/src/engine/assets/image/Sampler.hpp index eafb37c..010da52 100644 --- a/src/engine/assets/image/Sampler.hpp +++ b/src/engine/assets/image/Sampler.hpp @@ -15,7 +15,7 @@ namespace fgl::engine class Sampler { - vk::raii::Sampler m_sampler { VK_NULL_HANDLE }; + vk::raii::Sampler m_sampler; public: diff --git a/src/engine/assets/model/ModelVertex.cpp b/src/engine/assets/model/ModelVertex.cpp index 39c4085..927398e 100644 --- a/src/engine/assets/model/ModelVertex.cpp +++ b/src/engine/assets/model/ModelVertex.cpp @@ -43,8 +43,11 @@ namespace fgl::engine // {location, binding, format, offset} // attribute_descriptions.emplace_back( 0, 0, vk::Format::eR32G32B32Sfloat, offsetof( ModelVertex, m_position ) ); // attribute_descriptions.emplace_back( 1, 0, vk::Format::eR32G32B32Sfloat, offsetof( ModelVertex, m_color ) ); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winvalid-offsetof" attribute_descriptions.emplace_back( 2, 0, vk::Format::eR32G32B32Sfloat, offsetof( ModelVertex, m_normal ) ); attribute_descriptions.emplace_back( 3, 0, vk::Format::eR32G32Sfloat, offsetof( ModelVertex, m_uv ) ); +#pragma GCC diagnostic pop //Normal Matrix attribute_descriptions.emplace_back( 4, 1, vk::Format::eR32G32B32A32Sfloat, 0 ); diff --git a/src/engine/assets/model/SimpleVertex.hpp b/src/engine/assets/model/SimpleVertex.hpp index 473ef5a..aa3407f 100644 --- a/src/engine/assets/model/SimpleVertex.hpp +++ b/src/engine/assets/model/SimpleVertex.hpp @@ -3,7 +3,11 @@ // #pragma once + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Weffc++" #include +#pragma GCC diagnostic pop #include @@ -11,7 +15,7 @@ namespace vk { struct VertexInputAttributeDescription; struct VertexInputBindingDescription; -} +} // namespace vk namespace fgl::engine { @@ -28,5 +32,4 @@ namespace fgl::engine static std::vector< vk::VertexInputAttributeDescription > getAttributeDescriptions(); }; - -} +} // namespace fgl::engine diff --git a/src/engine/assets/model/builders/SceneBuilder.cpp b/src/engine/assets/model/builders/SceneBuilder.cpp index 59b136b..a285729 100644 --- a/src/engine/assets/model/builders/SceneBuilder.cpp +++ b/src/engine/assets/model/builders/SceneBuilder.cpp @@ -100,54 +100,66 @@ namespace fgl::engine // If the type is a smaller scalar then we want can still copy the data. log::warn( "Attempting to copy data of size {} into type of size {}", byte_count, T_SIZE ); - switch ( byte_count ) + if constexpr ( std::is_scalar_v< T > ) { - default: - throw std::runtime_error( "Unknown size" ); - case 1: - for ( std::size_t i = 0; i < accessor.count; ++i ) - { - std::uint8_t tmp {}; - std::memcpy( - &tmp, - buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset + ( i * byte_count ), - byte_count ); - data.emplace_back( static_cast< T >( tmp ) ); - } - return data; - case 2: - for ( std::size_t i = 0; i < accessor.count; ++i ) - { - std::uint16_t tmp {}; - std::memcpy( - &tmp, - buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset + ( i * byte_count ), - byte_count ); - data.emplace_back( static_cast< T >( tmp ) ); - } - return data; - case 4: - for ( std::size_t i = 0; i < accessor.count; ++i ) - { - std::uint32_t tmp {}; - std::memcpy( - &tmp, - buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset + ( i * byte_count ), - byte_count ); - data.emplace_back( static_cast< T >( tmp ) ); - } - return data; - case 8: - for ( std::size_t i = 0; i < accessor.count; ++i ) - { - std::uint64_t tmp {}; - std::memcpy( - &tmp, - buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset + ( i * byte_count ), - byte_count ); - data.emplace_back( static_cast< T >( tmp ) ); - } - return data; + switch ( byte_count ) + { + default: + throw std::runtime_error( "Unknown size" ); + case 1: + for ( std::size_t i = 0; i < accessor.count; ++i ) + { + std::uint8_t tmp {}; + std::memcpy( + &tmp, + buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset + + ( i * byte_count ), + byte_count ); + data.emplace_back( static_cast< T >( tmp ) ); + } + return data; + case 2: + for ( std::size_t i = 0; i < accessor.count; ++i ) + { + std::uint16_t tmp {}; + std::memcpy( + &tmp, + buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset + + ( i * byte_count ), + byte_count ); + data.emplace_back( static_cast< T >( tmp ) ); + } + return data; + case 4: + for ( std::size_t i = 0; i < accessor.count; ++i ) + { + std::uint32_t tmp {}; + std::memcpy( + &tmp, + buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset + + ( i * byte_count ), + byte_count ); + data.emplace_back( static_cast< T >( tmp ) ); + } + return data; + case 8: + for ( std::size_t i = 0; i < accessor.count; ++i ) + { + std::uint64_t tmp {}; + std::memcpy( + &tmp, + buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset + + ( i * byte_count ), + byte_count ); + data.emplace_back( static_cast< T >( tmp ) ); + } + return data; + } + } + else + { + throw std::runtime_error( + std::format( "Tried extracting data of size {} into type of size {}", byte_count, T_SIZE ) ); } } else diff --git a/src/engine/camera/Camera.cpp b/src/engine/camera/Camera.cpp index cd74985..e5b9fd6 100644 --- a/src/engine/camera/Camera.cpp +++ b/src/engine/camera/Camera.cpp @@ -58,7 +58,7 @@ namespace fgl::engine descriptors::DescriptorSet& Camera::getDescriptor( const FrameIndex index ) { assert( index < m_camera_info_descriptors.size() ); - return m_camera_info_descriptors[ index ]; + return *m_camera_info_descriptors[ index ]; } void Camera::setFOV( const float fov_y ) @@ -331,10 +331,10 @@ namespace fgl::engine for ( std::uint8_t i = 0; i < SwapChain::MAX_FRAMES_IN_FLIGHT; ++i ) { - descriptors::DescriptorSet set { CameraDescriptorSet::createLayout() }; - set.setMaxIDX( 0 ); - set.bindUniformBuffer( 0, m_camera_frame_info[ i ] ); - set.update(); + auto set { camera_descriptor_set.create() }; + set->setMaxIDX( 0 ); + set->bindUniformBuffer( 0, m_camera_frame_info[ i ] ); + set->update(); m_camera_info_descriptors.emplace_back( std::move( set ) ); } diff --git a/src/engine/camera/Camera.hpp b/src/engine/camera/Camera.hpp index 33f5783..cf296f4 100644 --- a/src/engine/camera/Camera.hpp +++ b/src/engine/camera/Camera.hpp @@ -73,7 +73,7 @@ namespace fgl::engine PerFrameSuballocation< HostSingleT< CameraInfo > > m_camera_frame_info; // Camera info is expected at binding 0 - std::vector< descriptors::DescriptorSet > m_camera_info_descriptors {}; + std::vector< std::unique_ptr< descriptors::DescriptorSet > > m_camera_info_descriptors {}; // TODO: Remove this old swapchain and instead do a proper deffered cleanup of it. std::shared_ptr< CameraSwapchain > m_old_swapchain { nullptr }; diff --git a/src/engine/camera/CameraDescriptor.hpp b/src/engine/camera/CameraDescriptor.hpp index 046e43e..70f71a5 100644 --- a/src/engine/camera/CameraDescriptor.hpp +++ b/src/engine/camera/CameraDescriptor.hpp @@ -7,8 +7,10 @@ namespace fgl::engine { - using CameraDescriptor = - descriptors::Descriptor< 0, vk::DescriptorType::eUniformBuffer, vk::ShaderStageFlagBits::eAllGraphics >; + constexpr descriptors::Descriptor camera_descriptor { 0, + vk::DescriptorType::eUniformBuffer, + vk::ShaderStageFlagBits::eAllGraphics }; + + inline static descriptors::DescriptorSetLayout camera_descriptor_set { 1, camera_descriptor }; - using CameraDescriptorSet = descriptors::DescriptorSetLayout< 1, CameraDescriptor >; } // namespace fgl::engine \ No newline at end of file diff --git a/src/engine/camera/CameraSwapchain.cpp b/src/engine/camera/CameraSwapchain.cpp index 78169f0..5114a6f 100644 --- a/src/engine/camera/CameraSwapchain.cpp +++ b/src/engine/camera/CameraSwapchain.cpp @@ -16,7 +16,8 @@ namespace fgl::engine for ( PresentIndex i = 0; i < SwapChain::MAX_FRAMES_IN_FLIGHT; ++i ) { - auto set { std::make_unique< descriptors::DescriptorSet >( GBufferDescriptorSet::createLayout() ) }; + //auto set { std::make_unique< descriptors::DescriptorSet >( GBufferDescriptorSet::createLayout() ) }; + auto set { gbuffer_set.create() }; set->setMaxIDX( 2 ); diff --git a/src/engine/concepts/is_descriptor.hpp b/src/engine/concepts/is_descriptor.hpp deleted file mode 100644 index 4b6f126..0000000 --- a/src/engine/concepts/is_descriptor.hpp +++ /dev/null @@ -1,32 +0,0 @@ -// -// Created by kj16609 on 1/1/24. -// - -#pragma once - -#include "is_empty_descriptor.hpp" -#include "is_layout_descriptor.hpp" - -namespace fgl::engine -{ - template < typename T > - concept is_image_descriptor = - is_layout_descriptor< T > && ( T::m_descriptor_type == vk::DescriptorType::eSampledImage ); - - template < typename T > - concept is_attachment_descriptor = - is_layout_descriptor< T > && ( T::m_descriptor_type == vk::DescriptorType::eInputAttachment ); - - template < typename T > - concept is_uniform_buffer_desciptor = - is_layout_descriptor< T > && ( T::m_descriptor_type == vk::DescriptorType::eUniformBuffer ); - - template < typename T > - concept is_storage_buffer_descriptor = - is_layout_descriptor< T > && ( T::m_descriptor_type == vk::DescriptorType::eStorageBuffer ); - - template < typename T > - concept is_buffer_descriptor = is_uniform_buffer_desciptor< T > || is_storage_buffer_descriptor< T >; - - template < typename T > concept is_descriptor = is_empty_descriptor< T > || is_layout_descriptor< T >; -} // namespace fgl::engine \ No newline at end of file diff --git a/src/engine/concepts/is_descriptor_set.hpp b/src/engine/concepts/is_descriptor_set.hpp deleted file mode 100644 index 599e19d..0000000 --- a/src/engine/concepts/is_descriptor_set.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// -// Created by kj16609 on 3/13/24. -// - -#pragma once - -#include -#include - -#include -#include - -namespace fgl::engine -{ - template < typename T > - concept is_descriptor_set = requires( std::remove_reference_t< T > t ) { - { - t.descriptor_count - } -> std::same_as< const std::uint16_t& >; - { - T::createLayout() - } -> std::same_as< vk::raii::DescriptorSetLayout >; - }; -} // namespace fgl::engine diff --git a/src/engine/concepts/is_descriptor_set_collection.hpp b/src/engine/concepts/is_descriptor_set_collection.hpp deleted file mode 100644 index 58b2107..0000000 --- a/src/engine/concepts/is_descriptor_set_collection.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// -// Created by kj16609 on 3/13/24. -// - -#pragma once - -#include -#include - -namespace fgl::engine -{ - - template < typename T > - concept is_descriptor_set_collection = requires( T t ) { - typename T::DescriptorSetTuple; - { - t.DescriptorSetCount - } -> std::same_as< const std::uint64_t& >; - }; - -} // namespace fgl::engine \ No newline at end of file diff --git a/src/engine/concepts/is_empty_descriptor.hpp b/src/engine/concepts/is_empty_descriptor.hpp deleted file mode 100644 index d8da15a..0000000 --- a/src/engine/concepts/is_empty_descriptor.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// -// Created by kj16609 on 3/13/24. -// - -#pragma once - -namespace fgl::engine -{ - /** - * Descriptor must have a `static constexpr bool is_empty` member with the value `true` - * Descriptor must also be valid in `is_descriptor` - * @tparam T - */ - template < typename T > - concept is_empty_descriptor = requires( T t ) { - { - t.m_binding_idx - } -> std::same_as< const std::uint16_t& >; - { - t.is_empty - } -> std::same_as< const bool& >; - } && T::is_empty; - -} // namespace fgl::engine \ No newline at end of file diff --git a/src/engine/concepts/is_empty_descriptor_set.hpp b/src/engine/concepts/is_empty_descriptor_set.hpp deleted file mode 100644 index d49d480..0000000 --- a/src/engine/concepts/is_empty_descriptor_set.hpp +++ /dev/null @@ -1,16 +0,0 @@ -// -// Created by kj16609 on 3/13/24. -// - -#pragma once - -#include "is_descriptor_set.hpp" -#include "is_empty_descriptor.hpp" - -namespace fgl::engine -{ - - template < typename T > - concept is_empty_descriptor_set = is_descriptor_set< T > && ( T::descriptor_count == 1 ) - && is_empty_descriptor< typename T::template Binding< 0 > >; -} diff --git a/src/engine/concepts/is_layout_descriptor.hpp b/src/engine/concepts/is_layout_descriptor.hpp deleted file mode 100644 index bb7e135..0000000 --- a/src/engine/concepts/is_layout_descriptor.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// -// Created by kj16609 on 3/13/24. -// - -#pragma once - -namespace fgl::engine -{ - template < typename T > - concept is_layout_descriptor = requires( T t ) { - { - t.m_binding_idx - } -> std::same_as< const std::uint16_t& >; - { - t.m_layout_binding - } -> std::same_as< const vk::DescriptorSetLayoutBinding& >; - { - t.m_descriptor_type - } -> std::same_as< const vk::DescriptorType& >; - }; -} \ No newline at end of file diff --git a/src/engine/concepts/is_valid_pipeline_input.hpp b/src/engine/concepts/is_valid_pipeline_input.hpp deleted file mode 100644 index 0fe5788..0000000 --- a/src/engine/concepts/is_valid_pipeline_input.hpp +++ /dev/null @@ -1,13 +0,0 @@ -// -// Created by kj16609 on 3/13/24. -// - -#pragma once - -#include "is_constant_range.hpp" -#include "is_descriptor_set.hpp" - -namespace fgl::engine -{ - template < typename T > concept is_valid_pipeline_input = is_constant_range< T > || is_descriptor_set< T >; -} \ No newline at end of file diff --git a/src/engine/debug/drawers.cpp b/src/engine/debug/drawers.cpp index 65bb91a..2f7ac0a 100644 --- a/src/engine/debug/drawers.cpp +++ b/src/engine/debug/drawers.cpp @@ -14,7 +14,7 @@ namespace fgl::engine::debug void drawLine( const LineSegment< CoordinateSpace::World >& line, const glm::vec3 color ) { - drawLine( line.getStart(), line.getEnd() ); + drawLine( line.getStart(), line.getEnd(), color ); } void drawBoundingBox( const AxisAlignedBoundingBox< CoordinateSpace::World >& bounding_box, const glm::vec3 color ) diff --git a/src/engine/debug/logging/formatters/glm.cpp b/src/engine/debug/logging/formatters/glm.cpp index 64b4ee1..91bbe85 100644 --- a/src/engine/debug/logging/formatters/glm.cpp +++ b/src/engine/debug/logging/formatters/glm.cpp @@ -4,8 +4,12 @@ #include "glm.hpp" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Weffc++" +#pragma GCC diagnostic ignored "-Wduplicated-branches" #define GLM_ENABLE_EXPERIMENTAL #include +#pragma GCC diagnostic pop std::format_context::iterator std::formatter< glm::qua< float > >::format( const glm::quat& quat, format_context& ctx ) const diff --git a/src/engine/debug/logging/formatters/matrix.cpp b/src/engine/debug/logging/formatters/matrix.cpp index 4c4044e..9e43611 100644 --- a/src/engine/debug/logging/formatters/matrix.cpp +++ b/src/engine/debug/logging/formatters/matrix.cpp @@ -4,7 +4,11 @@ #include "matrix.hpp" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Weffc++" +#pragma GCC diagnostic ignored "-Wduplicated-branches" #include +#pragma GCC diagnostic pop std::format_context::iterator std::formatter< glm::vec4 >::format( const glm::vec4& vec, format_context& ctx ) const { diff --git a/src/engine/descriptors/Descriptor.hpp b/src/engine/descriptors/Descriptor.hpp index 954e9c7..0f16369 100644 --- a/src/engine/descriptors/Descriptor.hpp +++ b/src/engine/descriptors/Descriptor.hpp @@ -7,85 +7,81 @@ #include #include "engine/memory/buffers/Buffer.hpp" -#include "engine/concepts/is_descriptor.hpp" namespace fgl::engine::descriptors { - /** - * - * @tparam binding_idx Index of the descriptor - * @tparam descriptor_type Descriptor flags - * @tparam stage_flags - * @tparam binding_count Number of descriptors to have - * @tparam binding_flags Flags to bind with - */ - template < - std::uint16_t binding_idx, - vk::DescriptorType descriptor_type, - vk::ShaderStageFlags stage_flags = vk::ShaderStageFlagBits::eAll, - std::uint16_t binding_count = 1, - vk::DescriptorBindingFlags binding_flags = static_cast< vk::DescriptorBindingFlags >( 0 ) > struct Descriptor { - static constexpr std::uint16_t m_binding_idx { binding_idx }; - static constexpr std::uint16_t m_count { binding_count }; + std::uint16_t m_index; + vk::DescriptorType m_type; + vk::ShaderStageFlags m_stage_flags; + std::uint16_t m_count; + vk::DescriptorBindingFlags m_binding_flags; - static constexpr vk::DescriptorType m_descriptor_type { descriptor_type }; + consteval Descriptor() = delete; - static constexpr auto m_binding_flags { binding_flags }; + constexpr Descriptor( + const std::uint16_t binding_idx, + const vk::DescriptorType type, + const vk::ShaderStageFlags stage_flags, + const std::uint16_t count = 1, + const vk::DescriptorBindingFlags binding_flags = static_cast< vk::DescriptorBindingFlags >( 0 ) ) : + m_index( binding_idx ), + m_type( type ), + m_stage_flags( stage_flags ), + m_count( count ), + m_binding_flags( binding_flags ) + {} - consteval static vk::DescriptorSetLayoutBinding generateLayoutBinding() + constexpr vk::DescriptorSetLayoutBinding generateLayoutBinding() { - vk::DescriptorSetLayoutBinding layout_binding {}; - layout_binding.binding = binding_idx; - layout_binding.descriptorType = descriptor_type; - layout_binding.descriptorCount = binding_count; - layout_binding.stageFlags = stage_flags; + vk::DescriptorSetLayoutBinding layout_binding; + layout_binding.binding = m_index; + layout_binding.descriptorType = m_type; + layout_binding.descriptorCount = m_count; + layout_binding.stageFlags = m_stage_flags; layout_binding.pImmutableSamplers = VK_NULL_HANDLE; return layout_binding; } - /** - * The layout binding is used during pipeline creation to provide information to the pipeline about the descriptor set layout. - * This is used to construct the actual layout and can be done at compiletime. - */ - static constexpr vk::DescriptorSetLayoutBinding m_layout_binding { generateLayoutBinding() }; + vk::DescriptorSetLayoutBinding m_layout_binding { generateLayoutBinding() }; }; - template < std::uint16_t binding_idx, vk::ShaderStageFlags stage_flags > - using ImageDescriptor = Descriptor< binding_idx, vk::DescriptorType::eSampledImage, stage_flags >; - - template < std::uint16_t binding_idx, vk::ShaderStageFlags stage_flags > - using AttachmentDescriptor = Descriptor< binding_idx, vk::DescriptorType::eInputAttachment, stage_flags >; - - template < std::uint16_t binding_idx, vk::ShaderStageFlags stage_flags > - using StorageDescriptor = Descriptor< binding_idx, vk::DescriptorType::eStorageBuffer, stage_flags >; - - template < std::uint16_t binding_idx, vk::ShaderStageFlags stage_flags > - using UniformDescriptor = Descriptor< binding_idx, vk::DescriptorType::eUniformBuffer, stage_flags >; - - template < std::uint16_t idx > - struct EmptyDescriptor + struct ImageDescriptor : Descriptor { - static constexpr std::uint16_t m_binding_idx { idx }; - static constexpr bool is_empty { true }; + ImageDescriptor() = delete; + + constexpr ImageDescriptor( std::uint16_t idx, vk::ShaderStageFlags stage_flags ) : + Descriptor( idx, vk::DescriptorType::eSampledImage, stage_flags ) + {} }; - static_assert( is_empty_descriptor< EmptyDescriptor< 0 > > ); - - //! Returns the maximum binding index for a list of given descriptors - template < is_descriptor Current, is_descriptor... Bindings > - consteval std::uint16_t getMaxDescriptorIDX() + struct AttachmentDescriptor : Descriptor { - if constexpr ( sizeof...( Bindings ) == 0 ) - { - return Current::m_binding_idx; - } - else - { - return std::max( Current::m_binding_idx, getMaxDescriptorIDX< Bindings... >() ); - } - } + AttachmentDescriptor() = delete; + + constexpr AttachmentDescriptor( std::uint16_t idx, vk::ShaderStageFlags stage_flags ) : + Descriptor( idx, vk::DescriptorType::eInputAttachment, stage_flags ) + {} + }; + + struct StorageDescriptor : Descriptor + { + StorageDescriptor() = delete; + + StorageDescriptor( std::uint16_t idx, vk::ShaderStageFlags stage_flags ) : + Descriptor( idx, vk::DescriptorType::eStorageBuffer, stage_flags ) + {} + }; + + struct UniformDescriptor : Descriptor + { + UniformDescriptor() = delete; + + UniformDescriptor( const std::uint16_t idx, vk::ShaderStageFlags stage_flags ) : + Descriptor( idx, vk::DescriptorType::eUniformBuffer, stage_flags ) + {} + }; } // namespace fgl::engine::descriptors diff --git a/src/engine/descriptors/DescriptorPool.cpp b/src/engine/descriptors/DescriptorPool.cpp index 6998b41..9e37337 100644 --- a/src/engine/descriptors/DescriptorPool.cpp +++ b/src/engine/descriptors/DescriptorPool.cpp @@ -30,7 +30,7 @@ namespace fgl::engine::descriptors DescriptorPool::DescriptorPool( std::uint32_t set_count ) : m_pool( createPool( set_count ) ) {} - [[nodiscard]] vk::raii::DescriptorSet DescriptorPool::allocateSet( vk::raii::DescriptorSetLayout& layout ) + [[nodiscard]] vk::raii::DescriptorSet DescriptorPool::allocateSet( const vk::raii::DescriptorSetLayout& layout ) { vk::DescriptorSetAllocateInfo alloc_info {}; alloc_info.setDescriptorPool( m_pool ); diff --git a/src/engine/descriptors/DescriptorPool.hpp b/src/engine/descriptors/DescriptorPool.hpp index 2334f0c..c5b1511 100644 --- a/src/engine/descriptors/DescriptorPool.hpp +++ b/src/engine/descriptors/DescriptorPool.hpp @@ -41,7 +41,7 @@ namespace fgl::engine::descriptors static DescriptorPool& init(); [[nodiscard]] static DescriptorPool& getInstance(); - [[nodiscard]] vk::raii::DescriptorSet allocateSet( vk::raii::DescriptorSetLayout& layout ); + [[nodiscard]] vk::raii::DescriptorSet allocateSet( const vk::raii::DescriptorSetLayout& layout ); }; } // namespace fgl::engine::descriptors diff --git a/src/engine/descriptors/DescriptorSet.cpp b/src/engine/descriptors/DescriptorSet.cpp index 77b9fc1..93f0ee0 100644 --- a/src/engine/descriptors/DescriptorSet.cpp +++ b/src/engine/descriptors/DescriptorSet.cpp @@ -10,24 +10,24 @@ #include #include "DescriptorPool.hpp" -#include "engine/memory/buffers/BufferSuballocation.hpp" #include "engine/assets/image/ImageView.hpp" +#include "engine/memory/buffers/BufferSuballocation.hpp" #include "engine/rendering/SwapChain.hpp" #include "engine/texture/Texture.hpp" namespace fgl::engine::descriptors { - DescriptorSet::DescriptorSet( vk::raii::DescriptorSetLayout&& layout ) : - m_layout( std::forward< vk::raii::DescriptorSetLayout >( layout ) ), - m_set( DescriptorPool::getInstance().allocateSet( m_layout ) ) + DescriptorSet::DescriptorSet( const vk::raii::DescriptorSetLayout& layout, std::uint16_t idx ) : + m_set_idx( idx ), + m_set( DescriptorPool::getInstance().allocateSet( layout ) ) {} DescriptorSet::DescriptorSet( DescriptorSet&& other ) noexcept : + m_set_idx( other.m_set_idx ), m_infos( std::move( other.m_infos ) ), descriptor_writes( std::move( other.descriptor_writes ) ), m_resources( std::move( other.m_resources ) ), - m_layout( std::move( other.m_layout ) ), m_set( std::move( other.m_set ) ), m_max_idx( other.m_max_idx ) { @@ -36,10 +36,10 @@ namespace fgl::engine::descriptors DescriptorSet& DescriptorSet::operator=( DescriptorSet&& other ) noexcept { + m_set_idx = other.m_set_idx; m_infos = std::move( other.m_infos ); descriptor_writes = std::move( other.descriptor_writes ); m_resources = std::move( other.m_resources ); - m_layout = std::move( other.m_layout ); m_set = std::move( other.m_set ); other.m_set = VK_NULL_HANDLE; m_max_idx = other.m_max_idx; diff --git a/src/engine/descriptors/DescriptorSet.hpp b/src/engine/descriptors/DescriptorSet.hpp index b319968..7097161 100644 --- a/src/engine/descriptors/DescriptorSet.hpp +++ b/src/engine/descriptors/DescriptorSet.hpp @@ -28,6 +28,7 @@ namespace fgl::engine::descriptors class DescriptorSet { + std::uint16_t m_set_idx; //TODO: Maybe redo this to not be a monostate variant? std::vector< std::variant< std::monostate, vk::DescriptorImageInfo, vk::DescriptorBufferInfo > > m_infos {}; std::vector< vk::WriteDescriptorSet > descriptor_writes {}; @@ -35,7 +36,6 @@ namespace fgl::engine::descriptors std::vector< std::variant< std::shared_ptr< ImageView >, std::shared_ptr< memory::BufferSuballocation > > > m_resources {}; - vk::raii::DescriptorSetLayout m_layout; vk::raii::DescriptorSet m_set; std::uint32_t m_max_idx { 0 }; @@ -52,8 +52,10 @@ namespace fgl::engine::descriptors VkDescriptorSet getVkDescriptorSet() const { return *m_set; } + inline std::uint16_t setIDX() const { return m_set_idx; } + DescriptorSet() = delete; - DescriptorSet( vk::raii::DescriptorSetLayout&& layout ); + DescriptorSet( const vk::raii::DescriptorSetLayout& layout, const std::uint16_t idx ); //Copy DescriptorSet( const DescriptorSet& other ) = delete; diff --git a/src/engine/descriptors/DescriptorSetCollection.hpp b/src/engine/descriptors/DescriptorSetCollection.hpp deleted file mode 100644 index 5ea73a7..0000000 --- a/src/engine/descriptors/DescriptorSetCollection.hpp +++ /dev/null @@ -1,105 +0,0 @@ -// -// Created by kj16609 on 3/13/24. -// - -#pragma once - -#include "engine/concepts/is_empty_descriptor_set.hpp" -#include "engine/concepts/is_valid_pipeline_input.hpp" -#include "engine/descriptors/createDescriptorSets.hpp" - -namespace fgl::engine::descriptors -{ - - template < is_descriptor_set Current, is_valid_pipeline_input... Sets > - consteval std::uint16_t getMaxBindingSetIDX() - { - if constexpr ( sizeof...( Sets ) == 0 ) - return Current::m_set_idx; - else - { - constexpr auto current_idx { Current::m_set_idx }; - constexpr auto next_idx { getMaxBindingSetIDX< Sets... >() }; - return std::max( current_idx, next_idx ); - } - } - - template < is_constant_range Current, is_valid_pipeline_input... Sets > - consteval std::uint16_t getMaxBindingSetIDX() - { - if constexpr ( sizeof...( Sets ) == 0 ) - return 0; - else - return getMaxBindingSetIDX< Sets... >(); - } - - template < is_valid_pipeline_input... DescriptorSets > - struct DescriptorSetCollection - { - using DescriptorSetTuple = std::tuple< DescriptorSets... >; - static constexpr auto SIZE { sizeof...( DescriptorSets ) }; - - static constexpr std::uint64_t DescriptorSetCount { sizeof...( DescriptorSets ) }; - - //If the first descriptor set is a constant range, then the pipeline has a constant range - static constexpr bool has_constant_range { - is_constant_range< std::tuple_element_t< 0, std::tuple< DescriptorSets... > > > - }; - - static constexpr std::uint16_t binding_sets { ( is_descriptor_set< DescriptorSets > + ... ) }; - - static constexpr std::uint16_t max_binding_set { getMaxBindingSetIDX< DescriptorSets... >() }; - - static constexpr std::uint16_t set_count { ( is_descriptor_set< DescriptorSets > + ... ) }; - - static constexpr std::uint16_t empty_sets { ( is_empty_descriptor_set< DescriptorSets > + ... ) }; - - static std::vector< vk::raii::DescriptorSetLayout > createDescriptorSets() - { - std::vector< vk::raii::DescriptorSetLayout > layouts {}; - layouts.reserve( binding_sets ); - createDescriptorSetsT< DescriptorSets... >( layouts ); - - assert( layouts.size() > 0 ); - assert( layouts.size() == binding_sets ); - - return layouts; - } - - template < std::uint64_t IDX > - requires( IDX < DescriptorSetCount ) - using DescriptorSet = std::tuple_element_t< IDX, DescriptorSetTuple >; - - template < std::uint64_t BindingIDX > - using BindingSet = DescriptorSet< BindingIDX + ( has_constant_range ? 1 : 0 ) >; - - using PushConstantT = BindingSet< 0 >; - }; - - template <> - struct DescriptorSetCollection<> - { - using DescriptorSetTuple = std::tuple< void >; - - static constexpr auto SIZE { 0 }; - - static constexpr std::uint64_t DescriptorSetCount { 0 }; - - //If the first descriptor set is a constant range, then the pipeline has a constant range - static constexpr bool has_constant_range { false }; - - static constexpr std::uint16_t binding_sets { 0 }; - - static constexpr std::uint16_t max_binding_set { 0 }; - - static constexpr std::uint16_t set_count { 0 }; - - static constexpr std::uint16_t empty_sets { 0 }; - - template < std::uint64_t BindingIDX > - using BindingSet = void; - - static std::vector< vk::raii::DescriptorSetLayout > createDescriptorSets() { return {}; } - }; - -} // namespace fgl::engine::descriptors \ No newline at end of file diff --git a/src/engine/descriptors/DescriptorSetLayout.cpp b/src/engine/descriptors/DescriptorSetLayout.cpp new file mode 100644 index 0000000..43eaff0 --- /dev/null +++ b/src/engine/descriptors/DescriptorSetLayout.cpp @@ -0,0 +1,66 @@ +// +// Created by kj16609 on 10/9/24. +// + +#include "DescriptorSetLayout.hpp" + +#include "DescriptorSet.hpp" +#include "engine/debug/logging/logging.hpp" + +namespace fgl::engine::descriptors +{ + + DescriptorSetLayout::DescriptorSetLayout( + const std::uint16_t set_idx, const std::vector< std::reference_wrapper< const Descriptor > >& descriptors ) : + m_set_idx( set_idx ) + { + FGL_ASSERT( descriptors.size() > 0, "Must have more then 1 descriptor set" ); + + for ( const auto& descriptor_w : descriptors ) + { + const auto& descriptor { descriptor_w.get() }; + vk::DescriptorSetLayoutBinding binding {}; + binding.binding = descriptor.m_index; + binding.descriptorType = descriptor.m_type; + binding.descriptorCount = descriptor.m_count; + binding.stageFlags = descriptor.m_stage_flags; + binding.pImmutableSamplers = VK_NULL_HANDLE; + + bindings.emplace_back( binding ); + + flags.emplace_back( descriptor.m_binding_flags ); + } + } + + DescriptorSetLayout::DescriptorSetLayout() : m_set_idx( std::numeric_limits< std::uint16_t >::max() ) + {} + + std::unique_ptr< DescriptorSet > DescriptorSetLayout::create() + { + if ( !m_layout.has_value() ) m_layout = createLayout(); + return std::make_unique< DescriptorSet >( *m_layout, m_set_idx ); + } + + vk::raii::DescriptorSetLayout DescriptorSetLayout::createLayout() const + { + vk::DescriptorSetLayoutBindingFlagsCreateInfo flags_info {}; + flags_info.setBindingFlags( flags ); + + vk::DescriptorSetLayoutCreateInfo info {}; + info.setFlags( vk::DescriptorSetLayoutCreateFlagBits::eUpdateAfterBindPool ); + info.setBindings( bindings ); + info.setPNext( &flags_info ); + + log::debug( "Created layout with as set = {} and {} bindings", m_set_idx, bindings.size() ); + + return Device::getInstance()->createDescriptorSetLayout( info ); + } + + vk::raii::DescriptorSetLayout& DescriptorSetLayout::layout() + { + if ( !m_layout.has_value() ) m_layout = createLayout(); + + return *m_layout; + } + +} // namespace fgl::engine::descriptors diff --git a/src/engine/descriptors/DescriptorSetLayout.hpp b/src/engine/descriptors/DescriptorSetLayout.hpp index fdd6093..864e7ac 100644 --- a/src/engine/descriptors/DescriptorSetLayout.hpp +++ b/src/engine/descriptors/DescriptorSetLayout.hpp @@ -5,185 +5,49 @@ #pragma once #include "Descriptor.hpp" -#include "DescriptorPool.hpp" -#include "engine/concepts/is_descriptor.hpp" -#include "engine/concepts/is_descriptor_set.hpp" -#include "engine/concepts/is_empty_descriptor_set.hpp" -#include "engine/rendering/devices/Device.hpp" +#include "DescriptorSet.hpp" + +namespace fgl::engine +{ + class PipelineBuilder; +} namespace fgl::engine::descriptors { + class DescriptorSet; + struct Descriptor; - template < std::uint16_t set_idx, is_descriptor... Descriptors > - struct DescriptorSetLayout + class DescriptorSetLayout { - static_assert( sizeof...( Descriptors ) > 0, "Binding set must have at least one binding" ); + std::vector< vk::DescriptorSetLayoutBinding > bindings {}; + std::vector< vk::DescriptorBindingFlags > flags {}; - static constexpr std::uint16_t m_set_idx { set_idx }; + std::optional< vk::raii::DescriptorSetLayout > m_layout { std::nullopt }; - //! The number of bindings in this set - static constexpr std::uint16_t descriptor_count { sizeof...( Descriptors ) }; + std::uint16_t m_set_idx; - //! Number of non-empty descriptors - static constexpr std::uint32_t used_descriptor_count { ( is_layout_descriptor< Descriptors > + ... ) }; + DescriptorSetLayout( + std::uint16_t set_idx, const std::vector< std::reference_wrapper< const Descriptor > >& descriptors ); - //! The max binding index in this set - static constexpr std::uint16_t max_binding_idx { getMaxDescriptorIDX< Descriptors... >() }; - - static_assert( - descriptor_count == max_binding_idx + 1, - "Binding count must equal max binding index. (Use EmptyDescriptor for spaces)" ); - - static_assert( - max_binding_idx + 1 == sizeof...( Descriptors ), - "Binding count must equal max binding index. No spaces allowed." ); - - template < std::uint16_t local_idx > - using Binding = std::tuple_element_t< local_idx, std::tuple< Descriptors... > >; - - /** - * @tparam current_idx Current index to extract - * @tparam offset Number to subtract from the current_idx for the array. (Empty bindings are skipped and do not show up in the array) - * @return - */ - template < std::uint16_t current_idx, std::uint16_t offset > - static consteval std::array< vk::DescriptorSetLayoutBinding, used_descriptor_count > extractBinding() - { - if constexpr ( current_idx == descriptor_count ) - { - std::array< vk::DescriptorSetLayoutBinding, used_descriptor_count > data {}; - - for ( std::uint16_t i = 0; i < used_descriptor_count; ++i ) - { - data[ i ] = vk::DescriptorSetLayoutBinding( - std::numeric_limits< std::uint32_t >::max(), - vk::DescriptorType::eUniformBuffer, - 1, - vk::ShaderStageFlagBits::eAll, - nullptr ); - } - - return data; - } - else - { - using Current = Binding< current_idx >; - - if constexpr ( is_empty_descriptor< Current > ) - { - return extractBinding< current_idx + 1, offset + 1 >(); - } - else - { - static_assert( is_layout_descriptor< Current >, "Binding is not a layout descriptor" ); - std::array< vk::DescriptorSetLayoutBinding, used_descriptor_count > data { - extractBinding< current_idx + 1, offset >() - }; - data[ current_idx - offset ] = Current::m_layout_binding; - - return data; - } - } - } - - template < std::uint16_t current_idx, std::uint16_t offset > - static consteval std::array< vk::DescriptorBindingFlags, used_descriptor_count > extractBindingFlags() - { - if constexpr ( current_idx == descriptor_count ) - { - std::array< vk::DescriptorBindingFlags, used_descriptor_count > data; - - for ( std::uint16_t i = 0; i < used_descriptor_count; ++i ) - { - data[ i ] = {}; - } - - return data; - } - else - { - using Current = Binding< current_idx >; - - if constexpr ( is_empty_descriptor< Current > ) - { - return extractBindingFlags< current_idx + 1, offset + 1 >(); - } - else - { - static_assert( is_layout_descriptor< Current >, "Binding is not a layout descriptor" ); - std::array< vk::DescriptorBindingFlags, used_descriptor_count > data { - extractBindingFlags< current_idx + 1, offset >() - }; - - data[ current_idx - offset ] = Current::m_binding_flags; - - return data; - } - } - } - - static consteval std::array< vk::DescriptorSetLayoutBinding, used_descriptor_count > getLayoutBindings() - { - return extractBinding< 0, 0 >(); - } - - static consteval std::array< vk::DescriptorBindingFlags, used_descriptor_count > getLayoutBindingFlags() - { - return extractBindingFlags< 0, 0 >(); - } - - static vk::raii::DescriptorSetLayout createDescriptorSetLayout() - { - static constinit std::array< vk::DescriptorSetLayoutBinding, used_descriptor_count > bindings { - getLayoutBindings() - }; - - static constinit std::array< vk::DescriptorBindingFlags, used_descriptor_count > flags { - getLayoutBindingFlags() - }; - - static_assert( bindings.size() == flags.size(), "Binding did not match it's flags" ); - - static vk::DescriptorSetLayoutBindingFlagsCreateInfo flags_info {}; - flags_info.pBindingFlags = flags.data(); - flags_info.bindingCount = bindings.size(); - - static vk::DescriptorSetLayoutCreateInfo layout_info {}; - layout_info.pNext = VK_NULL_HANDLE; - layout_info.flags = vk::DescriptorSetLayoutCreateFlagBits::eUpdateAfterBindPool; - layout_info.bindingCount = static_cast< std::uint32_t >( bindings.size() ); - layout_info.pBindings = bindings.data(); - layout_info.pNext = &flags_info; - - return Device::getInstance()->createDescriptorSetLayout( layout_info ); - } + DescriptorSetLayout(); public: - DescriptorSetLayout() = delete; + //! Used to make creating an empty set VERY EXPLICIT + inline static DescriptorSetLayout createEmptySet() { return {}; } - static vk::raii::DescriptorSetLayout createLayout() { return createDescriptorSetLayout(); } + friend class ::fgl::engine::PipelineBuilder; + + template < typename... Args > + DescriptorSetLayout( const std::uint16_t set_idx, const Args&... descriptors ) : + DescriptorSetLayout( set_idx, std::vector< std::reference_wrapper< const Descriptor > > { descriptors... } ) + {} + + std::size_t count() const { return bindings.size(); } + + std::unique_ptr< DescriptorSet > create(); + vk::raii::DescriptorSetLayout createLayout() const; + vk::raii::DescriptorSetLayout& layout(); }; - template < std::uint16_t set_idx > - using EmptyDescriptorSet = DescriptorSetLayout< set_idx, EmptyDescriptor< 0 > >; - - namespace internal - { - using TestSet = DescriptorSetLayout< - 0, - ImageDescriptor< 0, vk::ShaderStageFlagBits::eAll >, - EmptyDescriptor< 1 >, - AttachmentDescriptor< 2, vk::ShaderStageFlagBits::eAll >, - UniformDescriptor< 3, vk::ShaderStageFlagBits::eAll >, - EmptyDescriptor< 4 >, - UniformDescriptor< 5, vk::ShaderStageFlagBits::eAll | vk::ShaderStageFlagBits::eVertex >, - UniformDescriptor< 6, vk::ShaderStageFlagBits::eAll > >; - - static_assert( TestSet::descriptor_count == 7 ); - } // namespace internal - - static_assert( is_descriptor_set< EmptyDescriptorSet< 0 > > && is_empty_descriptor_set< EmptyDescriptorSet< 0 > > ); - static_assert( is_descriptor_set< internal::TestSet > && !is_empty_descriptor_set< internal::TestSet > ); - } // namespace fgl::engine::descriptors \ No newline at end of file diff --git a/src/engine/descriptors/createDescriptorSets.hpp b/src/engine/descriptors/createDescriptorSets.hpp deleted file mode 100644 index a338e95..0000000 --- a/src/engine/descriptors/createDescriptorSets.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// -// Created by kj16609 on 3/13/24. -// - -#pragma once - -#include "engine/FGL_DEFINES.hpp" -#include "engine/concepts/is_valid_pipeline_input.hpp" - -namespace fgl::engine::descriptors -{ - - template < is_valid_pipeline_input CurrentSet, is_valid_pipeline_input... Sets > - FGL_FORCE_INLINE inline void createDescriptorSetsT( std::vector< vk::raii::DescriptorSetLayout >& out ) - { - if constexpr ( is_descriptor_set< CurrentSet > ) - { - vk::raii::DescriptorSetLayout layout { CurrentSet::createDescriptorSetLayout() }; - out.emplace_back( std::move( layout ) ); - } - else if constexpr ( is_constant_range< CurrentSet > ) - { - //noop - } - else - { - static_assert( false, "Invalid input" ); - } - - if constexpr ( sizeof...( Sets ) > 0 ) - { - return createDescriptorSetsT< Sets... >( out ); - } - } - -} // namespace fgl::engine::descriptors \ No newline at end of file diff --git a/src/engine/gameobjects/components/drawers.cpp b/src/engine/gameobjects/components/drawers.cpp index f6376d2..47f6fd4 100644 --- a/src/engine/gameobjects/components/drawers.cpp +++ b/src/engine/gameobjects/components/drawers.cpp @@ -4,7 +4,11 @@ #include "drawers.hpp" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Weffc++" +#pragma GCC diagnostic ignored "-Wold-style-cast" #include +#pragma GCC diagnostic pop namespace fgl::engine { diff --git a/src/engine/gameobjects/components/interface/ComponentEditorInterface.cpp b/src/engine/gameobjects/components/interface/ComponentEditorInterface.cpp index ffa606b..5103ba8 100644 --- a/src/engine/gameobjects/components/interface/ComponentEditorInterface.cpp +++ b/src/engine/gameobjects/components/interface/ComponentEditorInterface.cpp @@ -4,7 +4,11 @@ #include "ComponentEditorInterface.hpp" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Weffc++" +#pragma GCC diagnostic ignored "-Wold-style-cast" #include +#pragma GCC diagnostic pop namespace fgl::engine { diff --git a/src/engine/gameobjects/components/interface/GameObjectComponent.cpp b/src/engine/gameobjects/components/interface/GameObjectComponent.cpp index c0ead0a..17c9890 100644 --- a/src/engine/gameobjects/components/interface/GameObjectComponent.cpp +++ b/src/engine/gameobjects/components/interface/GameObjectComponent.cpp @@ -4,7 +4,11 @@ #include "GameObjectComponent.hpp" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Weffc++" +#pragma GCC diagnostic ignored "-Wold-style-cast" #include +#pragma GCC diagnostic pop namespace fgl::engine { diff --git a/src/engine/primitives/Rotation.cpp b/src/engine/primitives/Rotation.cpp index ae90f84..edd978a 100644 --- a/src/engine/primitives/Rotation.cpp +++ b/src/engine/primitives/Rotation.cpp @@ -41,7 +41,7 @@ namespace fgl::engine return q; } - Rotation::Rotation( const float x, const float y, const float z ) : glm::quat( toQuat( x, y, z ) ) + Rotation::Rotation( const float x_i, const float y_i, const float z_i ) : glm::quat( toQuat( x_i, y_i, z_i ) ) {} Rotation::Rotation( const float value ) : Rotation( value, value, value ) diff --git a/src/engine/primitives/Scale.hpp b/src/engine/primitives/Scale.hpp index 9870a33..ee1556d 100644 --- a/src/engine/primitives/Scale.hpp +++ b/src/engine/primitives/Scale.hpp @@ -20,14 +20,14 @@ namespace fgl::engine using glm::vec3::y; using glm::vec3::z; - Scale( const glm::vec3 value ) : glm::vec3( value ) + Scale( const glm::vec3 val ) : glm::vec3( val ) { assert( !std::isnan( x ) ); assert( !std::isnan( y ) ); assert( !std::isnan( z ) ); } - Scale( const float value ) : glm::vec3( value ) {} + Scale( const float val ) : glm::vec3( val ) {} Scale( const float x_i, const float y_i, const float z_i ) : glm::vec3( x_i, y_i, z_i ) {} }; diff --git a/src/engine/primitives/boxes/OrientedBoundingBox.hpp b/src/engine/primitives/boxes/OrientedBoundingBox.hpp index d0cef4a..63a037a 100644 --- a/src/engine/primitives/boxes/OrientedBoundingBox.hpp +++ b/src/engine/primitives/boxes/OrientedBoundingBox.hpp @@ -42,8 +42,8 @@ namespace fgl::engine }; OrientedBoundingBox() : - m_transform( Coordinate< CType >( constants::DEFAULT_VEC3 ) ), - transform_mode( TransformMode::Transform ) + transform_mode( TransformMode::Transform ), + m_transform( Coordinate< CType >( constants::DEFAULT_VEC3 ) ) {} OrientedBoundingBox( const Coordinate< CType > pos, const glm::vec3 inital_scale ) : @@ -76,6 +76,7 @@ namespace fgl::engine case TransformMode::Matrix: return Coordinate< CType >( m_matrix * glm::vec4( -1.0f, -1.0f, -1.0f, 1.0f ) ); } + FGL_UNREACHABLE(); } //! Returns the bottom right (x, y, z) coordinate @@ -88,6 +89,7 @@ namespace fgl::engine case TransformMode::Matrix: return Coordinate< CType >( m_matrix * glm::vec4( 1.0f, 1.0f, 1.0f, 1.0f ) ); } + FGL_UNREACHABLE(); } // 6 sides, 2 triangles each, 3 verts per triangle diff --git a/src/engine/primitives/points/Coordinate.hpp b/src/engine/primitives/points/Coordinate.hpp index c8b9a19..89fe236 100644 --- a/src/engine/primitives/points/Coordinate.hpp +++ b/src/engine/primitives/points/Coordinate.hpp @@ -39,7 +39,7 @@ namespace fgl::engine glm::vec3( i_x, i_y, i_z ) {} - constexpr explicit Coordinate( const float value ) : glm::vec3( value ) {} + constexpr explicit Coordinate( const float val ) : glm::vec3( val ) {} explicit Coordinate( const Vector& vector ); diff --git a/src/engine/primitives/vectors/Vector.hpp b/src/engine/primitives/vectors/Vector.hpp index 018215c..f7a6010 100644 --- a/src/engine/primitives/vectors/Vector.hpp +++ b/src/engine/primitives/vectors/Vector.hpp @@ -36,7 +36,7 @@ namespace fgl::engine constexpr Vector() : glm::vec3( constants::DEFAULT_VEC3 ) {} - constexpr explicit Vector( const float value ) : glm::vec3( value ) {} + constexpr explicit Vector( const float val ) : glm::vec3( val ) {} constexpr explicit Vector( const glm::vec3 i_vec ) : glm::vec3( i_vec ) {} @@ -72,7 +72,6 @@ namespace fgl::engine { return coord - *this; } - }; inline Vector operator-( const Vector vec ) diff --git a/src/engine/rendering/SwapChain.cpp b/src/engine/rendering/SwapChain.cpp index a8aa2b1..d38a347 100644 --- a/src/engine/rendering/SwapChain.cpp +++ b/src/engine/rendering/SwapChain.cpp @@ -64,7 +64,8 @@ namespace fgl::engine for ( PresentIndex i = 0; i < imageCount(); ++i ) { - auto set { std::make_unique< descriptors::DescriptorSet >( GuiInputDescriptorSet::createLayout() ) }; + auto set { gui_descriptor_set.create() }; + //auto set { std::make_unique< descriptors::DescriptorSet >( GuiInputDescriptorSet::createLayout() ) }; set->setMaxIDX( 0 ); diff --git a/src/engine/rendering/devices/Device.cpp b/src/engine/rendering/devices/Device.cpp index ef38faf..7d3013c 100644 --- a/src/engine/rendering/devices/Device.cpp +++ b/src/engine/rendering/devices/Device.cpp @@ -47,12 +47,18 @@ namespace fgl::engine throw std::runtime_error( "drawIndirectFirstInstance not supported by device" ); } + if ( available_features.wideLines != VK_TRUE ) + { + throw std::runtime_error( "wideLines not supported by device" ); + } + //Set enabled features vk::PhysicalDeviceFeatures deviceFeatures = {}; deviceFeatures.samplerAnisotropy = VK_TRUE; deviceFeatures.multiDrawIndirect = VK_TRUE; deviceFeatures.tessellationShader = VK_TRUE; deviceFeatures.drawIndirectFirstInstance = VK_TRUE; + deviceFeatures.wideLines = VK_TRUE; return deviceFeatures; } diff --git a/src/engine/rendering/pipelines/Pipeline.cpp b/src/engine/rendering/pipelines/Pipeline.cpp index c1f6654..a2e753f 100644 --- a/src/engine/rendering/pipelines/Pipeline.cpp +++ b/src/engine/rendering/pipelines/Pipeline.cpp @@ -13,7 +13,7 @@ namespace fgl::engine::internal { vk::raii::Pipeline Pipeline::createGraphicsPipeline( - std::vector< std::unique_ptr< ShaderHandle > >& shaders, + std::vector< std::unique_ptr< Shader > >& shaders, const PipelineConfigInfo& info, const vk::raii::PipelineLayout& layout ) { @@ -66,7 +66,7 @@ namespace fgl::engine::internal Device& device, vk::raii::PipelineLayout layout, PipelineConfigInfo info, - std::vector< std::unique_ptr< ShaderHandle > > shaders ) : + std::vector< std::unique_ptr< Shader > > shaders ) : m_device( device ), m_layout( std::move( layout ) ), m_vk_pipeline( createGraphicsPipeline( shaders, info, m_layout ) ) diff --git a/src/engine/rendering/pipelines/Pipeline.hpp b/src/engine/rendering/pipelines/Pipeline.hpp index d572648..64296ea 100644 --- a/src/engine/rendering/pipelines/Pipeline.hpp +++ b/src/engine/rendering/pipelines/Pipeline.hpp @@ -12,7 +12,7 @@ namespace fgl::engine { class Device; - struct ShaderHandle; + struct Shader; } namespace fgl::engine::internal @@ -29,7 +29,7 @@ namespace fgl::engine::internal vk::ShaderModule m_frag_shader { VK_NULL_HANDLE }; vk::raii::Pipeline createGraphicsPipeline( - std::vector< std::unique_ptr< ShaderHandle > >& shaders, + std::vector< std::unique_ptr< Shader > >& shaders, const PipelineConfigInfo& info, const vk::raii::PipelineLayout& layout ); @@ -39,7 +39,7 @@ namespace fgl::engine::internal Device& device, vk::raii::PipelineLayout layout, PipelineConfigInfo info, - std::vector< std::unique_ptr< ShaderHandle > > shaders ); + std::vector< std::unique_ptr< Shader > > shaders ); Pipeline( const Pipeline& other ) = delete; Pipeline& operator=( const Pipeline& ) = delete; diff --git a/src/engine/rendering/pipelines/PipelineT.hpp b/src/engine/rendering/pipelines/PipelineT.hpp deleted file mode 100644 index a411232..0000000 --- a/src/engine/rendering/pipelines/PipelineT.hpp +++ /dev/null @@ -1,140 +0,0 @@ -// -// Created by kj16609 on 12/7/23. -// - -#pragma once - -#include "Pipeline.hpp" -#include "Shader.hpp" -#include "engine/concepts/is_descriptor_set_collection.hpp" -#include "engine/concepts/is_empty_descriptor_set.hpp" -#include "engine/descriptors/DescriptorSet.hpp" - -namespace fgl::engine -{ - - template < is_shader_collection ShaderCollection, is_descriptor_set_collection DescriptorSetCollection > - class PipelineT : public internal::Pipeline - { - //If the first descriptor set is a constant range, then the pipeline has a constant range - constexpr static bool has_constant_range { DescriptorSetCollection::has_constant_range }; - constexpr static std::uint16_t binding_sets { DescriptorSetCollection::binding_sets }; - constexpr static bool has_binding_sets { binding_sets != 0 }; - - constexpr static std::uint16_t max_binding_set { DescriptorSetCollection::max_binding_set }; - - constexpr static std::uint16_t set_count { DescriptorSetCollection::set_count }; - - constexpr static std::uint16_t empty_sets { DescriptorSetCollection::empty_sets }; - - //! Returns the binding type assocaited with the index - template < std::uint16_t binding_set_idx > - using BindingSet = typename DescriptorSetCollection::template BindingSet< binding_set_idx >; - - static_assert( - set_count == 0 || ( set_count == ( max_binding_set + 1 ) ), - "Binding sets must not have any spaces (Use EmptySet)" ); - - template < std::uint16_t idx > - consteval static std::uint16_t emptyBindingsAfterIDX() - { - if constexpr ( idx == max_binding_set ) - return 0; - else - { - return ( is_empty_descriptor_set< BindingSet< idx > > ? 1 : 0 ) + emptyBindingsAfterIDX< idx + 1 >(); - } - } - - const vk::PushConstantRange* getRange() - { - if constexpr ( has_constant_range ) - { - return &DescriptorSetCollection::template DescriptorSet< 0 >::m_range; - } - else - { - return VK_NULL_HANDLE; - } - } - - template < std::uint16_t start_idx > - consteval static std::uint16_t getConcurrentSetCount() - { - if constexpr ( start_idx > max_binding_set ) - return 0; - else - { - if constexpr ( !is_empty_descriptor_set< BindingSet< start_idx > > ) - return 1 + getConcurrentSetCount< start_idx + 1 >(); - else - return 0; - } - } - - template < std::uint16_t start_idx > - static consteval std::uint16_t emptySetsBeforeIDX() - { - if constexpr ( start_idx == 0 ) - return 0; - else - return emptySetsBeforeIDX< start_idx - 1 >() + is_empty_descriptor_set< BindingSet< start_idx > >; - } - - vk::raii::PipelineLayout createLayout( [[maybe_unused]] Device& device ) - { - const auto layouts { DescriptorSetCollection::createDescriptorSets() }; - std::vector< vk::DescriptorSetLayout > vk_layouts {}; - vk_layouts.reserve( layouts.size() ); - - for ( const vk::raii::DescriptorSetLayout& layout : layouts ) - { - vk_layouts.emplace_back( *layout ); - } - - vk::PipelineLayoutCreateInfo pipeline_layout_info {}; - pipeline_layout_info.setLayoutCount = has_binding_sets ? static_cast< uint32_t >( vk_layouts.size() ) : 0; - pipeline_layout_info.pSetLayouts = has_binding_sets ? vk_layouts.data() : VK_NULL_HANDLE; - pipeline_layout_info.pushConstantRangeCount = has_constant_range ? 1 : 0; - pipeline_layout_info.pPushConstantRanges = has_constant_range ? getRange() : VK_NULL_HANDLE; - - return Device::getInstance()->createPipelineLayout( pipeline_layout_info ); - } - - public: - - void bindDescriptor( - vk::raii::CommandBuffer& cmd_buffer, std::uint16_t set_idx, descriptors::DescriptorSet& descriptor ) - { - const std::vector< vk::DescriptorSet > sets { *descriptor }; - constexpr std::vector< std::uint32_t > dynamic_offsets {}; - - cmd_buffer.bindDescriptorSets( vk::PipelineBindPoint::eGraphics, m_layout, set_idx, sets, dynamic_offsets ); - } - - template < typename TPushData > - void pushConstant( vk::raii::CommandBuffer& cmd_buffer, TPushData& data ) - { - if constexpr ( has_constant_range ) - { - using PushConstantType = typename DescriptorSetCollection::PushConstantT; - static_assert( - std::same_as< TPushData, typename PushConstantType::DataType >, - "Push constant data type mismatch" ); - - PushConstantType::push( cmd_buffer, m_layout, data ); - } - else - assert( "Attempted to push constant to pipeline without push constant range" ); - } - - PipelineT( Device& device, PipelineConfigInfo&& info ) : - Pipeline( - device, - createLayout( device ), - std::forward< PipelineConfigInfo >( info ), - ShaderCollection::loadShaders() ) - {} - }; - -} // namespace fgl::engine \ No newline at end of file diff --git a/src/engine/rendering/pipelines/Shader.cpp b/src/engine/rendering/pipelines/Shader.cpp index 138c606..9d2eb78 100644 --- a/src/engine/rendering/pipelines/Shader.cpp +++ b/src/engine/rendering/pipelines/Shader.cpp @@ -11,7 +11,7 @@ namespace fgl::engine { - std::vector< std::byte > ShaderHandle::loadData( const std::filesystem::path& path ) + std::vector< std::byte > Shader::loadData( const std::filesystem::path& path ) { if ( auto ifs = std::ifstream( path, std::ios::binary | std::ios::ate ); ifs ) { @@ -34,7 +34,7 @@ namespace fgl::engine } } - vk::ShaderModuleCreateInfo ShaderHandle::createModuleInfo() const + vk::ShaderModuleCreateInfo Shader::createModuleInfo() const { vk::ShaderModuleCreateInfo module_info {}; module_info.flags = {}; @@ -44,7 +44,7 @@ namespace fgl::engine return module_info; } - ShaderHandle::ShaderHandle( const std::filesystem::path& path, const vk::PipelineShaderStageCreateInfo& info ) : + Shader::Shader( const std::filesystem::path& path, const vk::PipelineShaderStageCreateInfo& info ) : shader_data( loadData( path ) ), module_create_info( createModuleInfo() ), stage_info( info ), @@ -53,4 +53,20 @@ namespace fgl::engine stage_info.module = shader_module; } + std::shared_ptr< Shader > Shader:: + loadShader( std::filesystem::path path, const vk::ShaderStageFlagBits stage_flags ) + { + std::filesystem::path full_path { std::filesystem::current_path() / path }; + + vk::PipelineShaderStageCreateInfo stage_info {}; + stage_info.stage = stage_flags; + stage_info.flags = {}; + stage_info.pName = "main"; + stage_info.pSpecializationInfo = VK_NULL_HANDLE; + + auto shader { std::make_shared< Shader >( path, stage_info ) }; + + return shader; + } + } // namespace fgl::engine diff --git a/src/engine/rendering/pipelines/Shader.hpp b/src/engine/rendering/pipelines/Shader.hpp index f1e087d..b8c7fde 100644 --- a/src/engine/rendering/pipelines/Shader.hpp +++ b/src/engine/rendering/pipelines/Shader.hpp @@ -12,25 +12,7 @@ namespace fgl::engine { - template < std::size_t N > - requires( N > 0 ) - struct TString - { - using Character = std::string::value_type; - - Character str[ N ]; - - constexpr TString( const char ( &literal )[ N ] ) { std::ranges::copy( literal, str ); } - - consteval operator std::string_view() const noexcept { return std::string_view( str, N - 1 ); } - - operator std::filesystem::path() const noexcept - { - return std::filesystem::path( std::string_view( str, N - 1 ) ); - } - }; - - struct ShaderHandle + struct Shader { std::vector< std::byte > shader_data; vk::ShaderModuleCreateInfo module_create_info; @@ -41,89 +23,27 @@ namespace fgl::engine static std::vector< std::byte > loadData( const std::filesystem::path& ); vk::ShaderModuleCreateInfo createModuleInfo() const; - ShaderHandle( const std::filesystem::path& path, const vk::PipelineShaderStageCreateInfo& info ); + Shader( const std::filesystem::path& path, const vk::PipelineShaderStageCreateInfo& info ); - ShaderHandle( const ShaderHandle& other ) = delete; + Shader( const Shader& other ) = delete; - ShaderHandle& operator=( const ShaderHandle& other ) = delete; + Shader& operator=( const Shader& other ) = delete; - ShaderHandle( ShaderHandle&& other ) = delete; + Shader( Shader&& other ) = delete; - ShaderHandle& operator=( ShaderHandle&& other ) = delete; - }; + Shader& operator=( Shader&& other ) = delete; - vk::ShaderModule loadShaderModule( const std::string_view path ); + static std::shared_ptr< Shader > loadShader( std::filesystem::path path, vk::ShaderStageFlagBits stage_flags ); - template < TString filepath, vk::ShaderStageFlagBits stage_flags > - struct Shader - { - consteval static vk::PipelineShaderStageCreateInfo defaultShaderInfo() + inline static std::shared_ptr< Shader > loadVertex( std::filesystem::path path ) { - vk::PipelineShaderStageCreateInfo info {}; - info.flags = {}; - info.stage = stage_flags; - info.pName = "main"; - info.pSpecializationInfo = nullptr; - - return info; + return loadShader( path, vk::ShaderStageFlagBits::eVertex ); } - static std::unique_ptr< ShaderHandle > load() + inline static std::shared_ptr< Shader > loadFragment( std::filesystem::path path ) { - return std::make_unique< ShaderHandle >( filepath, defaultShaderInfo() ); + return loadShader( path, vk::ShaderStageFlagBits::eFragment ); } - - virtual ~Shader() = default; - }; - - template < TString filepath > - using VertexShaderT = Shader< filepath, vk::ShaderStageFlagBits::eVertex >; - - template < TString filepath > - using FragmentShaderT = Shader< filepath, vk::ShaderStageFlagBits::eFragment >; - - template < TString filepath > - using TesselationControlShaderT = Shader< filepath, vk::ShaderStageFlagBits::eTessellationControl >; - - template < TString filepath > - using TesselationEvaluationShaderT = Shader< filepath, vk::ShaderStageFlagBits::eTessellationEvaluation >; - - template < typename T > - concept is_shader = requires( T t ) { - { - t.defaultShaderInfo() - } -> std::same_as< vk::PipelineShaderStageCreateInfo >; - }; - - template < is_shader... Shaders > - struct ShaderCollection - { - using ShaderTuple = std::tuple< Shaders... >; - - constexpr static std::uint64_t ShaderCount { sizeof...( Shaders ) }; - - template < std::uint64_t IDX > - requires( IDX < ShaderCount ) - using Shader = std::tuple_element_t< IDX, ShaderTuple >; - - static_assert( ShaderCount >= 1, "Shader count must be two, Missing vertex or fragment?" ); - - static std::vector< std::unique_ptr< ShaderHandle > > loadShaders() - { - std::vector< std::unique_ptr< ShaderHandle > > shaders; - - ( ( shaders.push_back( Shaders::load() ) ), ... ); - - return shaders; - } - }; - - template < typename T > - concept is_shader_collection = requires( T t ) { - typename T::ShaderTuple; - { - t.ShaderCount - } -> std::same_as< const std::uint64_t& >; }; } // namespace fgl::engine diff --git a/src/engine/rendering/pipelines/attachments/AttachmentPresets.cpp b/src/engine/rendering/pipelines/attachments/AttachmentPresets.cpp new file mode 100644 index 0000000..fd04f40 --- /dev/null +++ b/src/engine/rendering/pipelines/attachments/AttachmentPresets.cpp @@ -0,0 +1,18 @@ +// +// Created by kj16609 on 10/10/24. +// + +#include "AttachmentPresets.hpp" + +namespace fgl::engine::AttachmentPresets +{ + + void configureForPresent( AttachmentBuilder& builder ) + { + + + + + } + +} // namespace fgl::engine::AttachmentPresets diff --git a/src/engine/rendering/pipelines/attachments/AttachmentPresets.hpp b/src/engine/rendering/pipelines/attachments/AttachmentPresets.hpp new file mode 100644 index 0000000..60610f5 --- /dev/null +++ b/src/engine/rendering/pipelines/attachments/AttachmentPresets.hpp @@ -0,0 +1,15 @@ +// +// Created by kj16609 on 10/10/24. +// + +namespace fgl::engine +{ + class AttachmentBuilder; +} + +namespace fgl::engine::AttachmentPresets +{ + + void configureForPresent( AttachmentBuilder& builder ); + +} diff --git a/src/engine/rendering/pipelines/shaders/Compiler.cpp b/src/engine/rendering/pipelines/shaders/Compiler.cpp index 9060f36..7758c14 100644 --- a/src/engine/rendering/pipelines/shaders/Compiler.cpp +++ b/src/engine/rendering/pipelines/shaders/Compiler.cpp @@ -129,9 +129,6 @@ namespace fgl::engine const auto preprocessed_source { getInstance().PreprocessGlsl( reinterpret_cast< const char* >( input.data() ), input.size(), kind, input_name.data(), options ) }; - log::info( - "Preprocessed source:\n{}", std::string_view( preprocessed_source.begin(), preprocessed_source.end() ) ); - const auto result { getInstance().CompileGlslToSpv( reinterpret_cast< const char* >( input.data() ), input.size(), kind, input_name.data(), options ) }; diff --git a/src/engine/rendering/pipelines/v2/AttachmentBuilder.cpp b/src/engine/rendering/pipelines/v2/AttachmentBuilder.cpp new file mode 100644 index 0000000..a6a49de --- /dev/null +++ b/src/engine/rendering/pipelines/v2/AttachmentBuilder.cpp @@ -0,0 +1,42 @@ +// +// Created by kj16609 on 10/10/24. +// + +#include "AttachmentBuilder.hpp" + +#include "PipelineBuilder.hpp" + +namespace fgl::engine +{ + + AttachmentBuilder::AttachmentBuilder( PipelineBuilder& source ) : parent( source ) + { + // Default + color_blend_config.blendEnable = VK_FALSE; + color_blend_config.srcColorBlendFactor = vk::BlendFactor::eOne; + color_blend_config.dstColorBlendFactor = vk::BlendFactor::eZero; + color_blend_config.colorBlendOp = vk::BlendOp::eAdd; + color_blend_config.srcAlphaBlendFactor = vk::BlendFactor::eOne; + color_blend_config.dstAlphaBlendFactor = vk::BlendFactor::eZero; + color_blend_config.alphaBlendOp = vk::BlendOp::eAdd; + color_blend_config.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG + | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA; + } + + AttachmentBuilder& AttachmentBuilder::enableBlend() + { + color_blend_config.blendEnable = VK_TRUE; + return *this; + } + + void AttachmentBuilder::finish() + { + parent.config.color_blend_attachment.emplace_back( color_blend_config ); + m_finished = true; + } + + AttachmentBuilder::~AttachmentBuilder() + { + FGL_ASSERT( m_finished, "Attachemnt builder not finished!" ); + } +} // namespace fgl::engine diff --git a/src/engine/rendering/pipelines/v2/AttachmentBuilder.hpp b/src/engine/rendering/pipelines/v2/AttachmentBuilder.hpp new file mode 100644 index 0000000..57227e3 --- /dev/null +++ b/src/engine/rendering/pipelines/v2/AttachmentBuilder.hpp @@ -0,0 +1,32 @@ +// +// Created by kj16609 on 10/10/24. +// + +#include "engine/rendering/pipelines/Attachment.hpp" + +namespace fgl::engine +{ + class PipelineBuilder; + + class AttachmentBuilder + { + PipelineBuilder& parent; + bool m_finished { false }; + + AttachmentBuilder( PipelineBuilder& source ); + AttachmentBuilder() = delete; + + friend class PipelineBuilder; + + public: + + vk::PipelineColorBlendAttachmentState color_blend_config {}; + + void finish(); + + AttachmentBuilder& enableBlend(); + + ~AttachmentBuilder(); + }; + +} // namespace fgl::engine diff --git a/src/engine/rendering/pipelines/v2/Pipeline.cpp b/src/engine/rendering/pipelines/v2/Pipeline.cpp new file mode 100644 index 0000000..31729b0 --- /dev/null +++ b/src/engine/rendering/pipelines/v2/Pipeline.cpp @@ -0,0 +1,46 @@ +// +// Created by kj16609 on 10/9/24. +// + +#include "Pipeline.hpp" + +#include "PipelineBuilder.hpp" +#include "engine/descriptors/DescriptorSet.hpp" + +namespace fgl::engine +{ + + Pipeline::Pipeline( vk::raii::Pipeline&& pipeline_in, vk::raii::PipelineLayout&& layout ) : + m_pipeline( std::move( pipeline_in ) ), + m_layout( std::move( layout ) ) + {} + + void Pipeline::bind( vk::raii::CommandBuffer& cmd_buffer ) + { + cmd_buffer.bindPipeline( vk::PipelineBindPoint::eGraphics, m_pipeline ); + } + + void Pipeline::bindDescriptor( + vk::raii::CommandBuffer& command_buffer, std::size_t descriptor_idx, descriptors::DescriptorSet& set ) + { + const std::vector< vk::DescriptorSet > sets { *set }; + constexpr std::vector< std::uint32_t > offsets {}; + + command_buffer.bindDescriptorSets( vk::PipelineBindPoint::eGraphics, m_layout, descriptor_idx, sets, offsets ); + } + + void Pipeline::bindDescriptor( vk::raii::CommandBuffer& comd_buffer, descriptors::DescriptorSet& set ) + { + bindDescriptor( comd_buffer, set.setIDX(), set ); + } + + void Pipeline::setDebugName( const char* str ) + { + vk::DebugUtilsObjectNameInfoEXT info {}; + info.objectType = vk::ObjectType::ePipeline; + info.pObjectName = str; + info.objectHandle = reinterpret_cast< std::uint64_t >( static_cast< VkPipeline >( *this->m_pipeline ) ); + Device::getInstance().setDebugUtilsObjectName( info ); + } + +} // namespace fgl::engine \ No newline at end of file diff --git a/src/engine/rendering/pipelines/v2/Pipeline.hpp b/src/engine/rendering/pipelines/v2/Pipeline.hpp new file mode 100644 index 0000000..dd897d8 --- /dev/null +++ b/src/engine/rendering/pipelines/v2/Pipeline.hpp @@ -0,0 +1,32 @@ +// +// Created by kj16609 on 10/9/24. +// + +#include + +#include "engine/assets/model/Primitive.hpp" +#include "engine/rendering/pipelines/Shader.hpp" + +namespace fgl::engine +{ + + class Pipeline + { + vk::raii::Pipeline m_pipeline; + vk::raii::PipelineLayout m_layout; + + public: + + Pipeline() = delete; + Pipeline( vk::raii::Pipeline&& pipeline, vk::raii::PipelineLayout&& layout ); + + void bind( vk::raii::CommandBuffer& ); + + void bindDescriptor( vk::raii::CommandBuffer&, std::size_t descriptor_idx, descriptors::DescriptorSet& set ); + void bindDescriptor( vk::raii::CommandBuffer& comd_buffer, descriptors::DescriptorSet& set ); + + + void setDebugName( const char* str ); + }; + +} // namespace fgl::engine diff --git a/src/engine/rendering/pipelines/v2/PipelineBuilder.cpp b/src/engine/rendering/pipelines/v2/PipelineBuilder.cpp new file mode 100644 index 0000000..82d7f53 --- /dev/null +++ b/src/engine/rendering/pipelines/v2/PipelineBuilder.cpp @@ -0,0 +1,264 @@ +// +// Created by kj16609 on 10/10/24. +// + +#include "PipelineBuilder.hpp" + +#include "AttachmentBuilder.hpp" +#include "Pipeline.hpp" +#include "engine/descriptors/DescriptorSetLayout.hpp" + +namespace fgl::engine +{ + + PipelineBuilder::PipelineBuilder( vk::raii::RenderPass& renderpass, std::size_t subpass_stage ) : + m_render_pass( renderpass ), + subpass_idx( subpass_stage ) + { + addDynamicState( vk::DynamicState::eViewport ); + addDynamicState( vk::DynamicState::eScissor ); + } + + descriptors::DescriptorSetLayout empty_set_layout { descriptors::DescriptorSetLayout::createEmptySet() }; + + vk::raii::PipelineLayout PipelineBuilder::createLayout() + { + vk::PipelineLayoutCreateInfo info {}; + + std::vector< vk::DescriptorSetLayout > set_layouts {}; + + set_layouts.reserve( descriptor_set_layouts.size() ); + + SetID max_set_idx { 0 }; + + for ( const auto& [ set_idx, _ ] : descriptor_set_layouts ) + { + max_set_idx = std::max( max_set_idx, set_idx ); + } + + // Any sets not used, Should be set to VK_NULL_HANDLE + set_layouts.resize( max_set_idx + 1 ); + + for ( std::size_t i = 0; i < set_layouts.size(); ++i ) + { + auto itter { descriptor_set_layouts.find( i ) }; + if ( itter == descriptor_set_layouts.end() ) + { + // Could not find it. Empty + set_layouts[ i ] = empty_set_layout.layout(); + continue; + } + else + { + set_layouts[ i ] = itter->second; + continue; + } + } + + for ( const auto& [ set_idx, layout ] : descriptor_set_layouts ) + { + log::debug( "{} populated", set_idx ); + set_layouts[ set_idx ] = layout; + } + + info.setSetLayouts( set_layouts ); + + return Device::getInstance()->createPipelineLayout( info ); + } + + void PipelineBuilder:: + addDescriptorSet( const SetID idx, const vk::raii::DescriptorSetLayout& descriptor_set_layout ) + { + FGL_ASSERT( !descriptor_set_layouts.contains( idx ), "Descriptor already set!" ); + log::debug( "Setting descriptor layout for set idx {}", idx ); + descriptor_set_layouts.insert( std::make_pair( idx, *descriptor_set_layout ) ); + } + + void PipelineBuilder::addDescriptorSet( descriptors::DescriptorSetLayout& descriptor ) + { + return addDescriptorSet( descriptor.m_set_idx, descriptor.layout() ); + } + + void PipelineBuilder::addDynamicState( vk::DynamicState dynamic_state ) + { + m_dynamic_state.emplace_back( dynamic_state ); + } + + [[nodiscard]] vk::PipelineColorBlendAttachmentState& PipelineBuilder::Config::addColorAttachment() + { + color_blend_attachment.emplace_back(); + color_blend_info.setAttachments( color_blend_attachment ); + return color_blend_attachment.back(); + } + + PipelineBuilder::Config::Config() + { + viewport_info.viewportCount = 1; + viewport_info.pViewports = nullptr; + viewport_info.scissorCount = 1; + viewport_info.pScissors = nullptr; + + assembly_info.topology = vk::PrimitiveTopology::eTriangleList; + assembly_info.primitiveRestartEnable = VK_FALSE; + + rasterization_info.depthClampEnable = VK_FALSE; + rasterization_info.rasterizerDiscardEnable = VK_FALSE; + rasterization_info.polygonMode = vk::PolygonMode::eFill; + rasterization_info.cullMode = vk::CullModeFlagBits::eBack; + rasterization_info.frontFace = vk::FrontFace::eClockwise; + rasterization_info.depthBiasEnable = VK_FALSE; + rasterization_info.depthBiasConstantFactor = 0.0f; + rasterization_info.depthBiasClamp = 0.0f; + rasterization_info.depthBiasSlopeFactor = 0.0f; + rasterization_info.lineWidth = 1.0f; + + multisample_info.rasterizationSamples = vk::SampleCountFlagBits::e1; + multisample_info.sampleShadingEnable = VK_FALSE; + multisample_info.minSampleShading = 1.0f; + multisample_info.pSampleMask = nullptr; + multisample_info.alphaToCoverageEnable = VK_FALSE; + multisample_info.alphaToOneEnable = VK_FALSE; + + color_blend_info.logicOpEnable = VK_FALSE; + color_blend_info.logicOp = vk::LogicOp::eCopy; + color_blend_info.attachmentCount = 0; + color_blend_info.pAttachments = nullptr; + color_blend_info.blendConstants[ 0 ] = 0.0f; + color_blend_info.blendConstants[ 1 ] = 0.0f; + color_blend_info.blendConstants[ 2 ] = 0.0f; + color_blend_info.blendConstants[ 3 ] = 0.0f; + + depth_stencil_info.depthTestEnable = VK_TRUE; + depth_stencil_info.depthWriteEnable = VK_TRUE; + depth_stencil_info.depthCompareOp = vk::CompareOp::eLess; + depth_stencil_info.depthBoundsTestEnable = VK_FALSE; + depth_stencil_info.stencilTestEnable = VK_FALSE; + //depth_stencil_info.front = {}; + //depth_stencil_info.back = {}; + depth_stencil_info.minDepthBounds = 0.0f; + depth_stencil_info.maxDepthBounds = 1.0f; + + dynamic_state_enables = { vk::DynamicState::eViewport, vk::DynamicState::eScissor }; + dynamic_state_info.setDynamicStates( dynamic_state_enables ); + //info.dynamic_state_info.flags = 0; + } + + void PipelineBuilder::setTopology( vk::PrimitiveTopology primitive_topology ) + { + config.assembly_info.topology = primitive_topology; + } + + void PipelineBuilder::disableVertexInput() + { + vertex_input_descriptions.bindings = {}; + vertex_input_descriptions.attributes = {}; + } + + void PipelineBuilder::disableCulling() + { + config.rasterization_info.cullMode = vk::CullModeFlagBits::eNone; + } + + AttachmentBuilder PipelineBuilder::addAttachment() + { + return { *this }; + } + + AttachmentBuilder PipelineBuilder::addColorAttachment() + { + AttachmentBuilder builder { addAttachment() }; + return builder; + } + + void PipelineBuilder::setBindingDescriptions( const std::vector< vk::VertexInputBindingDescription >& descriptions ) + { + vertex_input_descriptions.bindings = descriptions; + } + + void PipelineBuilder::setAttributeDescriptions( const std::vector< vk::VertexInputAttributeDescription >& + descriptions ) + { + vertex_input_descriptions.attributes = descriptions; + } + + std::unique_ptr< Pipeline > PipelineBuilder::create() + { + // Precheck + { + FGL_ASSERT( shaders.fragment, "Pipeline requires fragment shader" ); + FGL_ASSERT( shaders.vertex, "Pipeline requires vertex shader" ); + } + + vk::raii::PipelineLayout layout { createLayout() }; + + vk::GraphicsPipelineCreateInfo info {}; + info.pNext = VK_NULL_HANDLE; + info.flags = {}; + + m_stages.clear(); + + if ( shaders.vertex ) m_stages.emplace_back( shaders.vertex->stage_info ); + if ( shaders.fragment ) m_stages.emplace_back( shaders.fragment->stage_info ); + + info.setStages( m_stages ); + + vk::PipelineVertexInputStateCreateInfo vertex_input_info {}; + vertex_input_info.pNext = VK_NULL_HANDLE; + vertex_input_info.flags = {}; + vertex_input_info.setVertexBindingDescriptions( vertex_input_descriptions.bindings ); + vertex_input_info.setVertexAttributeDescriptions( vertex_input_descriptions.attributes ); + info.setPVertexInputState( &vertex_input_info ); + + info.pInputAssemblyState = &config.assembly_info; + info.pTessellationState = &config.tesselation_state_info; + info.pViewportState = &config.viewport_info; + info.pRasterizationState = &config.rasterization_info; + info.pMultisampleState = &config.multisample_info; + info.pDepthStencilState = &config.depth_stencil_info; + + config.color_blend_info.setAttachments( config.color_blend_attachment ); + + info.pColorBlendState = &config.color_blend_info; + info.pDynamicState = &config.dynamic_state_info; + + info.layout = layout; + info.renderPass = m_render_pass; + info.subpass = subpass_idx; + + //TODO: Figure out what these do + info.basePipelineHandle = VK_NULL_HANDLE; + info.basePipelineIndex = -1; + + vk::PipelineDynamicStateCreateInfo dynamic_state_create_info {}; + dynamic_state_create_info.setDynamicStates( m_dynamic_state ); + + if ( m_dynamic_state.size() > 0 ) info.setPDynamicState( &dynamic_state_create_info ); + + vk::raii::Pipeline pipeline { Device::getInstance()->createGraphicsPipeline( VK_NULL_HANDLE, info ) }; + + return std::make_unique< Pipeline >( std::move( pipeline ), std::move( layout ) ); + } + + void setGBufferOutputAttachments( PipelineBuilder::Config& config ) + { + // In order for the pipeline to output, We need to ensure that we have enough attachments for the entire gbuffer (3) + + FGL_ASSERT( config.color_blend_attachment.size() == 0, "GBuffer output expected there to be no other outputs" ); + + for ( int i = 0; i < 3; ++i ) + { + auto& color_config { config.addColorAttachment() }; + + color_config.blendEnable = VK_FALSE; + color_config.srcColorBlendFactor = vk::BlendFactor::eOne; + color_config.dstColorBlendFactor = vk::BlendFactor::eZero; + color_config.colorBlendOp = vk::BlendOp::eAdd; + color_config.srcAlphaBlendFactor = vk::BlendFactor::eOne; + color_config.dstAlphaBlendFactor = vk::BlendFactor::eZero; + color_config.alphaBlendOp = vk::BlendOp::eAdd; + color_config.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG + | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA; + } + } + +} // namespace fgl::engine diff --git a/src/engine/rendering/pipelines/v2/PipelineBuilder.hpp b/src/engine/rendering/pipelines/v2/PipelineBuilder.hpp new file mode 100644 index 0000000..1dfd281 --- /dev/null +++ b/src/engine/rendering/pipelines/v2/PipelineBuilder.hpp @@ -0,0 +1,111 @@ +// +// Created by kj16609 on 10/10/24. +// + +#include + +#include +#include + +#include "engine/rendering/pipelines/Shader.hpp" + +namespace fgl::engine +{ + namespace descriptors + { + class DescriptorSetLayout; + class DescriptorSetCollection; + } // namespace descriptors + class AttachmentBuilder; + + class Pipeline; + + class PipelineBuilder + { + vk::raii::RenderPass& m_render_pass; + std::size_t subpass_idx; + + struct + { + std::vector< vk::VertexInputBindingDescription > bindings; + std::vector< vk::VertexInputAttributeDescription > attributes; + } vertex_input_descriptions; + + struct + { + std::shared_ptr< Shader > vertex { nullptr }; + std::shared_ptr< Shader > fragment { nullptr }; + } shaders {}; + + std::vector< vk::PipelineShaderStageCreateInfo > m_stages {}; + std::vector< vk::DynamicState > m_dynamic_state {}; + + using SetID = std::uint32_t; + std::unordered_map< SetID, vk::DescriptorSetLayout > descriptor_set_layouts {}; + + vk::raii::PipelineLayout createLayout(); + + public: + + void addDescriptorSet( SetID idx, const vk::raii::DescriptorSetLayout& descriptor_set_layout ); + void addDescriptorSet( descriptors::DescriptorSetLayout& descriptor ); + void addDynamicState( vk::DynamicState dynamic_state ); + + PipelineBuilder() = delete; + + struct Config + { + vk::PipelineViewportStateCreateInfo viewport_info {}; + vk::PipelineInputAssemblyStateCreateInfo assembly_info {}; + vk::PipelineTessellationStateCreateInfo tesselation_state_info {}; + vk::PipelineTessellationDomainOriginStateCreateInfo tesselation_domain_info {}; + vk::PipelineRasterizationStateCreateInfo rasterization_info {}; + vk::PipelineMultisampleStateCreateInfo multisample_info {}; + + std::vector< vk::PipelineColorBlendAttachmentState > color_blend_attachment {}; + vk::PipelineColorBlendAttachmentState& addColorAttachment(); + + vk::PipelineColorBlendStateCreateInfo color_blend_info {}; + vk::PipelineDepthStencilStateCreateInfo depth_stencil_info {}; + + std::vector< vk::DynamicState > dynamic_state_enables {}; + vk::PipelineDynamicStateCreateInfo dynamic_state_info {}; + + // Default config + Config(); + + } config; + + void setTopology( vk::PrimitiveTopology primitive_topology ); + void disableVertexInput(); + + void disableCulling(); + + [[nodiscard]] AttachmentBuilder addAttachment(); + [[nodiscard]] AttachmentBuilder addColorAttachment(); + + vk::PipelineLayoutCreateInfo layout_info {}; + + void setBindingDescriptions( const std::vector< vk::VertexInputBindingDescription >& descriptions ); + + void setAttributeDescriptions( const std::vector< vk::VertexInputAttributeDescription >& descriptions ); + + PipelineBuilder( vk::raii::RenderPass& renderpass, std::size_t subpass_stage ); + + void setVertexShader( std::shared_ptr< Shader >&& shader ) + { + shaders.vertex = std::forward< std::shared_ptr< Shader > >( shader ); + } + + void setFragmentShader( std::shared_ptr< Shader >&& shader ) + { + shaders.fragment = std::forward< std::shared_ptr< Shader > >( shader ); + } + + std::unique_ptr< Pipeline > create(); + }; + + //! Adds the GBuffer output attachments to the config for the given pipeline + void setGBufferOutputAttachments( PipelineBuilder::Config& config ); + +} // namespace fgl::engine diff --git a/src/engine/systems/CompositionSystem.cpp b/src/engine/systems/CompositionSystem.cpp index 34bb7fc..865fd04 100644 --- a/src/engine/systems/CompositionSystem.cpp +++ b/src/engine/systems/CompositionSystem.cpp @@ -6,19 +6,42 @@ #include +#include "engine/rendering/pipelines/attachments/AttachmentPresets.hpp" +#include "engine/rendering/pipelines/v2/AttachmentBuilder.hpp" +#include "engine/rendering/pipelines/v2/Pipeline.hpp" +#include "engine/rendering/pipelines/v2/PipelineBuilder.hpp" + namespace fgl::engine { CompositionSystem::CompositionSystem( [[maybe_unused]] Device& device, vk::raii::RenderPass& render_pass ) { + /* PipelineConfigInfo composition_info { render_pass }; PipelineConfigInfo::addColorAttachmentConfig( composition_info ); PipelineConfigInfo::disableVertexInput( composition_info ); PipelineConfigInfo::disableCulling( composition_info ); composition_info.subpass = 1; + */ + + constexpr std::size_t SUBPASS { 1 }; + + PipelineBuilder builder { render_pass, SUBPASS }; + + FGL_ASSERT( gbuffer_set.count() == 3, "Aaaa" ); + + builder.addDescriptorSet( gbuffer_set ); + + builder.addColorAttachment().finish(); + + builder.setVertexShader( Shader::loadVertex( "shaders/fullscreen.vert" ) ); + builder.setFragmentShader( Shader::loadFragment( "shaders/composition.frag" ) ); + + builder.disableCulling(); + builder.disableVertexInput(); + + m_composite_pipeline = builder.create(); - m_composite_pipeline = - std::make_unique< CompositionPipeline >( Device::getInstance(), std::move( composition_info ) ); m_composite_pipeline->setDebugName( "Composition pipeline" ); } @@ -30,8 +53,7 @@ namespace fgl::engine m_composite_pipeline->bind( command_buffer ); - m_composite_pipeline - ->bindDescriptor( command_buffer, GBufferDescriptorSet::m_set_idx, info.getGBufferDescriptor() ); + m_composite_pipeline->bindDescriptor( command_buffer, info.getGBufferDescriptor() ); return info.command_buffer; } diff --git a/src/engine/systems/CompositionSystem.hpp b/src/engine/systems/CompositionSystem.hpp index 01dc919..104e982 100644 --- a/src/engine/systems/CompositionSystem.hpp +++ b/src/engine/systems/CompositionSystem.hpp @@ -6,25 +6,16 @@ #include "concepts.hpp" #include "engine/FrameInfo.hpp" -#include "engine/descriptors/DescriptorSetCollection.hpp" -#include "engine/rendering/pipelines/PipelineT.hpp" #include "engine/rendering/pipelines/Shader.hpp" namespace fgl::engine { + class Pipeline; class CompositionSystem { - using DescriptorSets = descriptors::DescriptorSetCollection< GBufferDescriptorSet >; - using VertexShader = VertexShaderT< "shaders/fullscreen.vert" >; - using FragmentShader = FragmentShaderT< "shaders/composition.frag" >; - - using Shaders = ShaderCollection< VertexShader, FragmentShader >; - - using CompositionPipeline = PipelineT< Shaders, DescriptorSets >; - - std::unique_ptr< CompositionPipeline > m_composite_pipeline { nullptr }; + std::unique_ptr< Pipeline > m_composite_pipeline { nullptr }; vk::raii::CommandBuffer& setupSystem( FrameInfo& info ); diff --git a/src/engine/systems/EntityRendererSystem.cpp b/src/engine/systems/EntityRendererSystem.cpp index 6c6af78..0ef07b2 100644 --- a/src/engine/systems/EntityRendererSystem.cpp +++ b/src/engine/systems/EntityRendererSystem.cpp @@ -10,6 +10,9 @@ #include "DrawPair.hpp" #include "engine/camera/Camera.hpp" #include "engine/debug/profiling/counters.hpp" +#include "engine/rendering/pipelines/v2/AttachmentBuilder.hpp" +#include "engine/rendering/pipelines/v2/Pipeline.hpp" +#include "engine/rendering/pipelines/v2/PipelineBuilder.hpp" #include "engine/tree/octtree/OctTreeNode.hpp" namespace fgl::engine @@ -17,25 +20,57 @@ namespace fgl::engine EntityRendererSystem::EntityRendererSystem( Device& device, vk::raii::RenderPass& render_pass ) : m_device( device ) { ZoneScoped; - { - PipelineConfigInfo standard_info { render_pass }; - PipelineConfigInfo::addGBufferAttachmentsConfig( standard_info ); - standard_info.subpass = 0; - m_standard_pipeline = std::make_unique< StandardPipeline >( m_device, std::move( standard_info ) ); + { + // PipelineConfigInfo standard_info { render_pass }; + // PipelineConfigInfo::addGBufferAttachmentsConfig( standard_info ); + + PipelineBuilder builder { render_pass, 0 }; + + builder.addDescriptorSet( camera_descriptor_set ); + + builder.addColorAttachment().finish(); + builder.addColorAttachment().finish(); + builder.addColorAttachment().finish(); + + builder.setFragmentShader( Shader::loadFragment( "shaders/textureless-gbuffer.frag" ) ); + builder.setVertexShader( Shader::loadVertex( "shaders/textureless-gbuffer.vert" ) ); + + builder.setAttributeDescriptions( ModelVertex::getAttributeDescriptions() ); + builder.setBindingDescriptions( ModelVertex::getBindingDescriptions() ); + + m_standard_pipeline = builder.create(); + m_standard_pipeline->setDebugName( "Standard entity pipeline" ); } { - PipelineConfigInfo textured_info { render_pass }; - PipelineConfigInfo::addGBufferAttachmentsConfig( textured_info ); + // PipelineConfigInfo textured_info { render_pass }; + // PipelineConfigInfo::addGBufferAttachmentsConfig( textured_info ); - textured_info.subpass = 0; - m_textured_pipeline = std::make_unique< TexturedPipeline >( m_device, std::move( textured_info ) ); + PipelineBuilder builder { render_pass, 0 }; + + builder.addColorAttachment().finish(); + builder.addColorAttachment().finish(); + builder.addColorAttachment().finish(); + + builder.addDescriptorSet( camera_descriptor_set ); + builder.addDescriptorSet( texture_descriptor_set ); + + builder.setFragmentShader( Shader::loadFragment( "shaders/textured-gbuffer.frag" ) ); + builder.setVertexShader( Shader::loadVertex( "shaders/textured-gbuffer.vert" ) ); + + builder.setAttributeDescriptions( ModelVertex::getAttributeDescriptions() ); + builder.setBindingDescriptions( ModelVertex::getBindingDescriptions() ); + + m_textured_pipeline = builder.create(); m_textured_pipeline->setDebugName( "Textured entity pipeline" ); } } + EntityRendererSystem::~EntityRendererSystem() + {} + vk::raii::CommandBuffer& EntityRendererSystem::setupSystem( const FrameInfo& info ) { auto& command_buffer { info.command_buffer }; @@ -70,8 +105,7 @@ namespace fgl::engine //Bind pipeline m_standard_pipeline->bind( command_buffer ); - m_standard_pipeline - ->bindDescriptor( command_buffer, CameraDescriptorSet::m_set_idx, info.getCameraDescriptor() ); + m_standard_pipeline->bindDescriptor( command_buffer, info.getCameraDescriptor() ); //Get all commands for drawing anything without a texture auto [ draw_commands, model_matricies ] = getDrawCallsFromTree( @@ -116,8 +150,8 @@ namespace fgl::engine // m_textured_pipeline // ->bindDescriptor( command_buffer, CameraDescriptorSet::m_set_idx, info.global_descriptor_set ); - m_textured_pipeline - ->bindDescriptor( command_buffer, TextureDescriptorSet::m_set_idx, Texture::getTextureDescriptorSet() ); + m_standard_pipeline->bindDescriptor( command_buffer, info.getCameraDescriptor() ); + m_textured_pipeline->bindDescriptor( command_buffer, Texture::getTextureDescriptorSet() ); auto [ draw_commands, model_matricies ] = getDrawCallsFromTree( info.game_objects, info.camera->getFrustumBounds(), IS_VISIBLE | IS_ENTITY ); diff --git a/src/engine/systems/EntityRendererSystem.hpp b/src/engine/systems/EntityRendererSystem.hpp index bd1bd88..67884c7 100644 --- a/src/engine/systems/EntityRendererSystem.hpp +++ b/src/engine/systems/EntityRendererSystem.hpp @@ -9,12 +9,12 @@ #include "engine/assets/model/Model.hpp" #include "engine/memory/buffers/vector/HostVector.hpp" #include "engine/rendering/SwapChain.hpp" -#include "engine/rendering/pipelines/PipelineT.hpp" #include "engine/systems/modelRendering/StandardPipeline.hpp" #include "engine/systems/modelRendering/TexturedPipeline.hpp" namespace fgl::engine { + class Pipeline; class Device; namespace memory @@ -29,10 +29,10 @@ namespace fgl::engine Device& m_device; //! Standard pipeline for textureless models - std::unique_ptr< StandardPipeline > m_standard_pipeline {}; + std::unique_ptr< Pipeline > m_standard_pipeline {}; //! Pipeline for basic textured models (Single texture) - std::unique_ptr< TexturedPipeline > m_textured_pipeline {}; + std::unique_ptr< Pipeline > m_textured_pipeline {}; using DrawParameterBufferSuballocation = HostVector< vk::DrawIndexedIndirectCommand >; @@ -55,7 +55,7 @@ namespace fgl::engine void texturedPass( const FrameInfo& info ); EntityRendererSystem( Device& device, vk::raii::RenderPass& render_pass ); - ~EntityRendererSystem() = default; + ~EntityRendererSystem(); EntityRendererSystem( EntityRendererSystem&& other ) = delete; EntityRendererSystem( const EntityRendererSystem& other ) = delete; EntityRendererSystem& operator=( const EntityRendererSystem& other ) = delete; diff --git a/src/engine/systems/GuiSystem.cpp b/src/engine/systems/GuiSystem.cpp index 2a9af6d..7720c8d 100644 --- a/src/engine/systems/GuiSystem.cpp +++ b/src/engine/systems/GuiSystem.cpp @@ -5,6 +5,9 @@ #include "GuiSystem.hpp" #include "engine/FrameInfo.hpp" +#include "engine/rendering/pipelines/v2/AttachmentBuilder.hpp" +#include "engine/rendering/pipelines/v2/Pipeline.hpp" +#include "engine/rendering/pipelines/v2/PipelineBuilder.hpp" namespace fgl::engine { @@ -17,7 +20,21 @@ namespace fgl::engine PipelineConfigInfo::disableCulling( info ); info.subpass = 0; - m_pipeline = std::make_unique< Pipeline >( device, std::move( info ) ); + //descriptors::DescriptorSetCollection descriptors { gui_descriptor_set }; + + PipelineBuilder builder { render_pass, 0 }; + + builder.addDescriptorSet( gui_descriptor_set ); + + builder.setAttributeDescriptions( SimpleVertex::getAttributeDescriptions() ); + builder.setBindingDescriptions( SimpleVertex::getBindingDescriptions() ); + + builder.setVertexShader( Shader::loadVertex( "shaders/fullscreen.vert" ) ); + builder.setFragmentShader( Shader::loadFragment( "shaders/gui-compose.frag" ) ); + + builder.addColorAttachment().finish(); + + m_pipeline = builder.create(); m_pipeline->setDebugName( "Gui Pipeline" ); } diff --git a/src/engine/systems/GuiSystem.hpp b/src/engine/systems/GuiSystem.hpp index 7819fd4..311bb84 100644 --- a/src/engine/systems/GuiSystem.hpp +++ b/src/engine/systems/GuiSystem.hpp @@ -4,13 +4,12 @@ #pragma once #include "engine/FrameInfo.hpp" -#include "engine/descriptors/DescriptorSetCollection.hpp" #include "engine/descriptors/DescriptorSetLayout.hpp" -#include "engine/rendering/pipelines/PipelineT.hpp" #include "engine/rendering/pipelines/Shader.hpp" namespace fgl::engine { + class Pipeline; struct FrameInfo; /** @@ -18,16 +17,8 @@ namespace fgl::engine */ class GuiSystem { - // Attachment 0 will be the composited image - using CompositeDescriptorSets = descriptors::DescriptorSetCollection< GuiInputDescriptorSet >; - using VertexShader = VertexShaderT< "shaders/fullscreen.vert" >; - using FragmentShader = FragmentShaderT< "shaders/gui-compose.frag" >; - - using Shaders = ShaderCollection< VertexShader, FragmentShader >; - using Pipeline = PipelineT< Shaders, CompositeDescriptorSets >; - - std::unique_ptr< Pipeline > m_pipeline { nullptr }; + std::unique_ptr< Pipeline > m_pipeline; //Setup isn't needed for this. So we can just never define this safely. [[maybe_unused]] vk::raii::CommandBuffer& setupSystem( FrameInfo& info ); diff --git a/src/engine/systems/LineDrawer.cpp b/src/engine/systems/LineDrawer.cpp index 3813260..1cebf39 100644 --- a/src/engine/systems/LineDrawer.cpp +++ b/src/engine/systems/LineDrawer.cpp @@ -11,6 +11,8 @@ #include "engine/debug/drawers.hpp" #include "engine/memory/buffers/vector/HostVector.hpp" #include "engine/primitives/points/Coordinate.hpp" +#include "engine/rendering/pipelines/v2/AttachmentBuilder.hpp" +#include "engine/rendering/pipelines/v2/PipelineBuilder.hpp" namespace fgl::engine { @@ -25,13 +27,25 @@ namespace fgl::engine LineDrawer::LineDrawer( Device& device, vk::raii::RenderPass& render_pass ) { - PipelineConfigInfo config { render_pass }; + PipelineBuilder builder { render_pass, 0 }; - PipelineConfigInfo::addGBufferAttachmentsConfig( config ); - PipelineConfigInfo::setVertexInputType( config, Simple ); - PipelineConfigInfo::setLineTopo( config ); + builder.addDescriptorSet( camera_descriptor_set ); - m_pipeline = std::make_unique< LinePipeline >( device, std::move( config ) ); + builder.addColorAttachment().finish(); + builder.addColorAttachment().finish(); + builder.addColorAttachment().finish(); + + builder.setAttributeDescriptions( SimpleVertex::getAttributeDescriptions() ); + builder.setBindingDescriptions( SimpleVertex::getBindingDescriptions() ); + + builder.setTopology( vk::PrimitiveTopology::eLineList ); + + builder.setVertexShader( Shader::loadVertex( "shaders/line.vert" ) ); + builder.setFragmentShader( Shader::loadFragment( "shaders/line.frag" ) ); + + builder.addDynamicState( vk::DynamicState::eLineWidth ); + + m_pipeline = builder.create(); } LineDrawer::~LineDrawer() @@ -42,7 +56,7 @@ namespace fgl::engine auto& command_buffer { info.command_buffer }; m_pipeline->bind( command_buffer ); - m_pipeline->bindDescriptor( command_buffer, CameraDescriptorSet::m_set_idx, info.getCameraDescriptor() ); + m_pipeline->bindDescriptor( command_buffer, info.getCameraDescriptor() ); return command_buffer; } diff --git a/src/engine/systems/LineDrawer.hpp b/src/engine/systems/LineDrawer.hpp index af07b58..43f7d24 100644 --- a/src/engine/systems/LineDrawer.hpp +++ b/src/engine/systems/LineDrawer.hpp @@ -3,12 +3,11 @@ // #pragma once -#include "engine/rendering/pipelines/PipelineT.hpp" -#include "engine/memory/buffers/vector/HostVector.hpp" #include "engine/camera/CameraDescriptor.hpp" #include "engine/descriptors/Descriptor.hpp" -#include "engine/descriptors/DescriptorSetCollection.hpp" +#include "engine/memory/buffers/vector/HostVector.hpp" #include "engine/rendering/SwapChain.hpp" +#include "engine/rendering/pipelines/v2/Pipeline.hpp" namespace fgl::engine { @@ -18,6 +17,8 @@ namespace fgl::engine class LineDrawer { + /* + using VertexShader = VertexShaderT< "shaders/line.vert" >; using FragmentShader = FragmentShaderT< "shaders/line.frag" >; @@ -25,7 +26,10 @@ namespace fgl::engine ShaderCollection< VertexShader, FragmentShader >, descriptors::DescriptorSetCollection< descriptors::EmptyDescriptorSet< 0 >, CameraDescriptorSet > >; - std::unique_ptr< LinePipeline > m_pipeline {}; + */ + + + std::unique_ptr< Pipeline > m_pipeline {}; PerFrameArray< std::unique_ptr< HostVector< VertexLine > > > m_line_vertex_buffer {}; diff --git a/src/engine/systems/TerrainSystem.hpp b/src/engine/systems/TerrainSystem.hpp index 0cd2a9e..2232681 100644 --- a/src/engine/systems/TerrainSystem.hpp +++ b/src/engine/systems/TerrainSystem.hpp @@ -4,12 +4,10 @@ #pragma once -#include "engine/rendering/pipelines/PipelineT.hpp" #include "concepts.hpp" #include "engine/FrameInfo.hpp" #include "engine/memory/buffers/vector/HostVector.hpp" #include "engine/camera/Camera.hpp" -#include "engine/descriptors/DescriptorSetCollection.hpp" #include "engine/assets/model/Model.hpp" #include "engine/rendering/SwapChain.hpp" diff --git a/src/engine/systems/modelRendering/StandardPipeline.hpp b/src/engine/systems/modelRendering/StandardPipeline.hpp index d7eac3f..d71f70d 100644 --- a/src/engine/systems/modelRendering/StandardPipeline.hpp +++ b/src/engine/systems/modelRendering/StandardPipeline.hpp @@ -5,13 +5,12 @@ #pragma once #include "engine/FrameInfo.hpp" #include "engine/camera/CameraDescriptor.hpp" -#include "engine/descriptors/DescriptorSetCollection.hpp" -#include "engine/rendering/pipelines/PipelineT.hpp" #include "engine/rendering/pipelines/Shader.hpp" namespace fgl::engine { + /* using StandardPipelineVertexShader = VertexShaderT< "shaders/textureless-gbuffer.vert" >; using StandardPipelineFragShader = FragmentShaderT< "shaders/textureless-gbuffer.frag" >; using StandardPipelineShaders = ShaderCollection< StandardPipelineVertexShader, StandardPipelineFragShader >; @@ -22,5 +21,6 @@ namespace fgl::engine //! The standard pipeline is used for models without any form of texturing. They instead rely on Vertex coloring. A UV map is **NOT** expected using StandardPipeline = PipelineT< StandardPipelineShaders, StandardPipelineDescriptorSets >; + */ } // namespace fgl::engine diff --git a/src/engine/systems/modelRendering/TexturedPipeline.hpp b/src/engine/systems/modelRendering/TexturedPipeline.hpp index 88ab47f..df4d669 100644 --- a/src/engine/systems/modelRendering/TexturedPipeline.hpp +++ b/src/engine/systems/modelRendering/TexturedPipeline.hpp @@ -4,13 +4,12 @@ #pragma once #include "engine/FrameInfo.hpp" -#include "engine/descriptors/DescriptorSetCollection.hpp" -#include "engine/rendering/pipelines/PipelineT.hpp" #include "engine/rendering/pipelines/Shader.hpp" namespace fgl::engine { + /* using TexturedPipelineVertexShader = VertexShaderT< "shaders/textured-gbuffer.vert" >; using TexturedPipelineFragShader = FragmentShaderT< "shaders/textured-gbuffer.frag" >; using TexturedPipelineShaders = ShaderCollection< TexturedPipelineVertexShader, TexturedPipelineFragShader >; @@ -22,5 +21,6 @@ namespace fgl::engine //! The standard pipeline is used for models without any form of texturing. They instead rely on Vertex coloring. A UV map is **NOT** expected using TexturedPipeline = PipelineT< TexturedPipelineShaders, TexturedPipelineDescriptorSets >; + */ } // namespace fgl::engine diff --git a/src/engine/texture/Texture.cpp b/src/engine/texture/Texture.cpp index 938382e..e7a84b6 100644 --- a/src/engine/texture/Texture.cpp +++ b/src/engine/texture/Texture.cpp @@ -7,11 +7,11 @@ #include #include "engine/FrameInfo.hpp" -#include "engine/assets/transfer/TransferManager.hpp" -#include "engine/descriptors/DescriptorSet.hpp" #include "engine/assets/image/Image.hpp" #include "engine/assets/image/ImageView.hpp" +#include "engine/assets/transfer/TransferManager.hpp" #include "engine/debug/logging/logging.hpp" +#include "engine/descriptors/DescriptorSet.hpp" #include "engine/math/noise/perlin/generator.hpp" #pragma GCC diagnostic push @@ -90,7 +90,7 @@ namespace fgl::engine const ImVec2 imgui_size { static_cast< float >( extent.width ), static_cast< float >( extent.height ) }; - ImGui::Image( static_cast< ImTextureID >( getImGuiDescriptorSet() ), imgui_size ); + ImGui::Image( getImGuiDescriptorSet(), imgui_size ); } bool Texture::drawImGuiButton( vk::Extent2D extent ) @@ -113,7 +113,7 @@ namespace fgl::engine const ImVec2 imgui_size { static_cast< float >( extent.width ), static_cast< float >( extent.height ) }; - return ImGui::ImageButton( static_cast< ImTextureID >( getImGuiDescriptorSet() ), imgui_size ); + return ImGui::ImageButton( m_name.c_str(), getImGuiDescriptorSet(), imgui_size ); } Texture::Texture( std::tuple< std::vector< std::byte >, int, int, vk::Format > tuple ) : @@ -230,23 +230,19 @@ namespace fgl::engine void Texture::setName( const std::string& str ) { - this->getImageView().setName( str ); + m_image->setName( str + " Image" ); + m_image_view->setName( str + " ImageView" ); } descriptors::DescriptorSet& Texture::getTextureDescriptorSet() { static std::unique_ptr< descriptors::DescriptorSet > set { nullptr }; - static std::optional< vk::raii::DescriptorSetLayout > set_layout { std::nullopt }; if ( set ) return *set; else { - set_layout = TextureDescriptorSet::createLayout(); - - if ( !set_layout.has_value() ) throw std::runtime_error( "No set layout made" ); - - set = std::make_unique< descriptors::DescriptorSet >( std::move( set_layout.value() ) ); + set = texture_descriptor_set.create(); set->setMaxIDX( 1 ); set->setName( "Texture descriptor set" ); return *set; diff --git a/src/engine/texture/Texture.hpp b/src/engine/texture/Texture.hpp index e0223d2..e1f4682 100644 --- a/src/engine/texture/Texture.hpp +++ b/src/engine/texture/Texture.hpp @@ -11,8 +11,8 @@ #include "engine/assets/AssetManager.hpp" #include "engine/assets/image/ImageView.hpp" #include "engine/assets/image/Sampler.hpp" -#include "engine/types.hpp" #include "engine/constants.hpp" +#include "engine/types.hpp" namespace fgl::engine { @@ -37,8 +37,6 @@ namespace fgl::engine using TextureStore = AssetStore< Texture >; - - //TODO: Implement texture handle map to avoid loading the same texture multiple times class Texture final : public AssetInterface< Texture > { @@ -61,6 +59,8 @@ namespace fgl::engine //! Descriptor set used for displaying the texture in ImGui vk::DescriptorSet m_imgui_set { VK_NULL_HANDLE }; + std::string m_name; + [[nodiscard]] Texture( std::tuple< std::vector< std::byte >, int, int, vk::Format > ); //! Construct texture with a specific extent and data @@ -101,6 +101,8 @@ namespace fgl::engine [[nodiscard]] TextureID getID() const; void setName( const std::string& str ); + const std::string& getName() const { return m_name; } + [[nodiscard]] vk::DescriptorImageInfo getDescriptor() const; [[nodiscard]] vk::DescriptorSet& getImGuiDescriptorSet();