Work on switching to dynamic rendering

This commit is contained in:
2024-12-21 23:42:05 -05:00
parent 66c270d3c6
commit 615e994bd5
23 changed files with 612 additions and 235 deletions

View File

@@ -1 +1,4 @@
find_package(Vulkan REQUIRED)
find_package(Vulkan REQUIRED)
if (NOT Vulkan_FOUND)
error("Vulkan not found")
endif ()

View File

@@ -15,6 +15,26 @@ int main()
log::set_level( spdlog::level::debug );
const auto version { vk::enumerateInstanceVersion() };
// variant 3 bit int, bits 31-29
// major 7-bit, bits 28-22
// minor, 10 bit, 21-12
// patch, 12 bit, 10-0
// clang-format off
constexpr std::uint64_t PATCH_BITMASK { 0b00000000000000000000111111111111 };
constexpr std::uint64_t MINOR_BITMASK { 0b00000000001111111111000000000000 };
constexpr std::uint64_t MAJOR_BITMASK { 0b00011111110000000000000000000000 };
constexpr std::uint64_t VARIANT_BITMASK { 0b11100000000000000000000000000000 };
const auto patch { ( version & PATCH_BITMASK ) >> 0};
const auto minor { ( version & MINOR_BITMASK ) >> 10};
const auto major { ( version & MAJOR_BITMASK ) >> (10 + 12)};
const auto variant { ( version & VARIANT_BITMASK ) >> (10 + 12 + 7) };
// clang-format on
log::debug( "Vulkan instance version: {}.{}.{}.{}", major, minor, patch, minor );
EngineContext engine_ctx {};
// We start by hooking into the imgui rendering.

View File

@@ -48,6 +48,7 @@ namespace fgl::engine
memory::TransferManager::createInstance( device, 128_MiB );
m_matrix_info_pool.setDebugName( "Matrix info pool" );
m_draw_parameter_pool.setDebugName( "Draw parameter pool" );

View File

@@ -21,43 +21,43 @@ namespace fgl::engine
//XYZ in world space
auto position { builder.attachment( POSITION_INDEX ) };
position.setFormat( vk::Format::eR16G16B16A16Sfloat ); // position
position.setFormat( pickPositionFormat() ); // position
position.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal );
position.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore );
//RGBA
auto normal { builder.attachment( NORMAL_INDEX ) };
normal.setFormat( vk::Format::eR16G16B16A16Sfloat ); // normal
normal.setFormat( pickNormalFormat() ); // normal
normal.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal );
normal.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore );
// RGBA
auto color { builder.attachment( COLOR_INDEX ) };
color.setFormat( vk::Format::eR8G8B8A8Unorm ); // color
color.setFormat( pickColorFormat() ); // color
color.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal );
color.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore );
// Metallic, Roughness, Occlusion
auto metallic_roughness { builder.attachment( METALLIC_INDEX ) };
metallic_roughness.setFormat( vk::Format::eR16G16B16A16Sfloat );
metallic_roughness.setFormat( pickMetallicFormat() );
metallic_roughness.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal );
metallic_roughness.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore );
// RGB
auto emissive { builder.attachment( EMISSIVE_INDEX ) };
emissive.setFormat( vk::Format::eR16G16B16A16Sfloat );
emissive.setFormat( pickEmissiveFormat() );
emissive.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal );
emissive.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore );
auto composite { builder.attachment( COMPOSITE_INDEX ) };
//TODO: For HDR I think this needs to be a bigger range then 8bits per channel.
composite.setFormat( vk::Format::eR8G8B8A8Unorm ); // composite
composite.setFormat( pickCompositeFormat() ); // composite
composite.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal );
composite.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore );
auto depth { builder.attachment( DEPTH_INDEX ) };
depth.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eDepthStencilReadOnlyOptimal );
depth.setFormat( SwapChain::findDepthFormat() ); // depth
depth.setFormat( pickDepthFormat() ); // depth
depth.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore );
auto& g_buffer_subpass { builder.createSubpass( 0 ) };
@@ -124,14 +124,20 @@ namespace fgl::engine
void CameraRenderer::beginRenderPass(
const vk::raii::CommandBuffer& command_buffer, CameraSwapchain& swapchain, const FrameIndex index )
{
const vk::RenderingInfo info { swapchain.getRenderingInfo( index ) };
command_buffer.beginRendering( info );
/*
vk::RenderPassBeginInfo info {};
info.renderPass = m_renderpass;
info.framebuffer = swapchain.getFramebuffer( index );
info.renderArea = { .offset = { 0, 0 }, .extent = swapchain.getExtent() };
info.setClearValues( swapchain.getClearValues() );
*/
command_buffer.beginRenderPass( info, vk::SubpassContents::eInline );
// command_buffer.beginRenderPass( info, vk::SubpassContents::eInline );
setViewport( command_buffer, swapchain.getExtent() );
setScissor( command_buffer, swapchain.getExtent() );
@@ -139,7 +145,8 @@ namespace fgl::engine
void CameraRenderer::endRenderPass( const vk::raii::CommandBuffer& command_buffer )
{
command_buffer.endRenderPass();
command_buffer.endRendering();
// command_buffer.endRenderPass();
}
void CameraRenderer::pass( FrameInfo& frame_info, CameraSwapchain& camera_swapchain )
@@ -149,8 +156,12 @@ namespace fgl::engine
auto& command_buffer { frame_info.command_buffer };
camera_swapchain.transitionImages( command_buffer, CameraSwapchain::INITAL, frame_info.frame_idx );
beginRenderPass( command_buffer, camera_swapchain, frame_info.frame_idx );
// Transition the gbuffer to it's inital state
m_culling_system.wait();
//m_terrain_system.pass( frame_info );
@@ -158,9 +169,9 @@ namespace fgl::engine
m_entity_renderer.pass( frame_info );
m_line_drawer.pass( frame_info );
m_composition_system.pass( frame_info );
endRenderPass( command_buffer );
m_composition_system.pass( frame_info );
}
vk::raii::RenderPass& CameraRenderer::getRenderpass()

View File

