diff --git a/cmake_modules/dependencies/vulkan.cmake b/cmake_modules/dependencies/vulkan.cmake index 7c2a27a..ffd85c2 100644 --- a/cmake_modules/dependencies/vulkan.cmake +++ b/cmake_modules/dependencies/vulkan.cmake @@ -1 +1,4 @@ -find_package(Vulkan REQUIRED) \ No newline at end of file +find_package(Vulkan REQUIRED) +if (NOT Vulkan_FOUND) + error("Vulkan not found") +endif () \ No newline at end of file diff --git a/src/editor/src/main.cpp b/src/editor/src/main.cpp index 822c865..5254e54 100644 --- a/src/editor/src/main.cpp +++ b/src/editor/src/main.cpp @@ -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. diff --git a/src/engine/EngineContext.cpp b/src/engine/EngineContext.cpp index 6a0638c..0bc7cca 100644 --- a/src/engine/EngineContext.cpp +++ b/src/engine/EngineContext.cpp @@ -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" ); diff --git a/src/engine/camera/CameraRenderer.cpp b/src/engine/camera/CameraRenderer.cpp index 7a717af..fa9868e 100644 --- a/src/engine/camera/CameraRenderer.cpp +++ b/src/engine/camera/CameraRenderer.cpp @@ -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() diff --git a/src/engine/camera/CameraSwapchain.cpp b/src/engine/camera/CameraSwapchain.cpp index ce5cdc4..780f37c 100644 --- a/src/engine/camera/CameraSwapchain.cpp +++ b/src/engine/camera/CameraSwapchain.cpp @@ -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; diff --git a/src/engine/camera/CameraSwapchain.hpp b/src/engine/camera/CameraSwapchain.hpp index ffd5791..09a8b5c 100644 --- a/src/engine/camera/CameraSwapchain.hpp +++ b/src/engine/camera/CameraSwapchain.hpp @@ -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(); diff --git a/src/engine/rendering/Instance.cpp b/src/engine/rendering/Instance.cpp index b7195ac..cdf17e9 100644 --- a/src/engine/rendering/Instance.cpp +++ b/src/engine/rendering/Instance.cpp @@ -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 ) : diff --git a/src/engine/rendering/RenderingFormats.cpp b/src/engine/rendering/RenderingFormats.cpp new file mode 100644 index 0000000..8c8d245 --- /dev/null +++ b/src/engine/rendering/RenderingFormats.cpp @@ -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 diff --git a/src/engine/rendering/RenderingFormats.hpp b/src/engine/rendering/RenderingFormats.hpp new file mode 100644 index 0000000..305e15e --- /dev/null +++ b/src/engine/rendering/RenderingFormats.hpp @@ -0,0 +1,18 @@ +// +// Created by kj16609 on 12/9/24. +// +#pragma once + +#include + +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 \ No newline at end of file diff --git a/src/engine/rendering/SwapChain.cpp b/src/engine/rendering/SwapChain.cpp index e057fdd..28b1705 100644 --- a/src/engine/rendering/SwapChain.cpp +++ b/src/engine/rendering/SwapChain.cpp @@ -7,6 +7,7 @@ #include #include +#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 diff --git a/src/engine/rendering/SwapChain.hpp b/src/engine/rendering/SwapChain.hpp index f183cea..7e9c549 100644 --- a/src/engine/rendering/SwapChain.hpp +++ b/src/engine/rendering/SwapChain.hpp @@ -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 ); diff --git a/src/engine/rendering/devices/Device.cpp b/src/engine/rendering/devices/Device.cpp index 08cf02c..5ffeb4c 100644 --- a/src/engine/rendering/devices/Device.cpp +++ b/src/engine/rendering/devices/Device.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #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(), diff --git a/src/engine/rendering/devices/Device.hpp b/src/engine/rendering/devices/Device.hpp index a416a22..d1a577c 100644 --- a/src/engine/rendering/devices/Device.hpp +++ b/src/engine/rendering/devices/Device.hpp @@ -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; } diff --git a/src/engine/rendering/devices/extensions.hpp b/src/engine/rendering/devices/extensions.hpp index 7cf8703..16b3cee 100644 --- a/src/engine/rendering/devices/extensions.hpp +++ b/src/engine/rendering/devices/extensions.hpp @@ -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 }; diff --git a/src/engine/rendering/pipelines/Attachment.hpp b/src/engine/rendering/pipelines/Attachment.hpp index 80a0b3d..e37028e 100644 --- a/src/engine/rendering/pipelines/Attachment.hpp +++ b/src/engine/rendering/pipelines/Attachment.hpp @@ -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 >; diff --git a/src/engine/rendering/pipelines/v2/AttachmentBuilder.cpp b/src/engine/rendering/pipelines/v2/AttachmentBuilder.cpp index 1d9c8f7..2a30cd8 100644 --- a/src/engine/rendering/pipelines/v2/AttachmentBuilder.cpp +++ b/src/engine/rendering/pipelines/v2/AttachmentBuilder.cpp @@ -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 diff --git a/src/engine/rendering/pipelines/v2/AttachmentBuilder.hpp b/src/engine/rendering/pipelines/v2/AttachmentBuilder.hpp index 57227e3..37d6ea3 100644 --- a/src/engine/rendering/pipelines/v2/AttachmentBuilder.hpp +++ b/src/engine/rendering/pipelines/v2/AttachmentBuilder.hpp @@ -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 diff --git a/src/engine/rendering/pipelines/v2/PipelineBuilder.cpp b/src/engine/rendering/pipelines/v2/PipelineBuilder.cpp index 8f18811..3f63d30 100644 --- a/src/engine/rendering/pipelines/v2/PipelineBuilder.cpp +++ b/src/engine/rendering/pipelines/v2/PipelineBuilder.cpp @@ -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 diff --git a/src/engine/rendering/pipelines/v2/PipelineBuilder.hpp b/src/engine/rendering/pipelines/v2/PipelineBuilder.hpp index 028bc79..706f63f 100644 --- a/src/engine/rendering/pipelines/v2/PipelineBuilder.hpp +++ b/src/engine/rendering/pipelines/v2/PipelineBuilder.hpp @@ -9,6 +9,7 @@ #include #include +#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 diff --git a/src/engine/systems/composition/CompositionSystem.cpp b/src/engine/systems/composition/CompositionSystem.cpp index 9c1d1be..e4127e8 100644 --- a/src/engine/systems/composition/CompositionSystem.cpp +++ b/src/engine/systems/composition/CompositionSystem.cpp @@ -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() ); diff --git a/src/engine/systems/composition/GuiSystem.cpp b/src/engine/systems/composition/GuiSystem.cpp index 6aff3b6..c754aeb 100644 --- a/src/engine/systems/composition/GuiSystem.cpp +++ b/src/engine/systems/composition/GuiSystem.cpp @@ -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" ); diff --git a/src/engine/systems/render/EntityRendererSystem.cpp b/src/engine/systems/render/EntityRendererSystem.cpp index d387462..8426271 100644 --- a/src/engine/systems/render/EntityRendererSystem.cpp +++ b/src/engine/systems/render/EntityRendererSystem.cpp @@ -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() ); diff --git a/src/engine/systems/render/LineDrawer.cpp b/src/engine/systems/render/LineDrawer.cpp index 8e336a4..ea3d810 100644 --- a/src/engine/systems/render/LineDrawer.cpp +++ b/src/engine/systems/render/LineDrawer.cpp @@ -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() );