Finish pipeline rewrite
This commit is contained in:
2
dependencies/imgui
vendored
2
dependencies/imgui
vendored
Submodule dependencies/imgui updated: fdc084f532...b4c96355c9
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ),
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace fgl::engine
|
||||
|
||||
class Sampler
|
||||
{
|
||||
vk::raii::Sampler m_sampler { VK_NULL_HANDLE };
|
||||
vk::raii::Sampler m_sampler;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Weffc++"
|
||||
#include <glm/vec3.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ) );
|
||||
}
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -1,24 +0,0 @@
|
||||
//
|
||||
// Created by kj16609 on 3/13/24.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <vulkan/vulkan_raii.hpp>
|
||||
|
||||
#include <concepts>
|
||||
#include <cstdint>
|
||||
|
||||
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
|
||||
@@ -1,21 +0,0 @@
|
||||
//
|
||||
// Created by kj16609 on 3/13/24.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <concepts>
|
||||
#include <cstdint>
|
||||
|
||||
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
|
||||
@@ -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
|
||||
@@ -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 > >;
|
||||
}
|
||||
@@ -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& >;
|
||||
};
|
||||
}
|
||||
@@ -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 >;
|
||||
}
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 <glm/gtx/quaternion.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
std::format_context::iterator std::formatter< glm::qua< float > >::format( const glm::quat& quat, format_context& ctx )
|
||||
const
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
|
||||
#include "matrix.hpp"
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Weffc++"
|
||||
#pragma GCC diagnostic ignored "-Wduplicated-branches"
|
||||
#include <glm/glm.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
std::format_context::iterator std::formatter< glm::vec4 >::format( const glm::vec4& vec, format_context& ctx ) const
|
||||
{
|
||||
|
||||
@@ -7,85 +7,81 @@
|
||||
#include <cstdint>
|
||||
|
||||
#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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -10,24 +10,24 @@
|
||||
#include <queue>
|
||||
|
||||
#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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
66
src/engine/descriptors/DescriptorSetLayout.cpp
Normal file
66
src/engine/descriptors/DescriptorSetLayout.cpp
Normal file
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -4,7 +4,11 @@
|
||||
|
||||
#include "drawers.hpp"
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Weffc++"
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
#include <imgui.h>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
|
||||
#include "ComponentEditorInterface.hpp"
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Weffc++"
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
#include <imgui.h>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
|
||||
#include "GameObjectComponent.hpp"
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Weffc++"
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
#include <imgui.h>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 ) {}
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 ) )
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<idx>)" );
|
||||
|
||||
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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// Created by kj16609 on 10/10/24.
|
||||
//
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
class AttachmentBuilder;
|
||||
}
|
||||
|
||||
namespace fgl::engine::AttachmentPresets
|
||||
{
|
||||
|
||||
void configureForPresent( AttachmentBuilder& builder );
|
||||
|
||||
}
|
||||
@@ -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 ) };
|
||||
|
||||
|
||||
42
src/engine/rendering/pipelines/v2/AttachmentBuilder.cpp
Normal file
42
src/engine/rendering/pipelines/v2/AttachmentBuilder.cpp
Normal file
@@ -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
|
||||
32
src/engine/rendering/pipelines/v2/AttachmentBuilder.hpp
Normal file
32
src/engine/rendering/pipelines/v2/AttachmentBuilder.hpp
Normal file
@@ -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
|
||||
46
src/engine/rendering/pipelines/v2/Pipeline.cpp
Normal file
46
src/engine/rendering/pipelines/v2/Pipeline.cpp
Normal file
@@ -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
|
||||
32
src/engine/rendering/pipelines/v2/Pipeline.hpp
Normal file
32
src/engine/rendering/pipelines/v2/Pipeline.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// Created by kj16609 on 10/9/24.
|
||||
//
|
||||
|
||||
#include <memory>
|
||||
|
||||
#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
|
||||
264
src/engine/rendering/pipelines/v2/PipelineBuilder.cpp
Normal file
264
src/engine/rendering/pipelines/v2/PipelineBuilder.cpp
Normal file
@@ -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
|
||||
111
src/engine/rendering/pipelines/v2/PipelineBuilder.hpp
Normal file
111
src/engine/rendering/pipelines/v2/PipelineBuilder.hpp
Normal file
@@ -0,0 +1,111 @@
|
||||
//
|
||||
// Created by kj16609 on 10/10/24.
|
||||
//
|
||||
|
||||
#include <vulkan/vulkan_raii.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
|
||||
#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
|
||||
@@ -6,19 +6,42 @@
|
||||
|
||||
#include <engine/texture/Texture.hpp>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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" );
|
||||
}
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {};
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
#include <initializer_list>
|
||||
|
||||
#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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user