@@ -37,6 +37,124 @@ namespace fgl::engine
return data;
}
vk::ImageMemoryBarrier createColorImageBarrier(
const Image& image,
const vk::ImageLayout old_layout,
const vk::ImageLayout new_layout,
const vk::AccessFlags flags )
{
vk::ImageMemoryBarrier barrier {};
barrier.setImage( image.getVkImage() );
barrier.setOldLayout( old_layout );
barrier.setNewLayout( new_layout );
barrier.setSrcAccessMask( flags );
constexpr vk::ImageSubresourceRange subresource { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 };
barrier.setSubresourceRange( subresource );
return barrier;
}
vk::ImageMemoryBarrier createDepthImageBarrier(
const Image& image, const vk::ImageLayout old_layout, const vk::ImageLayout new_layout )
{
vk::ImageMemoryBarrier barrier {};
barrier.setImage( image.getVkImage() );
barrier.setOldLayout( old_layout );
barrier.setNewLayout( new_layout );
constexpr vk::ImageSubresourceRange subresource {
vk::ImageAspectFlagBits::eDepth, 0, 1, 0, 1,
};
barrier.setSubresourceRange( subresource );
return barrier;
}
void CameraSwapchain::transitionImages(
vk::raii::CommandBuffer& command_buffer, const std::uint16_t stage_id, const FrameIndex index )
{
switch ( stage_id )
{
default:
throw std::invalid_argument( "Invalid Stage ID" );
case INITAL:
{
const std::vector< vk::ImageMemoryBarrier > barriers {
createColorImageBarrier(
m_gbuffer.m_color.getImage( index ),
vk::ImageLayout::eUndefined,
vk::ImageLayout::eColorAttachmentOptimal,
vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead ),
createColorImageBarrier(
m_gbuffer.m_emissive.getImage( index ),
vk::ImageLayout::eUndefined,
vk::ImageLayout::eColorAttachmentOptimal,
vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead ),
createColorImageBarrier(
m_gbuffer.m_metallic.getImage( index ),
vk::ImageLayout::eUndefined,
vk::ImageLayout::eColorAttachmentOptimal,
vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead ),
createColorImageBarrier(
m_gbuffer.m_position.getImage( index ),
vk::ImageLayout::eUndefined,
vk::ImageLayout::eColorAttachmentOptimal,
vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead ),
createDepthImageBarrier(
m_gbuffer.m_depth.getImage( index ),
vk::ImageLayout::eUndefined,
vk::ImageLayout::eDepthStencilAttachmentOptimal )
};
command_buffer.pipelineBarrier(
vk::PipelineStageFlagBits::eColorAttachmentOutput,
vk::PipelineStageFlagBits::eBottomOfPipe,
vk::DependencyFlags( 0 ),
{},
{},
barriers );
return;
}
case FINAL:
{
return;
}
}
}
vk::RenderingInfo CameraSwapchain::getRenderingInfo( const FrameIndex frame_index )
{
// This should be safe to have as static as the information used here will only capable of being used in a single frame.
static thread_local std::vector< vk::RenderingAttachmentInfo > color_attachment_infos {};
static thread_local vk::RenderingAttachmentInfo depth_attachment_infos {};
depth_attachment_infos = m_gbuffer.m_depth.renderInfo( frame_index, vk::ImageLayout::eDepthAttachmentOptimal );
color_attachment_infos.clear();
color_attachment_infos = {
m_gbuffer.m_color.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ),
m_gbuffer.m_position.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ),
m_gbuffer.m_normal.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ),
m_gbuffer.m_metallic.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ),
m_gbuffer.m_emissive.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal )
};
vk::RenderingInfo rendering_info {};
rendering_info.setRenderArea( { { 0, 0 }, m_extent } );
rendering_info.setLayerCount( 1 );
rendering_info.setColorAttachments( color_attachment_infos );
rendering_info.setPDepthAttachment( &depth_attachment_infos );
// rendering_info.setPStencilAttachment( &depth_attachment_infos );
return rendering_info;
}
const std::vector< vk::ClearValue >& CameraSwapchain::getClearValues()
{
assert( !m_clear_values.empty() );
@@ -81,9 +199,9 @@ namespace fgl::engine
buffers.emplace_back( Device::getInstance()->createFramebuffer( info ) );
m_g_buffer_color_img.emplace_back( std::make_unique< Texture >( m_gbuffer.m_color.m_attachment_resources
.m_images[ i ]
->setName( "GBufferColor" ) ) );
m_g_buffer_color_img.emplace_back(
std::make_unique< Texture >( m_gbuffer.m_color.m_attachment_resources.m_images[ i ]
->setName( "GBufferColor" ) ) );
auto& position_resources { m_gbuffer.m_position.m_attachment_resources };
assert( position_resources.m_images[ i ] );
@@ -92,21 +210,21 @@ namespace fgl::engine
position_image.setName( format_ns::format( "GBufferPosition: {}", i ) );
m_g_buffer_position_img.emplace_back( std::make_unique< Texture >( position_image ) );
m_g_buffer_normal_img.emplace_back( std::make_unique< Texture >( m_gbuffer.m_normal.m_attachment_resources
.m_images[ i ]
->setName( "GBufferNormal" ) ) );
m_g_buffer_normal_img.emplace_back(
std::make_unique< Texture >( m_gbuffer.m_normal.m_attachment_resources.m_images[ i ]
->setName( "GBufferNormal" ) ) );
m_g_buffer_metallic_img.emplace_back( std::make_unique< Texture >( m_gbuffer.m_metallic.m_attachment_resources
.m_images[ i ]
->setName( "GBufferMetallic" ) ) );
m_g_buffer_metallic_img.emplace_back(
std::make_unique< Texture >( m_gbuffer.m_metallic.m_attachment_resources.m_images[ i ]
->setName( "GBufferMetallic" ) ) );
m_g_buffer_emissive_img.emplace_back( std::make_unique< Texture >( m_gbuffer.m_emissive.m_attachment_resources
.m_images[ i ]
->setName( "GBufferEmissive" ) ) );
m_g_buffer_emissive_img.emplace_back(
std::make_unique< Texture >( m_gbuffer.m_emissive.m_attachment_resources.m_images[ i ]
->setName( "GBufferEmissive" ) ) );
m_g_buffer_composite_img.emplace_back( std::make_unique< Texture >( m_gbuffer.m_composite.m_attachment_resources
.m_images[ i ]
->setName( "GBufferComposite" ) ) );
m_g_buffer_composite_img.emplace_back(
std::make_unique< Texture >( m_gbuffer.m_composite.m_attachment_resources.m_images[ i ]
->setName( "GBufferComposite" ) ) );
}
return buffers;

View File

