Finish GPU driven rendering basics

This commit is contained in:
2025-04-07 13:52:14 -04:00
parent 32953416a2
commit 5a0fc04a46
38 changed files with 197 additions and 169 deletions

View File

@@ -3,6 +3,7 @@
//
#include <cstdlib>
#include "assets/model/builders/SceneBuilder.hpp"
#include "debug/profiling/counters.hpp"
#include "engine/EngineContext.hpp"
#include "engine/camera/CameraManager.hpp"
@@ -52,7 +53,7 @@ int main()
profiling::resetCounters();
} );
engine_ctx.hookEarlyFrame( [ & ]( [[maybe_unused]] FrameInfo& info ) { editor_ctx.draw( info ); } );
engine_ctx.hookLateFrame( [ & ]( [[maybe_unused]] FrameInfo& info ) { editor_ctx.draw( info ); } );
engine_ctx.hookLateFrame( [ & ]( FrameInfo& info ) { editor_ctx.endDraw( info ); } );
// Now we need to create the camera for the editor.
@@ -67,6 +68,32 @@ int main()
constexpr bool playing { false };
{
auto& buffers { getModelBuffers() };
SceneBuilder builder { buffers.m_vertex_buffer, buffers.m_index_buffer };
constexpr std::string_view sponza_path {
"/home/kj16609/Desktop/Projects/cxx/Mecha/src/assets/khronos-sponza/Sponza.gltf"
};
builder.loadScene( sponza_path );
std::vector< GameObject > objs { builder.getGameObjects() };
for ( auto& obj : objs )
{
if ( obj.hasComponent< components::ModelComponent >() )
{
auto model_components { obj.getComponents< components::ModelComponent >() };
for ( auto& component : model_components )
{}
}
engine_ctx.game_objects.emplace_back( std::move( obj ) );
}
}
//! Will be true until the window says it wants to close.
while ( engine_ctx.good() )
{

View File

@@ -70,10 +70,10 @@ namespace fgl::engine
// Memory pool for matrix info and draw parameters
memory::Buffer m_draw_parameter_pool;
std::vector< GameObject > game_objects {};
public:
std::vector< GameObject > game_objects {};
ModelGPUBuffers m_model_buffers {};
private:

View File

@@ -11,15 +11,12 @@ namespace fgl::engine
std::shared_ptr< ImageView > Image::getView( Sampler sampler )
{
if ( !m_view.expired() )
return m_view.lock();
else
{
assert( m_handle );
auto ptr { std::make_shared< ImageView >( m_handle, std::move( sampler ) ) };
m_view = ptr;
return ptr;
}
if ( !m_view.expired() ) return m_view.lock();
assert( m_handle );
auto ptr { std::make_shared< ImageView >( m_handle, std::move( sampler ) ) };
m_view = ptr;
return ptr;
}
constexpr vk::AccessFlags getAccessFlags( const vk::ImageLayout layout )
@@ -29,7 +26,7 @@ namespace fgl::engine
default:
FGL_UNREACHABLE();
case vk::ImageLayout::eUndefined:
return vk::AccessFlags( 0 );
return vk::AccessFlagBits::eNone;
case vk::ImageLayout::eGeneral:
break;
case vk::ImageLayout::eColorAttachmentOptimal:
@@ -56,8 +53,7 @@ namespace fgl::engine
case vk::ImageLayout::eDepthReadOnlyOptimal:
[[fallthrough]];
case vk::ImageLayout::eDepthAttachmentOptimal:
return vk::AccessFlagBits::eDepthStencilAttachmentRead
| vk::AccessFlagBits::eDepthStencilAttachmentWrite;
return vk::AccessFlagBits::eDepthStencilAttachmentWrite;
case vk::ImageLayout::eStencilReadOnlyOptimal:
break;
case vk::ImageLayout::eReadOnlyOptimal:

View File

@@ -26,24 +26,27 @@ namespace fgl::engine
ImageView::ImageView( const std::shared_ptr< ImageHandle >& img ) :
m_resource( img ),
m_descriptor_info(),
m_image_view( createImageView( img ) ),
m_sampler(),
m_name( "Unnamed ImageView" )
{
m_descriptor_info.imageLayout = img->m_final_layout;
m_descriptor_info.imageView = m_image_view;
// m_descriptor_info.imageLayout = img->m_final_layout;
// m_descriptor_info.imageView = m_image_view;
}
ImageView::ImageView( const std::shared_ptr< ImageHandle >& img, Sampler&& sampler ) : ImageView( img )
{
m_sampler = std::move( sampler );
}
ImageView::ImageView( const std::shared_ptr< ImageHandle >& img, Sampler&& sampler ) :
m_resource( img ),
m_image_view( createImageView( img ) ),
m_sampler( std::forward< Sampler >( sampler ) ),
m_name( "Unnamed ImageView" )
{}
vk::DescriptorImageInfo ImageView::descriptorInfo( const vk::Sampler sampler, const vk::ImageLayout layout ) const
{
vk::DescriptorImageInfo info { descriptorInfo( layout ) };
vk::DescriptorImageInfo info {};
info.imageLayout = layout;
info.imageView = m_image_view;
info.sampler = sampler;
return info;
@@ -51,11 +54,7 @@ namespace fgl::engine
vk::DescriptorImageInfo ImageView::descriptorInfo( const vk::ImageLayout layout ) const
{
vk::DescriptorImageInfo info {};
info.imageLayout = layout;
info.imageView = m_image_view;
return info;
return descriptorInfo( *m_sampler, layout );
}
ImageView::~ImageView()

View File

@@ -16,8 +16,6 @@ namespace fgl::engine
{
std::shared_ptr< ImageHandle > m_resource;
vk::DescriptorImageInfo m_descriptor_info;
vk::raii::ImageView m_image_view;
Sampler m_sampler;
@@ -25,6 +23,8 @@ namespace fgl::engine
[[nodiscard]] static vk::raii::ImageView createImageView( const std::shared_ptr< ImageHandle >& img );
[[nodiscard]] vk::DescriptorImageInfo descriptorInfo( vk::Sampler sampler, vk::ImageLayout layout ) const;
public:
//! Returns true if the resource has been staged
@@ -52,7 +52,6 @@ namespace fgl::engine
// void setSampler( Sampler&& sampler ) { m_sampler = std::forward< Sampler >( sampler ); }
[[nodiscard]] const Sampler& getSampler() const { return m_sampler; };
[[nodiscard]] vk::DescriptorImageInfo descriptorInfo( vk::Sampler sampler, vk::ImageLayout layout ) const;
[[nodiscard]] vk::DescriptorImageInfo descriptorInfo( vk::ImageLayout layout ) const;
~ImageView();

View File

@@ -6,6 +6,7 @@
#include <vulkan/vulkan.hpp>
#include "engine/debug/logging/logging.hpp"
#include "engine/rendering/devices/Device.hpp"
namespace fgl::engine
@@ -30,6 +31,13 @@ namespace fgl::engine
info.addressModeV = sampler_wrap_v;
info.addressModeW = sampler_wrap_w;
if ( info.addressModeU == vk::SamplerAddressMode::eClampToBorder
|| info.addressModeV == vk::SamplerAddressMode::eClampToBorder
|| info.addressModeW == vk::SamplerAddressMode::eClampToBorder )
{
info.borderColor = vk::BorderColor::eFloatOpaqueWhite;
}
info.minLod = -1000;
info.maxLod = 1000;
@@ -45,12 +53,12 @@ namespace fgl::engine
const vk::SamplerAddressMode sampler_wrap_u,
const vk::SamplerAddressMode sampler_wrap_v,
const vk::SamplerAddressMode sampler_wrap_w ) :
m_sampler( createSampler( mag_filter, min_filter, mipmap_mode, sampler_wrap_u, sampler_wrap_v, sampler_wrap_w ) )
m_sampler( createSampler( min_filter, mag_filter, mipmap_mode, sampler_wrap_u, sampler_wrap_v, sampler_wrap_w ) )
{}
namespace gl
{
vk::Filter filterToVk( int value )
vk::Filter filterToVk( const int value )
{
switch ( value )
{
@@ -74,13 +82,19 @@ namespace fgl::engine
default:
throw std::runtime_error( "Failed to translate wrapping filter to vk address mode" );
case GL_REPEAT:
log::info( "eRepeat" );
return vk::SamplerAddressMode::eRepeat;
case GL_MIRRORED_REPEAT:
log::info( "eMirroredRepeat" );
return vk::SamplerAddressMode::eMirroredRepeat;
#ifdef GL_CLAMP_TO_BORDER
case GL_CLAMP_TO_BORDER:
log::info( "eClampToBorder" );
return vk::SamplerAddressMode::eClampToBorder;
#endif
#ifdef GL_CLAMP_TO_EDGE
case GL_CLAMP_TO_EDGE:
log::info( "eClampToEdge" );
return vk::SamplerAddressMode::eClampToEdge;
#endif
}

View File

@@ -76,51 +76,66 @@ namespace fgl::engine
using MaterialID = std::uint32_t;
#define PAD( id, size ) std::byte pad_##id[ size ];
//! Material data to be sent to the device
// Alignas to prevent the struct from becoming bigger then needed
struct DeviceMaterialData
{
struct Albedo
alignas( 16 ) struct Albedo
{
TextureID color_texture_id { constants::INVALID_TEXTURE_ID };
PAD( 1, 12 );
glm::vec4 color_factors {};
alignas( 4 * 4 ) glm::vec4 color_factors {};
} color;
struct Metallic
alignas( 16 ) struct Metallic
{
// Padding to shove metallic_texture_id to offset 32
TextureID metallic_texture_id { constants::INVALID_TEXTURE_ID };
alignas( 16 ) TextureID metallic_texture_id { constants::INVALID_TEXTURE_ID };
float metallic_factor { 0.0f };
float roughness_factor { 0.0f };
PAD( 1, 4 );
} metallic;
struct Normal
alignas( 16 ) struct Normal
{
TextureID normal_texture_id { constants::INVALID_TEXTURE_ID };
float normal_tex_scale { 0.0f };
PAD( 1, 8 );
} normal;
struct Occlusion
alignas( 16 ) struct Occlusion
{
TextureID occlusion_texture_id { constants::INVALID_TEXTURE_ID };
float occlusion_tex_strength { 0.0f };
PAD( 1, 8 );
} occlusion;
struct Emissive
alignas( 16 ) struct Emissive
{
TextureID emissive_texture_id { constants::INVALID_TEXTURE_ID };
glm::vec3 emissive_factors { 0.0f, 0.0f, 0.0f };
alignas( 4 * 4 ) glm::vec3 emissive_factors { 0.0f, 0.0f, 0.0f };
} emissive;
DeviceMaterialData() = default;
};
static_assert( offsetof( DeviceMaterialData, color ) == 0 );
static_assert( offsetof( DeviceMaterialData::Albedo, color_texture_id ) == 0 );
static_assert( sizeof( DeviceMaterialData::Albedo::color_texture_id ) == 4 );
static_assert( offsetof( DeviceMaterialData::Albedo, color_factors ) == 16 );
static_assert( sizeof( DeviceMaterialData::Albedo ) == 32 );
static_assert( offsetof( DeviceMaterialData, metallic ) == 32 );
static_assert( offsetof( DeviceMaterialData::Metallic, metallic_texture_id ) == 0 );
static_assert( sizeof( DeviceMaterialData::Metallic::metallic_texture_id ) == 4 );
static_assert( offsetof( DeviceMaterialData::Metallic, metallic_factor ) == 4 );
static_assert( offsetof( DeviceMaterialData::Metallic, roughness_factor ) == 8 );
static_assert( sizeof( DeviceMaterialData::Metallic ) == 16 );
static_assert( offsetof( DeviceMaterialData, emissive ) == 80 );
static_assert( offsetof( DeviceMaterialData::Emissive, emissive_texture_id ) == 0 );
static_assert( sizeof( DeviceMaterialData::Emissive::emissive_texture_id ) == 4 );
static_assert( offsetof( DeviceMaterialData::Emissive, emissive_factors ) == 16 );
static_assert( sizeof( DeviceMaterialData::Emissive ) == 32 );
static_assert( sizeof( DeviceMaterialData ) == 112 );
/*
static_assert( sizeof( DeviceMaterialData ) == 76 );
static_assert( offsetof( DeviceMaterialData, color_factors ) == 16 );

View File

@@ -91,7 +91,12 @@ namespace fgl::engine
std::vector< PrimitiveInstanceInfoIndex > primitive_instances {};
constexpr ModelInstanceInfo model_info {};
WorldTransform transform {};
transform.translation = Coordinate< CoordinateSpace::World >( glm::vec3( 0.0, 0.0, 0.0 ) );
transform.scale = glm::vec3( 0.007 );
transform.rotation = { glm::quat( 1.0, 0.0, 0.0, 0.0 ) };
const ModelInstanceInfo model_info { transform.mat4() };
ModelInstanceInfoIndex model_instance { buffers.m_model_instances.acquire( model_info ) };

View File

@@ -77,7 +77,7 @@ namespace fgl::engine
struct PerVertexInstanceInfo
{
glm::mat4x4 m_model_matrix;
alignas( 4 * 4 ) glm::mat4x4 m_model_matrix;
MaterialID material_id;
};
@@ -87,7 +87,7 @@ namespace fgl::engine
static_assert( offsetof( PerVertexInstanceInfo, material_id ) == 64 );
static_assert( sizeof( MaterialID ) == 4 );
static_assert( sizeof( PerVertexInstanceInfo ) == 64 + 4 );
static_assert( sizeof( PerVertexInstanceInfo ) == 64 + ( 4 * 4 ) );
struct ModelGPUBuffers
{

View File

@@ -2,7 +2,6 @@
// Created by kj16609 on 3/17/25.
//
#pragma once
#include <glm/mat4x4.hpp>
#include <memory>
@@ -13,20 +12,8 @@ namespace fgl::engine
{
class Model;
struct ModelGPUInstance
{
//! Index of the model
std::uint32_t m_model_index;
glm::mat4x4 m_transform;
};
using InstanceIndex = std::uint32_t;
struct ModelMatrixInfo
{
glm::mat4 model_matrix;
};
class ModelInstance
{
std::shared_ptr< Model > m_model;

View File

@@ -9,7 +9,7 @@ namespace fgl::engine
struct ModelInstanceInfo
{
glm::mat4 m_matrix { constants::MAT4_IDENTITY };
glm::mat4 m_matrix { glm::mat4( 0.007 ) };
};
using ModelInstanceInfoIndex = IndexedVector< ModelInstanceInfo >::Index;

View File

@@ -116,7 +116,8 @@ namespace fgl::engine
format )
{}
Texture::Texture( std::vector< std::byte >&& data, const vk::Extent2D extent, Sampler&&, const vk::Format format ) :
Texture::Texture(
std::vector< std::byte >&& data, const vk::Extent2D extent, Sampler&& sampler, const vk::Format format ) :
m_texture_id( texture_id_pool.getID() ),
m_image(
std::make_shared< Image >(
@@ -125,7 +126,7 @@ namespace fgl::engine
vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled,
vk::ImageLayout::eUndefined,
vk::ImageLayout::eShaderReadOnlyOptimal ) ),
m_image_view( m_image->getView() ),
m_image_view( m_image->getView( std::forward< Sampler >( sampler ) ) ),
m_extent( extent ),
m_name( "Default Texture Name" )
{
@@ -211,15 +212,6 @@ namespace fgl::engine
return m_imgui_set;
}
Texture::Texture( const std::shared_ptr< Image >& image, Sampler sampler ) :
m_texture_id( texture_id_pool.getID() ),
m_image( image ),
m_image_view( image->getView( std::move( sampler ) ) ),
//TODO: Figure out how to get extents from images.
m_extent( image->getExtent() ),
m_name( "Default Texture Name" )
{}
Texture::Texture( const std::shared_ptr< Image >& image, Sampler&& sampler ) :
m_texture_id( texture_id_pool.getID() ),
m_image( image ),

View File

@@ -93,7 +93,6 @@ namespace fgl::engine
Texture() = delete;
~Texture();
Texture( const std::shared_ptr< Image >& image, Sampler sampler = Sampler() );
Texture( const std::shared_ptr< Image >& image, Sampler&& sampler );
Image& getImageRef();

View File

@@ -345,7 +345,7 @@ namespace fgl::engine
m_composite_swapchain( std::make_unique< CompositeSwapchain >( m_target_extent ) ),
m_gbuffer_swapchain( std::make_unique< GBufferSwapchain >( m_target_extent ) ),
m_camera_renderer( renderer ),
m_camera_frame_info( buffer, constants::MAX_FRAMES_IN_FLIGHT )
m_camera_frame_info( buffer )
{
FGL_ASSERT( renderer, "Camera renderer is null" );
this->setPerspectiveProjection( m_fov_y, aspectRatio(), constants::NEAR_PLANE, constants::FAR_PLANE );

View File

@@ -100,7 +100,8 @@ namespace fgl::engine
for ( const auto& image : m_buffer.m_target.m_attachment_resources.m_images )
{
m_gbuffer_target.emplace_back( std::make_unique< Texture >( image ) );
Sampler default_sampler {};
m_gbuffer_target.emplace_back( std::make_unique< Texture >( image, std::move( default_sampler ) ) );
}
}

View File

@@ -4,7 +4,6 @@
#include "GBufferRenderer.hpp"
#include "Camera.hpp"
#include "GBufferSwapchain.hpp"
#include "engine/rendering/renderpass/RenderPass.hpp"

View File

@@ -21,12 +21,27 @@ namespace fgl::engine::descriptors
consteval Descriptor() = delete;
private:
[[nodiscard]] constexpr vk::DescriptorSetLayoutBinding generateLayoutBinding() const
{
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 = nullptr;
return layout_binding;
}
public:
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 ) ) :
const vk::DescriptorBindingFlags binding_flags = vk::DescriptorBindingFlags {} ) :
m_index( binding_idx ),
m_type( type ),
m_stage_flags( stage_flags ),
@@ -35,18 +50,9 @@ namespace fgl::engine::descriptors
m_layout_binding( generateLayoutBinding() )
{}
constexpr vk::DescriptorSetLayoutBinding generateLayoutBinding()
{
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;
}
vk::DescriptorSetLayoutBinding m_layout_binding;
virtual ~Descriptor() = default;
};
struct ImageDescriptor : Descriptor
@@ -71,7 +77,7 @@ namespace fgl::engine::descriptors
{
StorageDescriptor() = delete;
StorageDescriptor( std::uint16_t idx, vk::ShaderStageFlags stage_flags ) :
constexpr StorageDescriptor( std::uint16_t idx, vk::ShaderStageFlags stage_flags ) :
Descriptor( idx, vk::DescriptorType::eStorageBuffer, stage_flags )
{}
};
@@ -80,7 +86,7 @@ namespace fgl::engine::descriptors
{
UniformDescriptor() = delete;
UniformDescriptor( const std::uint16_t idx, vk::ShaderStageFlags stage_flags ) :
constexpr UniformDescriptor( const std::uint16_t idx, vk::ShaderStageFlags stage_flags ) :
Descriptor( idx, vk::DescriptorType::eUniformBuffer, stage_flags )
{}
};

View File

@@ -65,7 +65,7 @@ namespace fgl::engine::descriptors
write.dstArrayElement = 0;
write.descriptorCount = 1;
write.descriptorType = vk::DescriptorType::eUniformBuffer;
write.pBufferInfo = &( std::get< vk::DescriptorBufferInfo >( m_infos.data()[ binding_idx ] ) );
write.pBufferInfo = &( std::get< vk::DescriptorBufferInfo >( m_infos[ binding_idx ] ) );
write.pImageInfo = VK_NULL_HANDLE;
write.pTexelBufferView = VK_NULL_HANDLE;
@@ -118,16 +118,13 @@ namespace fgl::engine::descriptors
m_descriptor_writes.push_back( write );
}
void DescriptorSet::bindImage(
const std::uint32_t binding_idx,
const ImageView& view,
const vk::ImageLayout layout,
const vk::raii::Sampler& sampler )
void DescriptorSet::
bindImage( const std::uint32_t binding_idx, const ImageView& view, const vk::ImageLayout layout )
{
assert( binding_idx < m_infos.size() && "Binding index out of range" );
//Store info
m_infos[ binding_idx ] = view.descriptorInfo( sampler, layout );
m_infos[ binding_idx ] = view.descriptorInfo( layout );
vk::WriteDescriptorSet write {};
write.dstSet = m_set;
@@ -155,8 +152,7 @@ namespace fgl::engine::descriptors
Texture& tex { *tex_ptr };
m_infos[ binding_idx ] = tex.getImageView().descriptorInfo(
tex.getImageView().getSampler().getVkSampler(), vk::ImageLayout::eShaderReadOnlyOptimal );
m_infos[ binding_idx ] = tex.getImageView().descriptorInfo( vk::ImageLayout::eShaderReadOnlyOptimal );
vk::WriteDescriptorSet write {};
write.dstSet = m_set;
@@ -187,16 +183,13 @@ namespace fgl::engine::descriptors
m_infos.resize( m_binding_count );
}
void DescriptorSet::bindAttachment(
const std::uint32_t binding_idx,
const ImageView& view,
const vk::ImageLayout layout,
const vk::raii::Sampler& sampler )
void DescriptorSet::
bindAttachment( const std::uint32_t binding_idx, const ImageView& view, const vk::ImageLayout layout )
{
assert( binding_idx < m_infos.size() && "Binding index out of range" );
//Store info
m_infos[ binding_idx ] = view.descriptorInfo( sampler, layout );
m_infos[ binding_idx ] = view.descriptorInfo( layout );
vk::WriteDescriptorSet write {};
write.dstSet = m_set;

View File

@@ -75,11 +75,7 @@ namespace fgl::engine::descriptors
~DescriptorSet();
void bindImage(
std::uint32_t binding_idx,
const ImageView& view,
vk::ImageLayout layout,
const vk::raii::Sampler& sampler = VK_NULL_HANDLE );
void bindImage( std::uint32_t binding_idx, const ImageView& view, vk::ImageLayout layout );
void bindUniformBuffer( std::uint32_t binding_idx, const memory::BufferSuballocation& buffer );
void bindStorageBuffer( std::uint32_t binding_idx, const memory::BufferSuballocation& buffer );
@@ -89,11 +85,7 @@ namespace fgl::engine::descriptors
std::size_t array_idx,
std::size_t item_size );
void bindAttachment(
std::uint32_t binding_idx,
const ImageView& view,
vk::ImageLayout layout,
const vk::raii::Sampler& sampler = VK_NULL_HANDLE );
void bindAttachment( std::uint32_t binding_idx, const ImageView& view, vk::ImageLayout layout );
void bindTexture( std::uint32_t binding_idx, const std::shared_ptr< Texture >& tex_ptr );

View File

@@ -7,6 +7,7 @@
#include "ComponentIDS.hpp"
#include "TransformComponent.hpp"
#include "assets/model/ModelInstance.hpp"
#include "interface/GameObjectComponent.hpp"
namespace fgl::engine
@@ -39,6 +40,15 @@ namespace fgl::engine::components
virtual ~ModelComponent() override
{}
TransformComponent getTransform() const
{
return m_transform;
}
void updateTransform( TransformComponent & transform )
{
m_transform = transform;
}
// Model* operator->();
// const Model* operator->() const;

View File

@@ -3,6 +3,7 @@
//
#pragma once
#include "ComponentIDS.hpp"
#include "assets/model/ModelInstanceInfo.hpp"
#include "interface/GameObjectComponent.hpp"
namespace fgl::engine::components
@@ -11,6 +12,7 @@ namespace fgl::engine::components
COMPONENT_CLASS( TransformComponent, TransformComponentID )
{
WorldTransform m_transform;
std::shared_ptr< ModelInstanceInfoIndex > m_model_instance_info_index;
public:

View File

@@ -33,7 +33,9 @@ namespace fgl::engine::shadows
{
PerFrameArray< std::shared_ptr< Texture > > array {};
for ( std::size_t i = 0; i < array.size(); ++i ) array[ i ] = std::make_shared< Texture >( m_image[ i ] );
Sampler default_sampler {};
for ( std::size_t i = 0; i < array.size(); ++i )
array[ i ] = std::make_shared< Texture >( m_image[ i ], std::move( default_sampler ) );
return array;
}
@@ -47,11 +49,6 @@ namespace fgl::engine::shadows
const Matrix< MatrixType::CameraToScreen > identity { 1.0f };
const Matrix< MatrixType::WorldToScreen > matrix { camera_matrix * identity };
}
ShadowMap::ShadowMap( const vk::Extent2D extent ) :

View File

@@ -30,6 +30,7 @@ namespace fgl::engine
HostSingleT& operator=( T& t )
{
FGL_ASSERT( this->ptr(), "Invalid host pointer for HostSingleT!" );
*static_cast< T* >( this->ptr() ) = t;
flush();

View File

@@ -18,8 +18,9 @@ namespace fgl::engine
public:
PerFrameSuballocation( memory::Buffer& buffer, const std::uint32_t frames_in_flight ) : m_buffer( buffer )
PerFrameSuballocation( memory::Buffer& buffer ) : m_buffer( buffer )
{
constexpr auto frames_in_flight { constants::MAX_FRAMES_IN_FLIGHT };
m_suballocations.reserve( frames_in_flight );
for ( std::uint16_t i = 0; i < frames_in_flight; ++i )
{
@@ -39,11 +40,6 @@ namespace fgl::engine
return *m_suballocations[ index ];
}
void bindForFrame( vk::raii::CommandBuffer& cmd_buffer, std::uint16_t frame_idx )
{
m_suballocations[ frame_idx ].bind( cmd_buffer );
}
};
} // namespace fgl::engine

View File

@@ -7,6 +7,7 @@
#include "BufferVector.hpp"
#include "concepts.hpp"
#include "engine/assets/transfer/TransferManager.hpp"
#include "engine/debug/logging/logging.hpp"
namespace fgl::engine::memory
{
@@ -42,6 +43,9 @@ namespace fgl::engine
DeviceVector( buffer, static_cast< std::uint32_t >( data.size() ) )
{
memory::TransferManager::getInstance().copyToVector< T, DeviceVector< T > >( data, *this );
log::debug(
"Allocated device vector of size: {}, With stride: {} at offset {}", size(), stride(), m_offset );
}
// void resize( const std::size_t new_size ) { BufferVector::resize( new_size ); }

View File

@@ -17,10 +17,6 @@ namespace fgl::engine
{
if ( m_free_indexes.empty() )
{
log::warn(
"IndexedVector had to resize due to limited space. Size: {} Capacity: {}",
this->size(),
this->capacity() );
this->resize( this->size() + 1 );
m_free_indexes.push( this->size() - 1 );
}
@@ -95,10 +91,6 @@ namespace fgl::engine
{
if ( m_free_indexes.empty() )
{
log::warn(
"IndexedVector had to resize due to limited space. Size: {} Capacity: {}",
this->size(),
this->capacity() );
this->resize( this->size() + 1 );
m_free_indexes.push( this->size() - 1 );
}

View File

@@ -35,7 +35,7 @@ namespace fgl::engine
init();
m_render_attachments.m_color.linkImages( m_swap_chain_images );
m_render_attachments.m_color.setName( "PresetnSwapChain::color" );
m_render_attachments.m_color.setName( "PresentSwapChain::color" );
m_render_attachments.m_depth.createResources( imageCount(), getSwapChainExtent() );
m_render_attachments.m_depth.setName( "PresentSwapChain::Depth" );
@@ -178,6 +178,7 @@ namespace fgl::engine
void PresentSwapChain::
transitionImages( const CommandBuffer& command_buffer, const StageID stage_id, const FrameIndex frame_index )
const
{
switch ( stage_id )
{
@@ -196,7 +197,7 @@ namespace fgl::engine
};
command_buffer->pipelineBarrier(
vk::PipelineStageFlagBits::eTopOfPipe,
vk::PipelineStageFlagBits::eBottomOfPipe,
vk::PipelineStageFlagBits::eColorAttachmentOutput
| vk::PipelineStageFlagBits::eEarlyFragmentTests
| vk::PipelineStageFlagBits::eLateFragmentTests,

View File

@@ -104,7 +104,7 @@ namespace fgl::engine
[[nodiscard]] std::pair< vk::Result, PresentIndex > acquireNextImage();
[[nodiscard]] vk::Result submitCommandBuffers( const CommandBuffer& buffers, PresentIndex present_index );
void transitionImages( const CommandBuffer& command_buffer, StageID stage_id, FrameIndex frame_index );
void transitionImages( const CommandBuffer& command_buffer, StageID stage_id, FrameIndex frame_index ) const;
};
template < typename T >

View File

@@ -215,9 +215,9 @@ namespace fgl::engine
// auto& command_buffer { getCurrentCommandbuffer() };
// Get a primary command buffer
const auto primary_cmd {
Device::getInstance().getCmdBufferPool().getCommandBuffer( CommandBufferHandle::Primary )
};
auto primary_cmd { Device::getInstance().getCmdBufferPool().getCommandBuffer( CommandBufferHandle::Primary ) };
primary_cmd.setName( "Primary command buffer" );
vk::CommandBufferBeginInfo begin_info {};
begin_info.pNext = VK_NULL_HANDLE;
@@ -225,13 +225,23 @@ namespace fgl::engine
primary_cmd->begin( begin_info );
buffers.transfer_cb->end();
buffers.transfer_cb.setName( "Transfer Commands" );
buffers.render_cb->end();
buffers.render_cb.setName( "Render Commands" );
buffers.composition_cb->end();
buffers.composition_cb.setName( "Composition Commands" );
buffers.imgui_cb->end();
buffers.imgui_cb.setName( "ImGui Commands" );
// run all secondary command buffers
primary_cmd->executeCommands(
{ *buffers.transfer_cb, *buffers.render_cb, *buffers.composition_cb, *buffers.imgui_cb } );
// { *buffers.transfer_cb, *buffers.render_cb, *buffers.composition_cb, *buffers.imgui_cb } );
{ *buffers.transfer_cb, *buffers.render_cb, *buffers.composition_cb } );
primary_cmd->pipelineBarrier(
vk::PipelineStageFlagBits::eAllCommands, vk::PipelineStageFlagBits::eAllCommands, {}, {}, {}, {} );
primary_cmd->executeCommands( { *buffers.imgui_cb } );
primary_cmd->end();

View File

@@ -107,9 +107,11 @@ namespace fgl::engine
{ .name = CompilerOptionName::Optimization,
.value = { .kind = CompilerOptionValueKind::Int,
.intValue0 = static_cast< int32_t >( SLANG_OPTIMIZATION_LEVEL_NONE ) } },
// .intValue0 = static_cast< int32_t >( SLANG_OPTIMIZATION_LEVEL_HIGH ) } },
{ .name = CompilerOptionName::DebugInformation,
.value = { .kind = CompilerOptionValueKind::Int,
.intValue0 = static_cast< int32_t >( SLANG_DEBUG_INFO_LEVEL_MAXIMAL ) } },
// .intValue0 = static_cast< int32_t >( SLANG_DEBUG_INFO_LEVEL_MINIMAL ) } },
{ .name = CompilerOptionName::EmitSpirvDirectly,
.value = { .kind = CompilerOptionValueKind::Int, .intValue0 = static_cast< int32_t >( true ) } },
} };

View File

@@ -39,6 +39,7 @@ namespace fgl::engine
catch ( std::runtime_error& e )
{
log::warn( "Failed to recompile pipeline! Shader error!" );
m_pipeline = VK_NULL_HANDLE;
}
}
@@ -58,9 +59,9 @@ namespace fgl::engine
command_buffer->bindDescriptorSets( m_bind_point, m_layout, descriptor_idx, sets, offsets );
}
void Pipeline::bindDescriptor( CommandBuffer& comd_buffer, descriptors::DescriptorSet& set )
void Pipeline::bindDescriptor( CommandBuffer& cmd_buffer, descriptors::DescriptorSet& set )
{
bindDescriptor( comd_buffer, set.setIDX(), set );
bindDescriptor( cmd_buffer, set.setIDX(), set );
}
void Pipeline::setDebugName( const char* str )

View File

@@ -37,7 +37,7 @@ namespace fgl::engine
void bindDescriptor(
CommandBuffer&, descriptors::DescriptorIDX descriptor_idx, descriptors::DescriptorSet& set );
void bindDescriptor( CommandBuffer& comd_buffer, descriptors::DescriptorSet& set );
void bindDescriptor( CommandBuffer& cmd_buffer, descriptors::DescriptorSet& set );
void setDebugName( const char* str );

View File

@@ -30,6 +30,7 @@ namespace fgl::engine
builder.setFragmentShader( Shader::loadFragment( "shaders/gui-compose.slang" ) );
builder.addColorAttachment().setFormat( pickPresentFormat() ).finish();
builder.addDepthAttachment();
m_pipeline = builder.create();
m_pipeline->setDebugName( "Gui Pipeline" );

View File

@@ -85,7 +85,8 @@ namespace fgl::engine
command_buffer->pipelineBarrier(
vk::PipelineStageFlagBits::eComputeShader, // Source: Compute shader
vk::PipelineStageFlagBits::eDrawIndirect | // Destination: Indirect drawing
vk::PipelineStageFlagBits::eVertexInput, // ... and vertex input
vk::PipelineStageFlagBits::eVertexInput
| vk::PipelineStageFlagBits::eFragmentShader, // ... and vertex input
{}, // Dependency flags
{ memory_barrier }, // Memory barrier for synchronization
{}, // No buffer barrier

View File

@@ -38,6 +38,8 @@ namespace fgl::engine
builder.setAttributeDescriptions( ModelVertex::getAttributeDescriptions() );
builder.setBindingDescriptions( ModelVertex::getBindingDescriptions() );
builder.addDepthAttachment();
m_textured_pipeline = builder.create();
m_textured_pipeline->setDebugName( "Textured entity pipeline" );
}

View File

@@ -6,9 +6,6 @@
#include <memory>
#include "assets/model/ModelInstance.hpp"
#include "engine/assets/model/Model.hpp"
#include "engine/memory/buffers/vector/HostVector.hpp"
#include "engine/rendering/PresentSwapChain.hpp"
namespace fgl::engine
@@ -32,24 +29,11 @@ namespace fgl::engine
std::unique_ptr< Pipeline > m_textured_pipeline;
// std::unique_ptr< ComputePipeline > m_cull_pipeline {};
using DrawParameterBufferSuballocation = HostVector< vk::DrawIndexedIndirectCommand >;
using ModelMatrixInfoBufferSuballocation = HostVector< ModelMatrixInfo >;
// Simple parameter buffers
PerFrameArray< std::unique_ptr< DrawParameterBufferSuballocation > > m_draw_simple_parameter_buffers {};
PerFrameArray< std::unique_ptr< ModelMatrixInfoBufferSuballocation > > m_simple_model_matrix_info_buffers {};
// Textured parameter buffers
PerFrameArray< std::unique_ptr< DrawParameterBufferSuballocation > > m_draw_textured_parameter_buffers {};
PerFrameArray< std::unique_ptr< ModelMatrixInfoBufferSuballocation > > m_textured_model_matrix_info_buffers {};
CommandBuffer& setupSystem( const FrameInfo& );
public:
void pass( FrameInfo& info );
void texturelessPass( const FrameInfo& info );
void texturedPass( const FrameInfo& info );
EntityRendererSystem();

View File

@@ -20,7 +20,7 @@ StructuredBuffer< PrimitiveRenderInfo > primitives : PRIMITIVES;
[[vk::binding(0,1)]]
StructuredBuffer< PrimitiveInstanceInfo > primitive_instances : PRIMITIVE_INSTANCES;
[ [ vk::binding( 1, 1 ) ] ]
[[vk::binding(1,1)]]
StructuredBuffer< ModelInstanceInfo > model_instances : MODEL_INSTANCES;
// out
@@ -28,8 +28,8 @@ StructuredBuffer< ModelInstanceInfo > model_instances : MODEL_INSTANCES;
RWStructuredBuffer< vk::DrawIndexedIndirectCommand > commands : COMMANDS;
// vertex info generated from compute shader. This information is used in the rendering process
[ [ vk::binding( 1, 2 ) ] ]
RWStructuredBuffer< InstanceRenderInfo, ScalarDataLayout > out_instances : OUT_INSTANCES;
[[vk::binding(1,2)]]
RWStructuredBuffer< InstanceRenderInfo > out_instances : OUT_INSTANCES;
//TODO: shader command constants
struct PushConstants