@@ -5,6 +5,7 @@
#pragma once
#include "engine/descriptors/DescriptorSet.hpp"
#include "engine/rendering/RenderingFormats.hpp"
#include "engine/rendering/SwapChain.hpp"
#include "engine/rendering/pipelines/Attachment.hpp"
@@ -24,14 +25,14 @@ namespace fgl::engine
{
struct
{
ColorAttachment< COLOR_INDEX > m_color { vk::Format::eR8G8B8A8Unorm };
ColorAttachment< POSITION_INDEX > m_position { vk::Format::eR16G16B16A16Sfloat };
ColorAttachment< NORMAL_INDEX > m_normal { vk::Format::eR16G16B16A16Sfloat };
ColorAttachment< METALLIC_INDEX > m_metallic { vk::Format::eR16G16B16A16Sfloat };
ColorAttachment< EMISSIVE_INDEX > m_emissive { vk::Format::eR16G16B16A16Sfloat };
ColorAttachment< COLOR_INDEX > m_color { pickColorFormat() };
ColorAttachment< POSITION_INDEX > m_position { pickPositionFormat() };
ColorAttachment< NORMAL_INDEX > m_normal { pickNormalFormat() };
ColorAttachment< METALLIC_INDEX > m_metallic { pickMetallicFormat() };
ColorAttachment< EMISSIVE_INDEX > m_emissive { pickEmissiveFormat() };
ColorAttachment< COMPOSITE_INDEX > m_composite { vk::Format::eR8G8B8A8Unorm };
DepthAttachment< DEPTH_INDEX > m_depth { SwapChain::findDepthFormat() };
ColorAttachment< COMPOSITE_INDEX > m_composite { pickCompositeFormat() };
DepthAttachment< DEPTH_INDEX > m_depth { pickDepthFormat() };
} m_gbuffer {};
public:
@@ -60,6 +61,15 @@ namespace fgl::engine
public:
enum StageID : std::uint16_t
{
INITAL = 0,
FINAL = std::numeric_limits< std::uint16_t >::max()
};
void transitionImages( vk::raii::CommandBuffer& command_buffer, std::uint16_t stage_id, FrameIndex index );
vk::RenderingInfo getRenderingInfo( const FrameIndex frame_index );
CameraSwapchain( vk::raii::RenderPass& renderpass, vk::Extent2D extent );
~CameraSwapchain();

View File

@@ -99,7 +99,7 @@ namespace fgl::engine
info.pEngineName = "titor";
info.engineVersion = VK_MAKE_VERSION( 1, 0, 0 );
info.apiVersion = VK_API_VERSION_1_3;
info.apiVersion = VK_API_VERSION_1_4;
return info;
}
@@ -165,8 +165,10 @@ namespace fgl::engine
if ( ENABLE_VALIDATION_LAYERS )
{
extensions.push_back( VK_EXT_DEBUG_UTILS_EXTENSION_NAME );
log::info( "Validation layers enabled" );
}
return extensions;
}
@@ -231,40 +233,41 @@ namespace fgl::engine
log::info( "Validation disabled. Skipping debug messenger" );
return;
}
log::info( "Setting up debug messenger" );
pfnVkCreateDebugUtilsMessengerEXT = reinterpret_cast<
PFN_vkCreateDebugUtilsMessengerEXT >( m_instance.getProcAddr( "vkCreateDebugUtilsMessengerEXT" ) );
pfnVkDestroyDebugUtilsMessengerEXT = reinterpret_cast<
PFN_vkDestroyDebugUtilsMessengerEXT >( m_instance.getProcAddr( "vkDestroyDebugUtilsMessengerEXT" ) );
pfnVkSetDebugUtilsObjectNameEXT =
reinterpret_cast< PFN_vkSetDebugUtilsObjectNameEXT >( m_instance
.getProcAddr( "vkSetDebugUtilsObjectNameEXT" ) );
if ( !pfnVkCreateDebugUtilsMessengerEXT || !pfnVkDestroyDebugUtilsMessengerEXT )
else
{
log::critical(
"Failed to load create/destroy messenger functions pfnVkCreateDebugUtilsMessengerEXT/pfnVkDestroyDebugUtilsMessengerEXT" );
throw std::runtime_error( "failed to load debug messenger functions!" );
log::info( "Setting up debug messenger" );
pfnVkCreateDebugUtilsMessengerEXT = reinterpret_cast<
PFN_vkCreateDebugUtilsMessengerEXT >( m_instance.getProcAddr( "vkCreateDebugUtilsMessengerEXT" ) );
pfnVkDestroyDebugUtilsMessengerEXT = reinterpret_cast<
PFN_vkDestroyDebugUtilsMessengerEXT >( m_instance.getProcAddr( "vkDestroyDebugUtilsMessengerEXT" ) );
pfnVkSetDebugUtilsObjectNameEXT = reinterpret_cast<
PFN_vkSetDebugUtilsObjectNameEXT >( m_instance.getProcAddr( "vkSetDebugUtilsObjectNameEXT" ) );
if ( !pfnVkCreateDebugUtilsMessengerEXT || !pfnVkDestroyDebugUtilsMessengerEXT )
{
log::critical(
"Failed to load create/destroy messenger functions pfnVkCreateDebugUtilsMessengerEXT/pfnVkDestroyDebugUtilsMessengerEXT" );
throw std::runtime_error( "failed to load debug messenger functions!" );
}
if ( !pfnVkSetDebugUtilsObjectNameEXT )
{
log::critical( "Failed to load debug object naming function: pfnVkSetDebugUtilsObjectNameEXT" );
throw std::runtime_error( "failed to load debug object name function!" );
}
if ( CreateDebugUtilsMessengerEXT( m_instance, m_debug_info, nullptr, &m_debug_messenger )
!= vk::Result::eSuccess )
{
throw std::runtime_error( "failed to set up debug messenger!" );
}
//Setup some glfw error callbacks
glfwSetErrorCallback( &glfwCallback );
log::info( "Debug callback setup" );
}
if ( !pfnVkSetDebugUtilsObjectNameEXT )
{
log::critical( "Failed to load debug object naming function: pfnVkSetDebugUtilsObjectNameEXT" );
throw std::runtime_error( "failed to load debug object name function!" );
}
if ( CreateDebugUtilsMessengerEXT( m_instance, m_debug_info, nullptr, &m_debug_messenger )
!= vk::Result::eSuccess )
{
throw std::runtime_error( "failed to set up debug messenger!" );
}
//Setup some glfw error callbacks
glfwSetErrorCallback( &glfwCallback );
log::info( "Debug callback setup" );
}
Instance::Instance( vk::raii::Context& ctx ) :

View File

@@ -0,0 +1,70 @@
//
// Created by kj16609 on 12/9/24.
//
#include "RenderingFormats.hpp"
#include "devices/Device.hpp"
namespace fgl::engine
{
vk::Format pickColorFormat()
{
static std::vector< vk::Format > formats { vk::Format::eR8G8B8A8Unorm };
return Device::getInstance()
.findSupportedFormat( formats, vk::ImageTiling::eOptimal, vk::FormatFeatureFlagBits::eSampledImage );
}
vk::Format pickPositionFormat()
{
static std::vector< vk::Format > formats { vk::Format::eR16G16B16A16Sfloat };
return Device::getInstance()
.findSupportedFormat( formats, vk::ImageTiling::eOptimal, vk::FormatFeatureFlagBits::eSampledImage );
}
vk::Format pickNormalFormat()
{
static std::vector< vk::Format > formats { vk::Format::eR16G16B16A16Sfloat };
return Device::getInstance()
.findSupportedFormat( formats, vk::ImageTiling::eOptimal, vk::FormatFeatureFlagBits::eSampledImage );
}
vk::Format pickDepthFormat()
{
static std::vector< vk::Format > formats { vk::Format::eD32Sfloat,
vk::Format::eD32SfloatS8Uint,
vk::Format::eD24UnormS8Uint };
return Device::getInstance().findSupportedFormat(
formats, vk::ImageTiling::eOptimal, vk::FormatFeatureFlagBits::eDepthStencilAttachment );
}
vk::Format pickMetallicFormat()
{
static std::vector< vk::Format > formats { vk::Format::eR16G16B16A16Sfloat };
return Device::getInstance()
.findSupportedFormat( formats, vk::ImageTiling::eOptimal, vk::FormatFeatureFlagBits::eSampledImage );
}
vk::Format pickEmissiveFormat()
{
static std::vector< vk::Format > formats { vk::Format::eR16G16B16A16Sfloat };
return Device::getInstance()
.findSupportedFormat( formats, vk::ImageTiling::eOptimal, vk::FormatFeatureFlagBits::eSampledImage );
}
vk::Format pickCompositeFormat()
{
static std::vector< vk::Format > formats { vk::Format::eR8G8B8A8Unorm };
return Device::getInstance()
.findSupportedFormat( formats, vk::ImageTiling::eOptimal, vk::FormatFeatureFlagBits::eSampledImage );
}
} // namespace fgl::engine

View File

@@ -0,0 +1,18 @@
//
// Created by kj16609 on 12/9/24.
//
#pragma once
#include <vulkan/vulkan.hpp>
namespace fgl::engine
{
vk::Format pickColorFormat();
vk::Format pickPositionFormat();
vk::Format pickNormalFormat();
vk::Format pickDepthFormat();
vk::Format pickMetallicFormat();
vk::Format pickEmissiveFormat();
vk::Format pickCompositeFormat();
} // namespace fgl::engine

View File

@@ -7,6 +7,7 @@
#include <limits>
#include <stdexcept>
#include "RenderingFormats.hpp"
#include "engine/assets/transfer/TransferManager.hpp"
#include "engine/descriptors/DescriptorSet.hpp"
#include "pipelines/Attachment.hpp"
@@ -21,11 +22,11 @@ namespace fgl::engine
m_present_mode( chooseSwapPresentMode( m_swapchain_details.presentModes ) ),
m_swapchain_extent( extent ),
m_swap_chain_format( m_surface_format.format ),
m_swap_chain_depth_format( findDepthFormat() ),
m_swap_chain_depth_format( pickDepthFormat() ),
old_swap_chain( nullptr ),
m_swapchain( createSwapChain() ),
m_swap_chain_images( createSwapchainImages() ),
render_attachments( getSwapChainImageFormat(), findDepthFormat() ),
render_attachments( getSwapChainImageFormat(), pickDepthFormat() ),
m_render_pass( createRenderPass() ),
m_swap_chain_buffers( createFramebuffers() ),
// m_input_descriptors( createInputDescriptors() ),
@@ -43,11 +44,11 @@ namespace fgl::engine
m_present_mode( chooseSwapPresentMode( m_swapchain_details.presentModes ) ),
m_swapchain_extent( extent ),
m_swap_chain_format( m_surface_format.format ),
m_swap_chain_depth_format( findDepthFormat() ),
m_swap_chain_depth_format( pickDepthFormat() ),
old_swap_chain( previous ),
m_swapchain( createSwapChain() ),
m_swap_chain_images( createSwapchainImages() ),
render_attachments( getSwapChainImageFormat(), findDepthFormat() ),
render_attachments( getSwapChainImageFormat(), m_swap_chain_depth_format ),
m_render_pass( createRenderPass() ),
m_swap_chain_buffers( createFramebuffers() ),
// m_input_descriptors( createInputDescriptors() ),
@@ -257,7 +258,7 @@ namespace fgl::engine
auto depth { builder.attachment( DepthIndex ) };
depth.setFormat( SwapChain::findDepthFormat() );
depth.setFormat( pickDepthFormat() );
depth.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eDepthStencilAttachmentOptimal );
depth.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eDontCare );
@@ -345,8 +346,8 @@ namespace fgl::engine
}
}
vk::SurfaceFormatKHR SwapChain::chooseSwapSurfaceFormat( const std::vector< vk::SurfaceFormatKHR >&
available_formats )
vk::SurfaceFormatKHR SwapChain::
chooseSwapSurfaceFormat( const std::vector< vk::SurfaceFormatKHR >& available_formats )
{
ZoneScoped;
for ( const auto& format : available_formats )
@@ -455,13 +456,4 @@ namespace fgl::engine
return static_cast< float >( m_swapchain_extent.width ) / static_cast< float >( m_swapchain_extent.height );
}
vk::Format SwapChain::findDepthFormat()
{
ZoneScoped;
return Device::getInstance().findSupportedFormat(
{ vk::Format::eD32Sfloat, vk::Format::eD32SfloatS8Uint, vk::Format::eD24UnormS8Uint },
vk::ImageTiling::eOptimal,
vk::FormatFeatureFlagBits::eDepthStencilAttachment );
}
} // namespace fgl::engine

View File

@@ -104,8 +104,6 @@ namespace fgl::engine
float extentAspectRatio() const;
static vk::Format findDepthFormat();
[[nodiscard]] std::pair< vk::Result, PresentIndex > acquireNextImage();
[[nodiscard]] vk::Result
submitCommandBuffers( const vk::raii::CommandBuffer& buffers, PresentIndex present_index );

View File

@@ -8,7 +8,6 @@
#include <cstring>
#include <iostream>
#include <set>
#include <unordered_set>
#include "engine/debug/logging/logging.hpp"
@@ -63,20 +62,23 @@ namespace fgl::engine
return deviceFeatures;
}
vk::PhysicalDeviceDescriptorIndexingFeatures Device::DeviceCreateInfo::getIndexingFeatures()
void Device::DeviceCreateInfo::getIndexingFeatures()
{
vk::PhysicalDeviceDescriptorIndexingFeatures indexing_features {};
indexing_features.setRuntimeDescriptorArray( VK_TRUE );
indexing_features.setDescriptorBindingPartiallyBound( VK_TRUE );
indexing_features.setShaderSampledImageArrayNonUniformIndexing( VK_TRUE );
indexing_features.setDescriptorBindingSampledImageUpdateAfterBind( VK_TRUE );
indexing_features.setDescriptorBindingUniformBufferUpdateAfterBind( VK_TRUE );
return indexing_features;
m_indexing_features.setRuntimeDescriptorArray( VK_TRUE );
m_indexing_features.setDescriptorBindingPartiallyBound( VK_TRUE );
m_indexing_features.setShaderSampledImageArrayNonUniformIndexing( VK_TRUE );
m_indexing_features.setDescriptorBindingSampledImageUpdateAfterBind( VK_TRUE );
m_indexing_features.setDescriptorBindingUniformBufferUpdateAfterBind( VK_TRUE );
}
std::vector< vk::DeviceQueueCreateInfo > Device::DeviceCreateInfo::getQueueCreateInfos( PhysicalDevice&
physical_device )
void Device::DeviceCreateInfo::getDynamicRenderingFeatures()
{
m_dynamic_rendering_features.setDynamicRendering( VK_TRUE );
m_dynamic_rendering_local_read_features.setDynamicRenderingLocalRead( VK_TRUE );
}
std::vector< vk::DeviceQueueCreateInfo > Device::DeviceCreateInfo::
getQueueCreateInfos( PhysicalDevice& physical_device )
{
std::vector< vk::DeviceQueueCreateInfo > queueCreateInfos;
std::set< std::uint32_t > uniqueQueueFamilies = {
@@ -98,22 +100,18 @@ namespace fgl::engine
return queueCreateInfos;
}
vk::DeviceCreateInfo Device::DeviceCreateInfo::getCreateInfo( PhysicalDevice& physical_device )
void Device::DeviceCreateInfo::getCreateInfo( PhysicalDevice& physical_device )
{
vk::DeviceCreateInfo createInfo {};
createInfo.queueCreateInfoCount = static_cast< uint32_t >( m_queue_create_infos.size() );
createInfo.pQueueCreateInfos = m_queue_create_infos.data();
m_create_info.setQueueCreateInfos( m_queue_create_infos );
createInfo.pEnabledFeatures = &m_requested_features;
createInfo.enabledExtensionCount = static_cast< uint32_t >( deviceExtensions.size() );
createInfo.ppEnabledExtensionNames = deviceExtensions.data();
m_create_info.setPEnabledFeatures( &m_requested_features );
createInfo.setPNext( &m_indexing_features );
m_create_info.setPEnabledExtensionNames( m_device_extensions );
//Get device extension list
const auto supported_extensions { physical_device.handle().enumerateDeviceExtensionProperties() };
std::cout << "Supported device extensions:" << std::endl;
for ( auto& desired_ext : deviceExtensions )
for ( auto& desired_ext : m_device_extensions )
{
bool found { false };
for ( auto& supported_ext : supported_extensions )
@@ -132,23 +130,23 @@ namespace fgl::engine
// have been deprecated
if ( true )
{
createInfo.enabledLayerCount = static_cast< uint32_t >( validationLayers.size() );
createInfo.ppEnabledLayerNames = validationLayers.data();
m_create_info.enabledLayerCount = static_cast< uint32_t >( m_validation_layers.size() );
m_create_info.ppEnabledLayerNames = m_validation_layers.data();
}
else
{
createInfo.enabledLayerCount = 0;
m_create_info.enabledLayerCount = 0;
}
return createInfo;
}
Device::DeviceCreateInfo::DeviceCreateInfo( PhysicalDevice& physical_device ) :
m_requested_features( getDeviceFeatures( physical_device ) ),
m_indexing_features( getIndexingFeatures() ),
m_queue_create_infos( getQueueCreateInfos( physical_device ) ),
m_create_info( getCreateInfo( physical_device ) )
{}
m_queue_create_infos( getQueueCreateInfos( physical_device ) )
{
getIndexingFeatures();
getDynamicRenderingFeatures();
getCreateInfo( physical_device );
}
vk::CommandPoolCreateInfo Device::commandPoolInfo()
{
@@ -175,6 +173,9 @@ namespace fgl::engine
{
assert( !global_device );
assert( *m_graphics_queue );
assert( *m_present_queue );
global_device = this;
DescriptorPool::init();
@@ -187,7 +188,7 @@ namespace fgl::engine
{
std::vector< vk::LayerProperties > availableLayers { vk::enumerateInstanceLayerProperties() };
for ( const char* layerName : validationLayers )
for ( const char* layerName : m_validation_layers )
{
bool layerFound = false;
@@ -215,12 +216,12 @@ namespace fgl::engine
device.enumerateDeviceExtensionProperties()
};
std::set< std::string > requiredExtensions( deviceExtensions.begin(), deviceExtensions.end() );
std::set< std::string > requiredExtensions( m_device_extensions.begin(), m_device_extensions.end() );
std::uint32_t required_count { static_cast< std::uint32_t >( requiredExtensions.size() ) };
std::uint32_t found_count { 0 };
for ( const auto required : deviceExtensions )
for ( const auto required : m_device_extensions )
{
if ( std::find_if(
availableExtensions.begin(),

View File

@@ -40,20 +40,43 @@ namespace fgl::engine
PhysicalDevice m_physical_device;
inline static std::vector< const char* > validationLayers { "VK_LAYER_KHRONOS_validation" };
inline static std::vector< const char* > deviceExtensions { DEVICE_EXTENSIONS };
inline static std::vector< const char* > m_validation_layers { "VK_LAYER_KHRONOS_validation" };
inline static std::vector< const char* > m_device_extensions { DEVICE_EXTENSIONS };
struct DeviceCreateInfo
class DeviceCreateInfo
{
vk::PhysicalDeviceFeatures m_requested_features;
vk::PhysicalDeviceDescriptorIndexingFeatures m_indexing_features;
std::vector< vk::DeviceQueueCreateInfo > m_queue_create_infos;
vk::DeviceCreateInfo m_create_info;
using InfoChain = vk::StructureChain<
vk::DeviceCreateInfo,
vk::PhysicalDeviceDynamicRenderingFeatures,
vk::PhysicalDeviceDynamicRenderingLocalReadFeatures,
vk::PhysicalDeviceDescriptorIndexingFeatures >;
InfoChain m_info_chain;
vk::PhysicalDeviceFeatures getDeviceFeatures( PhysicalDevice& );
vk::PhysicalDeviceDescriptorIndexingFeatures getIndexingFeatures();
void getIndexingFeatures();
void getDynamicRenderingFeatures();
std::vector< vk::DeviceQueueCreateInfo > getQueueCreateInfos( PhysicalDevice& );
vk::DeviceCreateInfo getCreateInfo( PhysicalDevice& );
void getCreateInfo( PhysicalDevice& );
public:
vk::DeviceCreateInfo& m_create_info { m_info_chain.get< vk::DeviceCreateInfo >() };
vk::PhysicalDeviceDescriptorIndexingFeatures& m_indexing_features {
m_info_chain.get< vk::PhysicalDeviceDescriptorIndexingFeatures >()
};
vk::PhysicalDeviceDynamicRenderingLocalReadFeatures& m_dynamic_rendering_local_read_features {
m_info_chain.get< vk::PhysicalDeviceDynamicRenderingLocalReadFeatures >()
};
vk::PhysicalDeviceDynamicRenderingFeatures& m_dynamic_rendering_features {
m_info_chain.get< vk::PhysicalDeviceDynamicRenderingFeatures >()
};
DeviceCreateInfo( PhysicalDevice& );
@@ -113,7 +136,11 @@ namespace fgl::engine
vk::SurfaceKHR surface() { return m_surface_khr; }
vk::raii::Queue& graphicsQueue() { return m_graphics_queue; }
vk::raii::Queue& graphicsQueue()
{
assert( *m_graphics_queue );
return m_graphics_queue;
}
vk::raii::Queue& presentQueue() { return m_present_queue; }

View File

@@ -14,5 +14,6 @@ inline const static std::vector< const char* > DEVICE_EXTENSIONS = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, // Used for descriptor indexing
VK_EXT_MESH_SHADER_EXTENSION_NAME // MAGICAL SHIT
VK_EXT_MESH_SHADER_EXTENSION_NAME, // MAGICAL SHIT
VK_KHR_DYNAMIC_RENDERING_LOCAL_READ_EXTENSION_NAME // Required until vulkan 1.4
};

View File

@@ -97,12 +97,13 @@ namespace fgl::engine
{
auto& images { m_attachment_resources.m_images };
auto& image_views { m_attachment_resources.m_image_views };
const auto& itter { images.emplace_back( std::make_shared< Image >(
extent,
description.format,
usage | vk::ImageUsageFlagBits::eInputAttachment | extra_flags,
vk::ImageLayout::eUndefined,
final_layout ) ) };
const auto& itter { images.emplace_back(
std::make_shared< Image >(
extent,
description.format,
usage | vk::ImageUsageFlagBits::eInputAttachment | extra_flags,
vk::ImageLayout::eUndefined,
final_layout ) ) };
image_views.emplace_back( itter->getView() );
}
}
@@ -124,12 +125,31 @@ namespace fgl::engine
}
}
ImageView& getView( const FrameIndex frame_idx )
ImageView& getView( const FrameIndex frame_idx ) const
{
assert( frame_idx < m_attachment_resources.m_image_views.size() );
return *m_attachment_resources.m_image_views[ frame_idx ];
}
Image& getImage( const FrameIndex frame_idx ) const
{
assert( frame_idx < m_attachment_resources.m_image_views.size() );
return *m_attachment_resources.m_images[ frame_idx ];
}
vk::RenderingAttachmentInfo renderInfo( const FrameIndex frame_index, const vk::ImageLayout layout ) const
{
vk::RenderingAttachmentInfo info {};
info.setClearValue( m_clear_value );
info.imageView = getView( frame_index ).getVkView();
info.loadOp = load_op;
info.storeOp = store_op;
info.imageLayout = layout;
return info;
}
constexpr vk::AttachmentDescription& desc() { return description; }
friend class RenderPassBuilder;
@@ -153,22 +173,14 @@ namespace fgl::engine
template < typename T >
concept is_input_attachment = requires( T a ) {
{
a.is_input
} -> std::same_as< const bool& >;
{
a.m_layout
} -> std::same_as< const vk::ImageLayout& >;
{ a.is_input } -> std::same_as< const bool& >;
{ a.m_layout } -> std::same_as< const vk::ImageLayout& >;
} && T::is_input;
template < typename T >
concept is_used_attachment = requires( T a ) {
{
a.is_input
} -> std::same_as< const bool& >;
{
a.m_layout
} -> std::same_as< const vk::ImageLayout& >;
{ a.is_input } -> std::same_as< const bool& >;
{ a.m_layout } -> std::same_as< const vk::ImageLayout& >;
} && !T::is_input;
template < typename T > concept is_wrapped_attachment = is_input_attachment< T > || is_used_attachment< T >;

View File

@@ -32,6 +32,7 @@ namespace fgl::engine
void AttachmentBuilder::finish()
{
parent.m_state->color_blend_attachment.emplace_back( color_blend_config );
parent.m_state->formats.colors.emplace_back( m_format );
m_finished = true;
}
@@ -39,4 +40,10 @@ namespace fgl::engine
{
FGL_ASSERT( m_finished, "Attachemnt builder not finished!" );
}
AttachmentBuilder& AttachmentBuilder::setFormat( const vk::Format format )
{
m_format = format;
return *this;
}
} // namespace fgl::engine

View File

@@ -12,6 +12,7 @@ namespace fgl::engine
{
PipelineBuilder& parent;
bool m_finished { false };
vk::Format m_format { vk::Format::eUndefined };
AttachmentBuilder( PipelineBuilder& source );
AttachmentBuilder() = delete;
@@ -27,6 +28,8 @@ namespace fgl::engine
AttachmentBuilder& enableBlend();
~AttachmentBuilder();
AttachmentBuilder& setFormat( vk::Format format );
};
} // namespace fgl::engine

View File

@@ -7,12 +7,13 @@
#include "AttachmentBuilder.hpp"
#include "Pipeline.hpp"
#include "engine/descriptors/DescriptorSetLayout.hpp"
#include "engine/rendering/RenderingFormats.hpp"
#include "engine/rendering/SwapChain.hpp"
namespace fgl::engine
{
PipelineBuilder::PipelineBuilder( vk::raii::RenderPass& renderpass, const std::uint32_t subpass_stage ) :
m_state( std::make_unique< BuilderState >( renderpass, subpass_stage ) )
PipelineBuilder::PipelineBuilder( std::uint32_t subpass ) : m_state( std::make_unique< BuilderState >( subpass ) )
{
addDynamicState( vk::DynamicState::eViewport );
addDynamicState( vk::DynamicState::eScissor );
@@ -28,6 +29,118 @@ namespace fgl::engine
m_state->shaders.fragment = std::forward< std::shared_ptr< Shader > >( shader );
}
vk::raii::Pipeline PipelineBuilder::
createRenderPassPipeline( BuilderState& state, const vk::raii::PipelineLayout& layout )
{
FGL_UNREACHABLE();
vk::GraphicsPipelineCreateInfo info {};
info.pNext = VK_NULL_HANDLE;
info.flags = {};
std::vector< vk::PipelineShaderStageCreateInfo > stages {};
if ( state.shaders.vertex ) stages.emplace_back( state.shaders.vertex->stage_info );
if ( state.shaders.fragment ) stages.emplace_back( state.shaders.fragment->stage_info );
info.setStages( stages );
vk::PipelineVertexInputStateCreateInfo vertex_input_info {};
vertex_input_info.pNext = VK_NULL_HANDLE;
vertex_input_info.flags = {};
vertex_input_info.setVertexBindingDescriptions( state.vertex_input_descriptions.bindings );
vertex_input_info.setVertexAttributeDescriptions( state.vertex_input_descriptions.attributes );
info.setPVertexInputState( &vertex_input_info );
info.pInputAssemblyState = &state.assembly_info;
info.pTessellationState = &state.tesselation_state_info;
info.pViewportState = &state.viewport_info;
info.pRasterizationState = &state.rasterization_info;
info.pMultisampleState = &state.multisample_info;
info.pDepthStencilState = &state.depth_stencil_info;
state.color_blend_info.setAttachments( state.color_blend_attachment );
info.pColorBlendState = &state.color_blend_info;
info.pDynamicState = &state.dynamic_state_info;
info.layout = layout;
info.subpass = state.m_subpass_stage;
//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( state.m_dynamic_state );
if ( state.m_dynamic_state.size() > 0 ) info.setPDynamicState( &dynamic_state_create_info );
vk::raii::Pipeline pipeline { Device::getInstance()->createGraphicsPipeline( VK_NULL_HANDLE, info ) };
return pipeline;
}
vk::raii::Pipeline PipelineBuilder::createDynamicPipeline( BuilderState& state, vk::raii::PipelineLayout& layout )
{
vk::StructureChain< vk::GraphicsPipelineCreateInfo, vk::PipelineRenderingCreateInfo > chain {};
vk::GraphicsPipelineCreateInfo& info { chain.get< vk::GraphicsPipelineCreateInfo >() };
info.pNext = VK_NULL_HANDLE;
info.flags = {};
chain.relink< vk::PipelineRenderingCreateInfo >();
std::vector< vk::PipelineShaderStageCreateInfo > stages {};
if ( state.shaders.vertex ) stages.emplace_back( state.shaders.vertex->stage_info );
if ( state.shaders.fragment ) stages.emplace_back( state.shaders.fragment->stage_info );
info.setStages( stages );
vk::PipelineVertexInputStateCreateInfo vertex_input_info {};
vertex_input_info.pNext = VK_NULL_HANDLE;
vertex_input_info.flags = {};
vertex_input_info.setVertexBindingDescriptions( state.vertex_input_descriptions.bindings );
vertex_input_info.setVertexAttributeDescriptions( state.vertex_input_descriptions.attributes );
info.setPVertexInputState( &vertex_input_info );
info.pInputAssemblyState = &state.assembly_info;
info.pTessellationState = &state.tesselation_state_info;
info.pViewportState = &state.viewport_info;
info.pRasterizationState = &state.rasterization_info;
info.pMultisampleState = &state.multisample_info;
info.pDepthStencilState = &state.depth_stencil_info;
state.color_blend_info.setAttachments( state.color_blend_attachment );
info.pColorBlendState = &state.color_blend_info;
info.pDynamicState = &state.dynamic_state_info;
info.layout = layout;
info.subpass = state.m_subpass_stage;
//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( state.m_dynamic_state );
vk::PipelineRenderingCreateInfo& rendering_info { chain.get< vk::PipelineRenderingCreateInfo >() };
rendering_info.setColorAttachmentFormats( state.formats.colors );
rendering_info.setDepthAttachmentFormat( state.formats.depth );
if ( state.m_dynamic_state.size() > 0 ) info.setPDynamicState( &dynamic_state_create_info );
vk::raii::Pipeline pipeline { Device::getInstance()->createGraphicsPipeline( VK_NULL_HANDLE, info ) };
return pipeline;
}
descriptors::DescriptorSetLayout empty_set_layout { descriptors::DescriptorSetLayout::createEmptySet() };
vk::raii::PipelineLayout PipelineBuilder::createLayout()
@@ -100,6 +213,9 @@ namespace fgl::engine
m_state->push_constant.stageFlags = flags;
}
PipelineBuilder::BuilderState::Formats::Formats() : depth( pickDepthFormat() )
{}
[[nodiscard]] vk::PipelineColorBlendAttachmentState& PipelineBuilder::BuilderState::addColorAttachment()
{
color_blend_attachment.emplace_back();
@@ -159,6 +275,11 @@ namespace fgl::engine
//info.dynamic_state_info.flags = 0;
}
PipelineBuilder::BuilderState::BuilderState( std::uint32_t subpass ) : m_subpass_stage( subpass )
{
setDefault();
}
void PipelineBuilder::setTopology( const vk::PrimitiveTopology primitive_topology )
{
m_state->assembly_info.topology = primitive_topology;
@@ -191,60 +312,15 @@ namespace fgl::engine
m_state->vertex_input_descriptions.bindings = descriptions;
}
void PipelineBuilder::setAttributeDescriptions( const std::vector< vk::VertexInputAttributeDescription >&
descriptions )
void PipelineBuilder::
setAttributeDescriptions( const std::vector< vk::VertexInputAttributeDescription >& descriptions )
{
m_state->vertex_input_descriptions.attributes = descriptions;
}
vk::raii::Pipeline PipelineBuilder::createFromState( BuilderState& state, vk::raii::PipelineLayout& layout )
{
vk::GraphicsPipelineCreateInfo info {};
info.pNext = VK_NULL_HANDLE;
info.flags = {};
std::vector< vk::PipelineShaderStageCreateInfo > stages {};
if ( state.shaders.vertex ) stages.emplace_back( state.shaders.vertex->stage_info );
if ( state.shaders.fragment ) stages.emplace_back( state.shaders.fragment->stage_info );
info.setStages( stages );
vk::PipelineVertexInputStateCreateInfo vertex_input_info {};
vertex_input_info.pNext = VK_NULL_HANDLE;
vertex_input_info.flags = {};
vertex_input_info.setVertexBindingDescriptions( state.vertex_input_descriptions.bindings );
vertex_input_info.setVertexAttributeDescriptions( state.vertex_input_descriptions.attributes );
info.setPVertexInputState( &vertex_input_info );
info.pInputAssemblyState = &state.assembly_info;
info.pTessellationState = &state.tesselation_state_info;
info.pViewportState = &state.viewport_info;
info.pRasterizationState = &state.rasterization_info;
info.pMultisampleState = &state.multisample_info;
info.pDepthStencilState = &state.depth_stencil_info;
state.color_blend_info.setAttachments( state.color_blend_attachment );
info.pColorBlendState = &state.color_blend_info;
info.pDynamicState = &state.dynamic_state_info;
info.layout = layout;
info.renderPass = state.m_render_pass;
info.subpass = state.m_subpass_stage;
//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( state.m_dynamic_state );
if ( state.m_dynamic_state.size() > 0 ) info.setPDynamicState( &dynamic_state_create_info );
vk::raii::Pipeline pipeline { Device::getInstance()->createGraphicsPipeline( VK_NULL_HANDLE, info ) };
return pipeline;
return createDynamicPipeline( state, layout );
}
vk::raii::Pipeline PipelineBuilder::rebuildFromState( BuilderState& state, vk::raii::PipelineLayout& layout )
@@ -294,4 +370,13 @@ namespace fgl::engine
}
}
void addGBufferAttachments( PipelineBuilder& builder )
{
builder.addColorAttachment().setFormat( pickColorFormat() ).finish();
builder.addColorAttachment().setFormat( pickPositionFormat() ).finish();
builder.addColorAttachment().setFormat( pickNormalFormat() ).finish();
builder.addColorAttachment().setFormat( pickMetallicFormat() ).finish();
builder.addColorAttachment().setFormat( pickEmissiveFormat() ).finish();
}
} // namespace fgl::engine

View File

@@ -9,6 +9,7 @@
#include <cstdint>
#include <unordered_map>
#include "engine/FGL_DEFINES.hpp"
#include "engine/rendering/pipelines/Shader.hpp"
namespace fgl::engine
@@ -35,12 +36,8 @@ namespace fgl::engine
void addDynamicState( vk::DynamicState dynamic_state );
void setPushConstant( vk::ShaderStageFlags flags, std::size_t size );
PipelineBuilder() = delete;
struct BuilderState
{
vk::raii::RenderPass& m_render_pass;
std::uint32_t m_subpass_stage;
vk::PushConstantRange push_constant {};
std::vector< vk::DynamicState > m_dynamic_state {};
@@ -67,6 +64,18 @@ namespace fgl::engine
vk::PipelineMultisampleStateCreateInfo multisample_info {};
std::vector< vk::PipelineColorBlendAttachmentState > color_blend_attachment {};
//! Struct containing the formats each attachment will be in for this pipeline.
struct Formats
{
std::vector< vk::Format > colors {};
vk::Format depth;
Formats();
} formats;
uint32_t m_subpass_stage;
vk::PipelineColorBlendAttachmentState& addColorAttachment();
vk::PipelineColorBlendStateCreateInfo color_blend_info {};
@@ -77,15 +86,14 @@ namespace fgl::engine
vk::PipelineLayoutCreateInfo layout_info {};
explicit BuilderState( std::uint32_t subpass );
// Default config
void setDefault();
BuilderState( vk::raii::RenderPass& renderpass, const std::size_t subpass_stage ) :
m_render_pass( renderpass ),
m_subpass_stage( subpass_stage )
{
setDefault();
}
FGL_DELETE_MOVE( BuilderState );
FGL_DELETE_COPY( BuilderState );
FGL_DELETE_DEFAULT_CTOR( BuilderState );
};
std::unique_ptr< BuilderState > m_state;
@@ -102,12 +110,16 @@ namespace fgl::engine
void setAttributeDescriptions( const std::vector< vk::VertexInputAttributeDescription >& descriptions );
PipelineBuilder( vk::raii::RenderPass& renderpass, std::uint32_t subpass_stage );
PipelineBuilder( std::uint32_t subpass );
void setVertexShader( std::shared_ptr< Shader >&& shader );
void setFragmentShader( std::shared_ptr< Shader >&& shader );
static vk::raii::Pipeline
createRenderPassPipeline( BuilderState& state, const vk::raii::PipelineLayout& layout );
static vk::raii::Pipeline createDynamicPipeline( BuilderState& state, vk::raii::PipelineLayout& layout );
static vk::raii::Pipeline createFromState( BuilderState& state, vk::raii::PipelineLayout& layout );
static vk::raii::Pipeline rebuildFromState( BuilderState& state, vk::raii::PipelineLayout& layout );
@@ -117,4 +129,6 @@ namespace fgl::engine
//! Adds the GBuffer output attachments to the config for the given pipeline
void setGBufferOutputAttachments( PipelineBuilder::BuilderState& config );
void addGBufferAttachments( PipelineBuilder& builder );
} // namespace fgl::engine

View File

@@ -7,6 +7,7 @@
#include "Control.hpp"
#include "editor/src/gui/safe_include.hpp"
#include "engine/camera/Camera.hpp"
#include "engine/rendering/RenderingFormats.hpp"
#include "engine/rendering/pipelines/v2/AttachmentBuilder.hpp"
#include "engine/rendering/pipelines/v2/Pipeline.hpp"
#include "engine/rendering/pipelines/v2/PipelineBuilder.hpp"
@@ -16,14 +17,12 @@ namespace fgl::engine
CompositionSystem::CompositionSystem( vk::raii::RenderPass& render_pass )
{
constexpr std::size_t SUBPASS { 1 };
PipelineBuilder builder { render_pass, SUBPASS };
PipelineBuilder builder { 0 };
builder.addDescriptorSet( gbuffer_set );
builder.addDescriptorSet( Camera::getDescriptorLayout() );
builder.addColorAttachment().finish();
builder.addColorAttachment().setFormat( pickColorFormat() ).finish();
builder.setPushConstant( vk::ShaderStageFlagBits::eFragment, sizeof( CompositionControl ) );
@@ -45,8 +44,6 @@ namespace fgl::engine
{
auto& command_buffer { info.command_buffer };
command_buffer.nextSubpass( vk::SubpassContents::eInline );
m_composite_pipeline->bind( command_buffer );
m_composite_pipeline->bindDescriptor( command_buffer, info.getGBufferDescriptor() );

View File

@@ -17,7 +17,7 @@ namespace fgl::engine
{
//descriptors::DescriptorSetCollection descriptors { gui_descriptor_set };
PipelineBuilder builder { render_pass, 0 };
PipelineBuilder builder { 0 };
builder.addDescriptorSet( gui_descriptor_set );
@@ -27,7 +27,7 @@ namespace fgl::engine
builder.setVertexShader( Shader::loadVertex( "shaders/fullscreen.vert" ) );
builder.setFragmentShader( Shader::loadFragment( "shaders/gui-compose.frag" ) );
builder.addColorAttachment().finish();
builder.addColorAttachment().setFormat( vk::Format::eR8G8B8A8Unorm ).finish();
m_pipeline = builder.create();
m_pipeline->setDebugName( "Gui Pipeline" );

View File

@@ -12,7 +12,6 @@
#include "engine/camera/Camera.hpp"
#include "engine/debug/profiling/counters.hpp"
#include "engine/debug/timing/FlameGraph.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"
@@ -27,15 +26,11 @@ namespace fgl::engine
// PipelineConfigInfo standard_info { render_pass };
// PipelineConfigInfo::addGBufferAttachmentsConfig( standard_info );
PipelineBuilder builder { render_pass, 0 };
PipelineBuilder builder { 0 };
builder.addDescriptorSet( Camera::getDescriptorLayout() );
builder.addColorAttachment().finish();
builder.addColorAttachment().finish();
builder.addColorAttachment().finish();
builder.addColorAttachment().finish();
builder.addColorAttachment().finish();
addGBufferAttachments( builder );
builder.setFragmentShader( Shader::loadFragment( "shaders/textureless-gbuffer.frag" ) );
builder.setVertexShader( Shader::loadVertex( "shaders/textureless-gbuffer.vert" ) );
@@ -52,13 +47,9 @@ namespace fgl::engine
// PipelineConfigInfo textured_info { render_pass };
// PipelineConfigInfo::addGBufferAttachmentsConfig( textured_info );
PipelineBuilder builder { render_pass, 0 };
PipelineBuilder builder { 0 };
builder.addColorAttachment().finish();
builder.addColorAttachment().finish();
builder.addColorAttachment().finish();
builder.addColorAttachment().finish();
builder.addColorAttachment().finish();
addGBufferAttachments( builder );
builder.addDescriptorSet( Camera::getDescriptorLayout() );
builder.addDescriptorSet( Texture::getDescriptorLayout() );

View File

@@ -10,7 +10,6 @@
#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/Pipeline.hpp"
#include "engine/rendering/pipelines/v2/PipelineBuilder.hpp"
@@ -27,15 +26,11 @@ namespace fgl::engine
LineDrawer::LineDrawer( vk::raii::RenderPass& render_pass )
{
PipelineBuilder builder { render_pass, 0 };
PipelineBuilder builder { 0 };
builder.addDescriptorSet( Camera::getDescriptorLayout() );
builder.addColorAttachment().finish();
builder.addColorAttachment().finish();
builder.addColorAttachment().finish();
builder.addColorAttachment().finish();
builder.addColorAttachment().finish();
addGBufferAttachments( builder );
builder.setAttributeDescriptions( SimpleVertex::getAttributeDescriptions() );
builder.setBindingDescriptions( SimpleVertex::getBindingDescriptions() );