From 5a0fc04a46564699fc4a4d90b1e2f3e5d71dc0f7 Mon Sep 17 00:00:00 2001 From: kj16609 Date: Mon, 7 Apr 2025 13:52:14 -0400 Subject: [PATCH] Finish GPU driven rendering basics --- fgl_cmake_modules | 2 +- src/editor/src/main.cpp | 29 ++++++++++++- src/engine/EngineContext.hpp | 4 +- src/engine/assets/image/Image.cpp | 20 ++++----- src/engine/assets/image/ImageView.cpp | 25 ++++++----- src/engine/assets/image/ImageView.hpp | 5 +-- src/engine/assets/image/Sampler.cpp | 18 +++++++- src/engine/assets/material/Material.hpp | 43 +++++++++++++------ src/engine/assets/model/Model.cpp | 7 ++- src/engine/assets/model/Model.hpp | 4 +- src/engine/assets/model/ModelInstance.hpp | 13 ------ src/engine/assets/model/ModelInstanceInfo.hpp | 2 +- src/engine/assets/texture/Texture.cpp | 14 ++---- src/engine/assets/texture/Texture.hpp | 1 - src/engine/camera/Camera.cpp | 2 +- src/engine/camera/CompositeSwapchain.cpp | 3 +- src/engine/camera/GBufferRenderer.cpp | 1 - src/engine/descriptors/Descriptor.hpp | 34 +++++++++------ src/engine/descriptors/DescriptorSet.cpp | 23 ++++------ src/engine/descriptors/DescriptorSet.hpp | 12 +----- .../gameobjects/components/ModelComponent.hpp | 10 +++++ .../components/TransformComponent.hpp | 2 + src/engine/lighting/shadows/ShadowMap.cpp | 9 ++-- src/engine/memory/buffers/HostSingleT.hpp | 1 + .../buffers/UniqueFrameSuballocation.hpp | 8 +--- .../memory/buffers/vector/DeviceVector.hpp | 4 ++ .../memory/buffers/vector/IndexedVector.hpp | 8 ---- src/engine/rendering/PresentSwapChain.cpp | 5 ++- src/engine/rendering/PresentSwapChain.hpp | 2 +- src/engine/rendering/Renderer.cpp | 18 ++++++-- .../rendering/pipelines/shaders/Compiler.cpp | 2 + .../rendering/pipelines/v2/Pipeline.cpp | 5 ++- .../rendering/pipelines/v2/Pipeline.hpp | 2 +- src/engine/systems/composition/GuiSystem.cpp | 1 + .../systems/prerender/CullingSystem.cpp | 3 +- .../systems/render/EntityRendererSystem.cpp | 2 + .../systems/render/EntityRendererSystem.hpp | 16 ------- src/shaders/culling.slang | 6 +-- 38 files changed, 197 insertions(+), 169 deletions(-) diff --git a/fgl_cmake_modules b/fgl_cmake_modules index 60d6dcf..1d3efaf 160000 --- a/fgl_cmake_modules +++ b/fgl_cmake_modules @@ -1 +1 @@ -Subproject commit 60d6dcff66c22acc5370ef25b99427dc6dcbf61a +Subproject commit 1d3efaf2bcdcefd7ff312733e1eda7933e8c24d6 diff --git a/src/editor/src/main.cpp b/src/editor/src/main.cpp index 18a32c3..b858a33 100644 --- a/src/editor/src/main.cpp +++ b/src/editor/src/main.cpp @@ -3,6 +3,7 @@ // #include +#include "assets/model/builders/SceneBuilder.hpp" #include "debug/profiling/counters.hpp" #include "engine/EngineContext.hpp" #include "engine/camera/CameraManager.hpp" @@ -52,7 +53,7 @@ int main() profiling::resetCounters(); } ); - engine_ctx.hookEarlyFrame( [ & ]( [[maybe_unused]] FrameInfo& info ) { editor_ctx.draw( info ); } ); + engine_ctx.hookLateFrame( [ & ]( [[maybe_unused]] FrameInfo& info ) { editor_ctx.draw( info ); } ); engine_ctx.hookLateFrame( [ & ]( FrameInfo& info ) { editor_ctx.endDraw( info ); } ); // Now we need to create the camera for the editor. @@ -67,6 +68,32 @@ int main() constexpr bool playing { false }; + { + auto& buffers { getModelBuffers() }; + SceneBuilder builder { buffers.m_vertex_buffer, buffers.m_index_buffer }; + + constexpr std::string_view sponza_path { + "/home/kj16609/Desktop/Projects/cxx/Mecha/src/assets/khronos-sponza/Sponza.gltf" + }; + + builder.loadScene( sponza_path ); + + std::vector< GameObject > objs { builder.getGameObjects() }; + + for ( auto& obj : objs ) + { + if ( obj.hasComponent< components::ModelComponent >() ) + { + auto model_components { obj.getComponents< components::ModelComponent >() }; + + for ( auto& component : model_components ) + {} + } + + engine_ctx.game_objects.emplace_back( std::move( obj ) ); + } + } + //! Will be true until the window says it wants to close. while ( engine_ctx.good() ) { diff --git a/src/engine/EngineContext.hpp b/src/engine/EngineContext.hpp index 5211efb..0f36eef 100644 --- a/src/engine/EngineContext.hpp +++ b/src/engine/EngineContext.hpp @@ -70,10 +70,10 @@ namespace fgl::engine // Memory pool for matrix info and draw parameters memory::Buffer m_draw_parameter_pool; - std::vector< GameObject > game_objects {}; - public: + std::vector< GameObject > game_objects {}; + ModelGPUBuffers m_model_buffers {}; private: diff --git a/src/engine/assets/image/Image.cpp b/src/engine/assets/image/Image.cpp index 2323188..1262354 100644 --- a/src/engine/assets/image/Image.cpp +++ b/src/engine/assets/image/Image.cpp @@ -11,15 +11,12 @@ namespace fgl::engine std::shared_ptr< ImageView > Image::getView( Sampler sampler ) { - if ( !m_view.expired() ) - return m_view.lock(); - else - { - assert( m_handle ); - auto ptr { std::make_shared< ImageView >( m_handle, std::move( sampler ) ) }; - m_view = ptr; - return ptr; - } + if ( !m_view.expired() ) return m_view.lock(); + + assert( m_handle ); + auto ptr { std::make_shared< ImageView >( m_handle, std::move( sampler ) ) }; + m_view = ptr; + return ptr; } constexpr vk::AccessFlags getAccessFlags( const vk::ImageLayout layout ) @@ -29,7 +26,7 @@ namespace fgl::engine default: FGL_UNREACHABLE(); case vk::ImageLayout::eUndefined: - return vk::AccessFlags( 0 ); + return vk::AccessFlagBits::eNone; case vk::ImageLayout::eGeneral: break; case vk::ImageLayout::eColorAttachmentOptimal: @@ -56,8 +53,7 @@ namespace fgl::engine case vk::ImageLayout::eDepthReadOnlyOptimal: [[fallthrough]]; case vk::ImageLayout::eDepthAttachmentOptimal: - return vk::AccessFlagBits::eDepthStencilAttachmentRead - | vk::AccessFlagBits::eDepthStencilAttachmentWrite; + return vk::AccessFlagBits::eDepthStencilAttachmentWrite; case vk::ImageLayout::eStencilReadOnlyOptimal: break; case vk::ImageLayout::eReadOnlyOptimal: diff --git a/src/engine/assets/image/ImageView.cpp b/src/engine/assets/image/ImageView.cpp index e0d2972..3d011f3 100644 --- a/src/engine/assets/image/ImageView.cpp +++ b/src/engine/assets/image/ImageView.cpp @@ -26,24 +26,27 @@ namespace fgl::engine ImageView::ImageView( const std::shared_ptr< ImageHandle >& img ) : m_resource( img ), - m_descriptor_info(), m_image_view( createImageView( img ) ), m_sampler(), m_name( "Unnamed ImageView" ) { - m_descriptor_info.imageLayout = img->m_final_layout; - m_descriptor_info.imageView = m_image_view; + // m_descriptor_info.imageLayout = img->m_final_layout; + // m_descriptor_info.imageView = m_image_view; } - ImageView::ImageView( const std::shared_ptr< ImageHandle >& img, Sampler&& sampler ) : ImageView( img ) - { - m_sampler = std::move( sampler ); - } + ImageView::ImageView( const std::shared_ptr< ImageHandle >& img, Sampler&& sampler ) : + m_resource( img ), + m_image_view( createImageView( img ) ), + m_sampler( std::forward< Sampler >( sampler ) ), + m_name( "Unnamed ImageView" ) + {} vk::DescriptorImageInfo ImageView::descriptorInfo( const vk::Sampler sampler, const vk::ImageLayout layout ) const { - vk::DescriptorImageInfo info { descriptorInfo( layout ) }; + vk::DescriptorImageInfo info {}; + info.imageLayout = layout; + info.imageView = m_image_view; info.sampler = sampler; return info; @@ -51,11 +54,7 @@ namespace fgl::engine vk::DescriptorImageInfo ImageView::descriptorInfo( const vk::ImageLayout layout ) const { - vk::DescriptorImageInfo info {}; - info.imageLayout = layout; - info.imageView = m_image_view; - - return info; + return descriptorInfo( *m_sampler, layout ); } ImageView::~ImageView() diff --git a/src/engine/assets/image/ImageView.hpp b/src/engine/assets/image/ImageView.hpp index 7108681..956795f 100644 --- a/src/engine/assets/image/ImageView.hpp +++ b/src/engine/assets/image/ImageView.hpp @@ -16,8 +16,6 @@ namespace fgl::engine { std::shared_ptr< ImageHandle > m_resource; - vk::DescriptorImageInfo m_descriptor_info; - vk::raii::ImageView m_image_view; Sampler m_sampler; @@ -25,6 +23,8 @@ namespace fgl::engine [[nodiscard]] static vk::raii::ImageView createImageView( const std::shared_ptr< ImageHandle >& img ); + [[nodiscard]] vk::DescriptorImageInfo descriptorInfo( vk::Sampler sampler, vk::ImageLayout layout ) const; + public: //! Returns true if the resource has been staged @@ -52,7 +52,6 @@ namespace fgl::engine // void setSampler( Sampler&& sampler ) { m_sampler = std::forward< Sampler >( sampler ); } [[nodiscard]] const Sampler& getSampler() const { return m_sampler; }; - [[nodiscard]] vk::DescriptorImageInfo descriptorInfo( vk::Sampler sampler, vk::ImageLayout layout ) const; [[nodiscard]] vk::DescriptorImageInfo descriptorInfo( vk::ImageLayout layout ) const; ~ImageView(); diff --git a/src/engine/assets/image/Sampler.cpp b/src/engine/assets/image/Sampler.cpp index c6702de..864a634 100644 --- a/src/engine/assets/image/Sampler.cpp +++ b/src/engine/assets/image/Sampler.cpp @@ -6,6 +6,7 @@ #include +#include "engine/debug/logging/logging.hpp" #include "engine/rendering/devices/Device.hpp" namespace fgl::engine @@ -30,6 +31,13 @@ namespace fgl::engine info.addressModeV = sampler_wrap_v; info.addressModeW = sampler_wrap_w; + if ( info.addressModeU == vk::SamplerAddressMode::eClampToBorder + || info.addressModeV == vk::SamplerAddressMode::eClampToBorder + || info.addressModeW == vk::SamplerAddressMode::eClampToBorder ) + { + info.borderColor = vk::BorderColor::eFloatOpaqueWhite; + } + info.minLod = -1000; info.maxLod = 1000; @@ -45,12 +53,12 @@ namespace fgl::engine const vk::SamplerAddressMode sampler_wrap_u, const vk::SamplerAddressMode sampler_wrap_v, const vk::SamplerAddressMode sampler_wrap_w ) : - m_sampler( createSampler( mag_filter, min_filter, mipmap_mode, sampler_wrap_u, sampler_wrap_v, sampler_wrap_w ) ) + m_sampler( createSampler( min_filter, mag_filter, mipmap_mode, sampler_wrap_u, sampler_wrap_v, sampler_wrap_w ) ) {} namespace gl { - vk::Filter filterToVk( int value ) + vk::Filter filterToVk( const int value ) { switch ( value ) { @@ -74,13 +82,19 @@ namespace fgl::engine default: throw std::runtime_error( "Failed to translate wrapping filter to vk address mode" ); case GL_REPEAT: + log::info( "eRepeat" ); return vk::SamplerAddressMode::eRepeat; + case GL_MIRRORED_REPEAT: + log::info( "eMirroredRepeat" ); + return vk::SamplerAddressMode::eMirroredRepeat; #ifdef GL_CLAMP_TO_BORDER case GL_CLAMP_TO_BORDER: + log::info( "eClampToBorder" ); return vk::SamplerAddressMode::eClampToBorder; #endif #ifdef GL_CLAMP_TO_EDGE case GL_CLAMP_TO_EDGE: + log::info( "eClampToEdge" ); return vk::SamplerAddressMode::eClampToEdge; #endif } diff --git a/src/engine/assets/material/Material.hpp b/src/engine/assets/material/Material.hpp index 6d73d73..3fa0d9b 100644 --- a/src/engine/assets/material/Material.hpp +++ b/src/engine/assets/material/Material.hpp @@ -76,51 +76,66 @@ namespace fgl::engine using MaterialID = std::uint32_t; -#define PAD( id, size ) std::byte pad_##id[ size ]; - //! Material data to be sent to the device // Alignas to prevent the struct from becoming bigger then needed struct DeviceMaterialData { - struct Albedo + alignas( 16 ) struct Albedo { TextureID color_texture_id { constants::INVALID_TEXTURE_ID }; - PAD( 1, 12 ); - glm::vec4 color_factors {}; + alignas( 4 * 4 ) glm::vec4 color_factors {}; } color; - struct Metallic + alignas( 16 ) struct Metallic { // Padding to shove metallic_texture_id to offset 32 - TextureID metallic_texture_id { constants::INVALID_TEXTURE_ID }; + alignas( 16 ) TextureID metallic_texture_id { constants::INVALID_TEXTURE_ID }; float metallic_factor { 0.0f }; float roughness_factor { 0.0f }; - PAD( 1, 4 ); } metallic; - struct Normal + alignas( 16 ) struct Normal { TextureID normal_texture_id { constants::INVALID_TEXTURE_ID }; float normal_tex_scale { 0.0f }; - PAD( 1, 8 ); } normal; - struct Occlusion + alignas( 16 ) struct Occlusion { TextureID occlusion_texture_id { constants::INVALID_TEXTURE_ID }; float occlusion_tex_strength { 0.0f }; - PAD( 1, 8 ); } occlusion; - struct Emissive + alignas( 16 ) struct Emissive { TextureID emissive_texture_id { constants::INVALID_TEXTURE_ID }; - glm::vec3 emissive_factors { 0.0f, 0.0f, 0.0f }; + alignas( 4 * 4 ) glm::vec3 emissive_factors { 0.0f, 0.0f, 0.0f }; } emissive; DeviceMaterialData() = default; }; + static_assert( offsetof( DeviceMaterialData, color ) == 0 ); + static_assert( offsetof( DeviceMaterialData::Albedo, color_texture_id ) == 0 ); + static_assert( sizeof( DeviceMaterialData::Albedo::color_texture_id ) == 4 ); + static_assert( offsetof( DeviceMaterialData::Albedo, color_factors ) == 16 ); + static_assert( sizeof( DeviceMaterialData::Albedo ) == 32 ); + + static_assert( offsetof( DeviceMaterialData, metallic ) == 32 ); + static_assert( offsetof( DeviceMaterialData::Metallic, metallic_texture_id ) == 0 ); + static_assert( sizeof( DeviceMaterialData::Metallic::metallic_texture_id ) == 4 ); + static_assert( offsetof( DeviceMaterialData::Metallic, metallic_factor ) == 4 ); + static_assert( offsetof( DeviceMaterialData::Metallic, roughness_factor ) == 8 ); + static_assert( sizeof( DeviceMaterialData::Metallic ) == 16 ); + + static_assert( offsetof( DeviceMaterialData, emissive ) == 80 ); + static_assert( offsetof( DeviceMaterialData::Emissive, emissive_texture_id ) == 0 ); + static_assert( sizeof( DeviceMaterialData::Emissive::emissive_texture_id ) == 4 ); + static_assert( offsetof( DeviceMaterialData::Emissive, emissive_factors ) == 16 ); + static_assert( sizeof( DeviceMaterialData::Emissive ) == 32 ); + + static_assert( sizeof( DeviceMaterialData ) == 112 ); + /* static_assert( sizeof( DeviceMaterialData ) == 76 ); static_assert( offsetof( DeviceMaterialData, color_factors ) == 16 ); diff --git a/src/engine/assets/model/Model.cpp b/src/engine/assets/model/Model.cpp index a1a1437..be6698b 100644 --- a/src/engine/assets/model/Model.cpp +++ b/src/engine/assets/model/Model.cpp @@ -91,7 +91,12 @@ namespace fgl::engine std::vector< PrimitiveInstanceInfoIndex > primitive_instances {}; - constexpr ModelInstanceInfo model_info {}; + WorldTransform transform {}; + transform.translation = Coordinate< CoordinateSpace::World >( glm::vec3( 0.0, 0.0, 0.0 ) ); + transform.scale = glm::vec3( 0.007 ); + transform.rotation = { glm::quat( 1.0, 0.0, 0.0, 0.0 ) }; + + const ModelInstanceInfo model_info { transform.mat4() }; ModelInstanceInfoIndex model_instance { buffers.m_model_instances.acquire( model_info ) }; diff --git a/src/engine/assets/model/Model.hpp b/src/engine/assets/model/Model.hpp index 2a4f428..8730a90 100644 --- a/src/engine/assets/model/Model.hpp +++ b/src/engine/assets/model/Model.hpp @@ -77,7 +77,7 @@ namespace fgl::engine struct PerVertexInstanceInfo { - glm::mat4x4 m_model_matrix; + alignas( 4 * 4 ) glm::mat4x4 m_model_matrix; MaterialID material_id; }; @@ -87,7 +87,7 @@ namespace fgl::engine static_assert( offsetof( PerVertexInstanceInfo, material_id ) == 64 ); static_assert( sizeof( MaterialID ) == 4 ); - static_assert( sizeof( PerVertexInstanceInfo ) == 64 + 4 ); + static_assert( sizeof( PerVertexInstanceInfo ) == 64 + ( 4 * 4 ) ); struct ModelGPUBuffers { diff --git a/src/engine/assets/model/ModelInstance.hpp b/src/engine/assets/model/ModelInstance.hpp index 8480489..ba165c8 100644 --- a/src/engine/assets/model/ModelInstance.hpp +++ b/src/engine/assets/model/ModelInstance.hpp @@ -2,7 +2,6 @@ // Created by kj16609 on 3/17/25. // #pragma once -#include #include @@ -13,20 +12,8 @@ namespace fgl::engine { class Model; - struct ModelGPUInstance - { - //! Index of the model - std::uint32_t m_model_index; - glm::mat4x4 m_transform; - }; - using InstanceIndex = std::uint32_t; - struct ModelMatrixInfo - { - glm::mat4 model_matrix; - }; - class ModelInstance { std::shared_ptr< Model > m_model; diff --git a/src/engine/assets/model/ModelInstanceInfo.hpp b/src/engine/assets/model/ModelInstanceInfo.hpp index 6f024f0..ea54fd7 100644 --- a/src/engine/assets/model/ModelInstanceInfo.hpp +++ b/src/engine/assets/model/ModelInstanceInfo.hpp @@ -9,7 +9,7 @@ namespace fgl::engine struct ModelInstanceInfo { - glm::mat4 m_matrix { constants::MAT4_IDENTITY }; + glm::mat4 m_matrix { glm::mat4( 0.007 ) }; }; using ModelInstanceInfoIndex = IndexedVector< ModelInstanceInfo >::Index; diff --git a/src/engine/assets/texture/Texture.cpp b/src/engine/assets/texture/Texture.cpp index f8e5c9b..44cbc9b 100644 --- a/src/engine/assets/texture/Texture.cpp +++ b/src/engine/assets/texture/Texture.cpp @@ -116,7 +116,8 @@ namespace fgl::engine format ) {} - Texture::Texture( std::vector< std::byte >&& data, const vk::Extent2D extent, Sampler&&, const vk::Format format ) : + Texture::Texture( + std::vector< std::byte >&& data, const vk::Extent2D extent, Sampler&& sampler, const vk::Format format ) : m_texture_id( texture_id_pool.getID() ), m_image( std::make_shared< Image >( @@ -125,7 +126,7 @@ namespace fgl::engine vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled, vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal ) ), - m_image_view( m_image->getView() ), + m_image_view( m_image->getView( std::forward< Sampler >( sampler ) ) ), m_extent( extent ), m_name( "Default Texture Name" ) { @@ -211,15 +212,6 @@ namespace fgl::engine return m_imgui_set; } - Texture::Texture( const std::shared_ptr< Image >& image, Sampler sampler ) : - m_texture_id( texture_id_pool.getID() ), - m_image( image ), - m_image_view( image->getView( std::move( sampler ) ) ), - //TODO: Figure out how to get extents from images. - m_extent( image->getExtent() ), - m_name( "Default Texture Name" ) - {} - Texture::Texture( const std::shared_ptr< Image >& image, Sampler&& sampler ) : m_texture_id( texture_id_pool.getID() ), m_image( image ), diff --git a/src/engine/assets/texture/Texture.hpp b/src/engine/assets/texture/Texture.hpp index f022eb9..8290a53 100644 --- a/src/engine/assets/texture/Texture.hpp +++ b/src/engine/assets/texture/Texture.hpp @@ -93,7 +93,6 @@ namespace fgl::engine Texture() = delete; ~Texture(); - Texture( const std::shared_ptr< Image >& image, Sampler sampler = Sampler() ); Texture( const std::shared_ptr< Image >& image, Sampler&& sampler ); Image& getImageRef(); diff --git a/src/engine/camera/Camera.cpp b/src/engine/camera/Camera.cpp index 68037ca..eae18e1 100644 --- a/src/engine/camera/Camera.cpp +++ b/src/engine/camera/Camera.cpp @@ -345,7 +345,7 @@ namespace fgl::engine m_composite_swapchain( std::make_unique< CompositeSwapchain >( m_target_extent ) ), m_gbuffer_swapchain( std::make_unique< GBufferSwapchain >( m_target_extent ) ), m_camera_renderer( renderer ), - m_camera_frame_info( buffer, constants::MAX_FRAMES_IN_FLIGHT ) + m_camera_frame_info( buffer ) { FGL_ASSERT( renderer, "Camera renderer is null" ); this->setPerspectiveProjection( m_fov_y, aspectRatio(), constants::NEAR_PLANE, constants::FAR_PLANE ); diff --git a/src/engine/camera/CompositeSwapchain.cpp b/src/engine/camera/CompositeSwapchain.cpp index 0c0327d..245f5b4 100644 --- a/src/engine/camera/CompositeSwapchain.cpp +++ b/src/engine/camera/CompositeSwapchain.cpp @@ -100,7 +100,8 @@ namespace fgl::engine for ( const auto& image : m_buffer.m_target.m_attachment_resources.m_images ) { - m_gbuffer_target.emplace_back( std::make_unique< Texture >( image ) ); + Sampler default_sampler {}; + m_gbuffer_target.emplace_back( std::make_unique< Texture >( image, std::move( default_sampler ) ) ); } } diff --git a/src/engine/camera/GBufferRenderer.cpp b/src/engine/camera/GBufferRenderer.cpp index e693321..446b67d 100644 --- a/src/engine/camera/GBufferRenderer.cpp +++ b/src/engine/camera/GBufferRenderer.cpp @@ -4,7 +4,6 @@ #include "GBufferRenderer.hpp" -#include "Camera.hpp" #include "GBufferSwapchain.hpp" #include "engine/rendering/renderpass/RenderPass.hpp" diff --git a/src/engine/descriptors/Descriptor.hpp b/src/engine/descriptors/Descriptor.hpp index 5016741..3caa568 100644 --- a/src/engine/descriptors/Descriptor.hpp +++ b/src/engine/descriptors/Descriptor.hpp @@ -21,12 +21,27 @@ namespace fgl::engine::descriptors consteval Descriptor() = delete; + private: + + [[nodiscard]] constexpr vk::DescriptorSetLayoutBinding generateLayoutBinding() const + { + vk::DescriptorSetLayoutBinding layout_binding; + layout_binding.binding = m_index; + layout_binding.descriptorType = m_type; + layout_binding.descriptorCount = m_count; + layout_binding.stageFlags = m_stage_flags; + layout_binding.pImmutableSamplers = nullptr; + return layout_binding; + } + + public: + constexpr Descriptor( const std::uint16_t binding_idx, const vk::DescriptorType type, const vk::ShaderStageFlags stage_flags, const std::uint16_t count = 1, - const vk::DescriptorBindingFlags binding_flags = static_cast< vk::DescriptorBindingFlags >( 0 ) ) : + const vk::DescriptorBindingFlags binding_flags = vk::DescriptorBindingFlags {} ) : m_index( binding_idx ), m_type( type ), m_stage_flags( stage_flags ), @@ -35,18 +50,9 @@ namespace fgl::engine::descriptors m_layout_binding( generateLayoutBinding() ) {} - constexpr vk::DescriptorSetLayoutBinding generateLayoutBinding() - { - vk::DescriptorSetLayoutBinding layout_binding; - layout_binding.binding = m_index; - layout_binding.descriptorType = m_type; - layout_binding.descriptorCount = m_count; - layout_binding.stageFlags = m_stage_flags; - layout_binding.pImmutableSamplers = VK_NULL_HANDLE; - return layout_binding; - } - vk::DescriptorSetLayoutBinding m_layout_binding; + + virtual ~Descriptor() = default; }; struct ImageDescriptor : Descriptor @@ -71,7 +77,7 @@ namespace fgl::engine::descriptors { StorageDescriptor() = delete; - StorageDescriptor( std::uint16_t idx, vk::ShaderStageFlags stage_flags ) : + constexpr StorageDescriptor( std::uint16_t idx, vk::ShaderStageFlags stage_flags ) : Descriptor( idx, vk::DescriptorType::eStorageBuffer, stage_flags ) {} }; @@ -80,7 +86,7 @@ namespace fgl::engine::descriptors { UniformDescriptor() = delete; - UniformDescriptor( const std::uint16_t idx, vk::ShaderStageFlags stage_flags ) : + constexpr UniformDescriptor( const std::uint16_t idx, vk::ShaderStageFlags stage_flags ) : Descriptor( idx, vk::DescriptorType::eUniformBuffer, stage_flags ) {} }; diff --git a/src/engine/descriptors/DescriptorSet.cpp b/src/engine/descriptors/DescriptorSet.cpp index 9a49c84..43e4f7d 100644 --- a/src/engine/descriptors/DescriptorSet.cpp +++ b/src/engine/descriptors/DescriptorSet.cpp @@ -65,7 +65,7 @@ namespace fgl::engine::descriptors write.dstArrayElement = 0; write.descriptorCount = 1; write.descriptorType = vk::DescriptorType::eUniformBuffer; - write.pBufferInfo = &( std::get< vk::DescriptorBufferInfo >( m_infos.data()[ binding_idx ] ) ); + write.pBufferInfo = &( std::get< vk::DescriptorBufferInfo >( m_infos[ binding_idx ] ) ); write.pImageInfo = VK_NULL_HANDLE; write.pTexelBufferView = VK_NULL_HANDLE; @@ -118,16 +118,13 @@ namespace fgl::engine::descriptors m_descriptor_writes.push_back( write ); } - void DescriptorSet::bindImage( - const std::uint32_t binding_idx, - const ImageView& view, - const vk::ImageLayout layout, - const vk::raii::Sampler& sampler ) + void DescriptorSet:: + bindImage( const std::uint32_t binding_idx, const ImageView& view, const vk::ImageLayout layout ) { assert( binding_idx < m_infos.size() && "Binding index out of range" ); //Store info - m_infos[ binding_idx ] = view.descriptorInfo( sampler, layout ); + m_infos[ binding_idx ] = view.descriptorInfo( layout ); vk::WriteDescriptorSet write {}; write.dstSet = m_set; @@ -155,8 +152,7 @@ namespace fgl::engine::descriptors Texture& tex { *tex_ptr }; - m_infos[ binding_idx ] = tex.getImageView().descriptorInfo( - tex.getImageView().getSampler().getVkSampler(), vk::ImageLayout::eShaderReadOnlyOptimal ); + m_infos[ binding_idx ] = tex.getImageView().descriptorInfo( vk::ImageLayout::eShaderReadOnlyOptimal ); vk::WriteDescriptorSet write {}; write.dstSet = m_set; @@ -187,16 +183,13 @@ namespace fgl::engine::descriptors m_infos.resize( m_binding_count ); } - void DescriptorSet::bindAttachment( - const std::uint32_t binding_idx, - const ImageView& view, - const vk::ImageLayout layout, - const vk::raii::Sampler& sampler ) + void DescriptorSet:: + bindAttachment( const std::uint32_t binding_idx, const ImageView& view, const vk::ImageLayout layout ) { assert( binding_idx < m_infos.size() && "Binding index out of range" ); //Store info - m_infos[ binding_idx ] = view.descriptorInfo( sampler, layout ); + m_infos[ binding_idx ] = view.descriptorInfo( layout ); vk::WriteDescriptorSet write {}; write.dstSet = m_set; diff --git a/src/engine/descriptors/DescriptorSet.hpp b/src/engine/descriptors/DescriptorSet.hpp index 8602219..df96029 100644 --- a/src/engine/descriptors/DescriptorSet.hpp +++ b/src/engine/descriptors/DescriptorSet.hpp @@ -75,11 +75,7 @@ namespace fgl::engine::descriptors ~DescriptorSet(); - void bindImage( - std::uint32_t binding_idx, - const ImageView& view, - vk::ImageLayout layout, - const vk::raii::Sampler& sampler = VK_NULL_HANDLE ); + void bindImage( std::uint32_t binding_idx, const ImageView& view, vk::ImageLayout layout ); void bindUniformBuffer( std::uint32_t binding_idx, const memory::BufferSuballocation& buffer ); void bindStorageBuffer( std::uint32_t binding_idx, const memory::BufferSuballocation& buffer ); @@ -89,11 +85,7 @@ namespace fgl::engine::descriptors std::size_t array_idx, std::size_t item_size ); - void bindAttachment( - std::uint32_t binding_idx, - const ImageView& view, - vk::ImageLayout layout, - const vk::raii::Sampler& sampler = VK_NULL_HANDLE ); + void bindAttachment( std::uint32_t binding_idx, const ImageView& view, vk::ImageLayout layout ); void bindTexture( std::uint32_t binding_idx, const std::shared_ptr< Texture >& tex_ptr ); diff --git a/src/engine/gameobjects/components/ModelComponent.hpp b/src/engine/gameobjects/components/ModelComponent.hpp index eec4852..e52f362 100644 --- a/src/engine/gameobjects/components/ModelComponent.hpp +++ b/src/engine/gameobjects/components/ModelComponent.hpp @@ -7,6 +7,7 @@ #include "ComponentIDS.hpp" #include "TransformComponent.hpp" +#include "assets/model/ModelInstance.hpp" #include "interface/GameObjectComponent.hpp" namespace fgl::engine @@ -39,6 +40,15 @@ namespace fgl::engine::components virtual ~ModelComponent() override {} + TransformComponent getTransform() const + { + return m_transform; + } + void updateTransform( TransformComponent & transform ) + { + m_transform = transform; + } + // Model* operator->(); // const Model* operator->() const; diff --git a/src/engine/gameobjects/components/TransformComponent.hpp b/src/engine/gameobjects/components/TransformComponent.hpp index 1213e92..2437dc2 100644 --- a/src/engine/gameobjects/components/TransformComponent.hpp +++ b/src/engine/gameobjects/components/TransformComponent.hpp @@ -3,6 +3,7 @@ // #pragma once #include "ComponentIDS.hpp" +#include "assets/model/ModelInstanceInfo.hpp" #include "interface/GameObjectComponent.hpp" namespace fgl::engine::components @@ -11,6 +12,7 @@ namespace fgl::engine::components COMPONENT_CLASS( TransformComponent, TransformComponentID ) { WorldTransform m_transform; + std::shared_ptr< ModelInstanceInfoIndex > m_model_instance_info_index; public: diff --git a/src/engine/lighting/shadows/ShadowMap.cpp b/src/engine/lighting/shadows/ShadowMap.cpp index 6e828da..ba559fe 100644 --- a/src/engine/lighting/shadows/ShadowMap.cpp +++ b/src/engine/lighting/shadows/ShadowMap.cpp @@ -33,7 +33,9 @@ namespace fgl::engine::shadows { PerFrameArray< std::shared_ptr< Texture > > array {}; - for ( std::size_t i = 0; i < array.size(); ++i ) array[ i ] = std::make_shared< Texture >( m_image[ i ] ); + Sampler default_sampler {}; + for ( std::size_t i = 0; i < array.size(); ++i ) + array[ i ] = std::make_shared< Texture >( m_image[ i ], std::move( default_sampler ) ); return array; } @@ -47,11 +49,6 @@ namespace fgl::engine::shadows const Matrix< MatrixType::CameraToScreen > identity { 1.0f }; const Matrix< MatrixType::WorldToScreen > matrix { camera_matrix * identity }; - - - - - } ShadowMap::ShadowMap( const vk::Extent2D extent ) : diff --git a/src/engine/memory/buffers/HostSingleT.hpp b/src/engine/memory/buffers/HostSingleT.hpp index e98cb01..4c4c4cd 100644 --- a/src/engine/memory/buffers/HostSingleT.hpp +++ b/src/engine/memory/buffers/HostSingleT.hpp @@ -30,6 +30,7 @@ namespace fgl::engine HostSingleT& operator=( T& t ) { + FGL_ASSERT( this->ptr(), "Invalid host pointer for HostSingleT!" ); *static_cast< T* >( this->ptr() ) = t; flush(); diff --git a/src/engine/memory/buffers/UniqueFrameSuballocation.hpp b/src/engine/memory/buffers/UniqueFrameSuballocation.hpp index 26b11c3..c6994a7 100644 --- a/src/engine/memory/buffers/UniqueFrameSuballocation.hpp +++ b/src/engine/memory/buffers/UniqueFrameSuballocation.hpp @@ -18,8 +18,9 @@ namespace fgl::engine public: - PerFrameSuballocation( memory::Buffer& buffer, const std::uint32_t frames_in_flight ) : m_buffer( buffer ) + PerFrameSuballocation( memory::Buffer& buffer ) : m_buffer( buffer ) { + constexpr auto frames_in_flight { constants::MAX_FRAMES_IN_FLIGHT }; m_suballocations.reserve( frames_in_flight ); for ( std::uint16_t i = 0; i < frames_in_flight; ++i ) { @@ -39,11 +40,6 @@ namespace fgl::engine return *m_suballocations[ index ]; } - - void bindForFrame( vk::raii::CommandBuffer& cmd_buffer, std::uint16_t frame_idx ) - { - m_suballocations[ frame_idx ].bind( cmd_buffer ); - } }; } // namespace fgl::engine \ No newline at end of file diff --git a/src/engine/memory/buffers/vector/DeviceVector.hpp b/src/engine/memory/buffers/vector/DeviceVector.hpp index 6f3c235..25e88be 100644 --- a/src/engine/memory/buffers/vector/DeviceVector.hpp +++ b/src/engine/memory/buffers/vector/DeviceVector.hpp @@ -7,6 +7,7 @@ #include "BufferVector.hpp" #include "concepts.hpp" #include "engine/assets/transfer/TransferManager.hpp" +#include "engine/debug/logging/logging.hpp" namespace fgl::engine::memory { @@ -42,6 +43,9 @@ namespace fgl::engine DeviceVector( buffer, static_cast< std::uint32_t >( data.size() ) ) { memory::TransferManager::getInstance().copyToVector< T, DeviceVector< T > >( data, *this ); + + log::debug( + "Allocated device vector of size: {}, With stride: {} at offset {}", size(), stride(), m_offset ); } // void resize( const std::size_t new_size ) { BufferVector::resize( new_size ); } diff --git a/src/engine/memory/buffers/vector/IndexedVector.hpp b/src/engine/memory/buffers/vector/IndexedVector.hpp index 62e0a42..e6610cc 100644 --- a/src/engine/memory/buffers/vector/IndexedVector.hpp +++ b/src/engine/memory/buffers/vector/IndexedVector.hpp @@ -17,10 +17,6 @@ namespace fgl::engine { if ( m_free_indexes.empty() ) { - log::warn( - "IndexedVector had to resize due to limited space. Size: {} Capacity: {}", - this->size(), - this->capacity() ); this->resize( this->size() + 1 ); m_free_indexes.push( this->size() - 1 ); } @@ -95,10 +91,6 @@ namespace fgl::engine { if ( m_free_indexes.empty() ) { - log::warn( - "IndexedVector had to resize due to limited space. Size: {} Capacity: {}", - this->size(), - this->capacity() ); this->resize( this->size() + 1 ); m_free_indexes.push( this->size() - 1 ); } diff --git a/src/engine/rendering/PresentSwapChain.cpp b/src/engine/rendering/PresentSwapChain.cpp index 2b4bd6d..d1c32ad 100644 --- a/src/engine/rendering/PresentSwapChain.cpp +++ b/src/engine/rendering/PresentSwapChain.cpp @@ -35,7 +35,7 @@ namespace fgl::engine init(); m_render_attachments.m_color.linkImages( m_swap_chain_images ); - m_render_attachments.m_color.setName( "PresetnSwapChain::color" ); + m_render_attachments.m_color.setName( "PresentSwapChain::color" ); m_render_attachments.m_depth.createResources( imageCount(), getSwapChainExtent() ); m_render_attachments.m_depth.setName( "PresentSwapChain::Depth" ); @@ -178,6 +178,7 @@ namespace fgl::engine void PresentSwapChain:: transitionImages( const CommandBuffer& command_buffer, const StageID stage_id, const FrameIndex frame_index ) + const { switch ( stage_id ) { @@ -196,7 +197,7 @@ namespace fgl::engine }; command_buffer->pipelineBarrier( - vk::PipelineStageFlagBits::eTopOfPipe, + vk::PipelineStageFlagBits::eBottomOfPipe, vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests, diff --git a/src/engine/rendering/PresentSwapChain.hpp b/src/engine/rendering/PresentSwapChain.hpp index 61de71a..838a5d2 100644 --- a/src/engine/rendering/PresentSwapChain.hpp +++ b/src/engine/rendering/PresentSwapChain.hpp @@ -104,7 +104,7 @@ namespace fgl::engine [[nodiscard]] std::pair< vk::Result, PresentIndex > acquireNextImage(); [[nodiscard]] vk::Result submitCommandBuffers( const CommandBuffer& buffers, PresentIndex present_index ); - void transitionImages( const CommandBuffer& command_buffer, StageID stage_id, FrameIndex frame_index ); + void transitionImages( const CommandBuffer& command_buffer, StageID stage_id, FrameIndex frame_index ) const; }; template < typename T > diff --git a/src/engine/rendering/Renderer.cpp b/src/engine/rendering/Renderer.cpp index eb55206..43e404d 100644 --- a/src/engine/rendering/Renderer.cpp +++ b/src/engine/rendering/Renderer.cpp @@ -215,9 +215,9 @@ namespace fgl::engine // auto& command_buffer { getCurrentCommandbuffer() }; // Get a primary command buffer - const auto primary_cmd { - Device::getInstance().getCmdBufferPool().getCommandBuffer( CommandBufferHandle::Primary ) - }; + auto primary_cmd { Device::getInstance().getCmdBufferPool().getCommandBuffer( CommandBufferHandle::Primary ) }; + + primary_cmd.setName( "Primary command buffer" ); vk::CommandBufferBeginInfo begin_info {}; begin_info.pNext = VK_NULL_HANDLE; @@ -225,13 +225,23 @@ namespace fgl::engine primary_cmd->begin( begin_info ); buffers.transfer_cb->end(); + buffers.transfer_cb.setName( "Transfer Commands" ); buffers.render_cb->end(); + buffers.render_cb.setName( "Render Commands" ); buffers.composition_cb->end(); + buffers.composition_cb.setName( "Composition Commands" ); buffers.imgui_cb->end(); + buffers.imgui_cb.setName( "ImGui Commands" ); // run all secondary command buffers primary_cmd->executeCommands( - { *buffers.transfer_cb, *buffers.render_cb, *buffers.composition_cb, *buffers.imgui_cb } ); + // { *buffers.transfer_cb, *buffers.render_cb, *buffers.composition_cb, *buffers.imgui_cb } ); + { *buffers.transfer_cb, *buffers.render_cb, *buffers.composition_cb } ); + + primary_cmd->pipelineBarrier( + vk::PipelineStageFlagBits::eAllCommands, vk::PipelineStageFlagBits::eAllCommands, {}, {}, {}, {} ); + + primary_cmd->executeCommands( { *buffers.imgui_cb } ); primary_cmd->end(); diff --git a/src/engine/rendering/pipelines/shaders/Compiler.cpp b/src/engine/rendering/pipelines/shaders/Compiler.cpp index 6586eec..1c3e2ec 100644 --- a/src/engine/rendering/pipelines/shaders/Compiler.cpp +++ b/src/engine/rendering/pipelines/shaders/Compiler.cpp @@ -107,9 +107,11 @@ namespace fgl::engine { .name = CompilerOptionName::Optimization, .value = { .kind = CompilerOptionValueKind::Int, .intValue0 = static_cast< int32_t >( SLANG_OPTIMIZATION_LEVEL_NONE ) } }, + // .intValue0 = static_cast< int32_t >( SLANG_OPTIMIZATION_LEVEL_HIGH ) } }, { .name = CompilerOptionName::DebugInformation, .value = { .kind = CompilerOptionValueKind::Int, .intValue0 = static_cast< int32_t >( SLANG_DEBUG_INFO_LEVEL_MAXIMAL ) } }, + // .intValue0 = static_cast< int32_t >( SLANG_DEBUG_INFO_LEVEL_MINIMAL ) } }, { .name = CompilerOptionName::EmitSpirvDirectly, .value = { .kind = CompilerOptionValueKind::Int, .intValue0 = static_cast< int32_t >( true ) } }, } }; diff --git a/src/engine/rendering/pipelines/v2/Pipeline.cpp b/src/engine/rendering/pipelines/v2/Pipeline.cpp index 917e72d..0c2a692 100644 --- a/src/engine/rendering/pipelines/v2/Pipeline.cpp +++ b/src/engine/rendering/pipelines/v2/Pipeline.cpp @@ -39,6 +39,7 @@ namespace fgl::engine catch ( std::runtime_error& e ) { log::warn( "Failed to recompile pipeline! Shader error!" ); + m_pipeline = VK_NULL_HANDLE; } } @@ -58,9 +59,9 @@ namespace fgl::engine command_buffer->bindDescriptorSets( m_bind_point, m_layout, descriptor_idx, sets, offsets ); } - void Pipeline::bindDescriptor( CommandBuffer& comd_buffer, descriptors::DescriptorSet& set ) + void Pipeline::bindDescriptor( CommandBuffer& cmd_buffer, descriptors::DescriptorSet& set ) { - bindDescriptor( comd_buffer, set.setIDX(), set ); + bindDescriptor( cmd_buffer, set.setIDX(), set ); } void Pipeline::setDebugName( const char* str ) diff --git a/src/engine/rendering/pipelines/v2/Pipeline.hpp b/src/engine/rendering/pipelines/v2/Pipeline.hpp index 04a0be8..1fd4969 100644 --- a/src/engine/rendering/pipelines/v2/Pipeline.hpp +++ b/src/engine/rendering/pipelines/v2/Pipeline.hpp @@ -37,7 +37,7 @@ namespace fgl::engine void bindDescriptor( CommandBuffer&, descriptors::DescriptorIDX descriptor_idx, descriptors::DescriptorSet& set ); - void bindDescriptor( CommandBuffer& comd_buffer, descriptors::DescriptorSet& set ); + void bindDescriptor( CommandBuffer& cmd_buffer, descriptors::DescriptorSet& set ); void setDebugName( const char* str ); diff --git a/src/engine/systems/composition/GuiSystem.cpp b/src/engine/systems/composition/GuiSystem.cpp index 1912871..81958f2 100644 --- a/src/engine/systems/composition/GuiSystem.cpp +++ b/src/engine/systems/composition/GuiSystem.cpp @@ -30,6 +30,7 @@ namespace fgl::engine builder.setFragmentShader( Shader::loadFragment( "shaders/gui-compose.slang" ) ); builder.addColorAttachment().setFormat( pickPresentFormat() ).finish(); + builder.addDepthAttachment(); m_pipeline = builder.create(); m_pipeline->setDebugName( "Gui Pipeline" ); diff --git a/src/engine/systems/prerender/CullingSystem.cpp b/src/engine/systems/prerender/CullingSystem.cpp index b069779..70f6547 100644 --- a/src/engine/systems/prerender/CullingSystem.cpp +++ b/src/engine/systems/prerender/CullingSystem.cpp @@ -85,7 +85,8 @@ namespace fgl::engine command_buffer->pipelineBarrier( vk::PipelineStageFlagBits::eComputeShader, // Source: Compute shader vk::PipelineStageFlagBits::eDrawIndirect | // Destination: Indirect drawing - vk::PipelineStageFlagBits::eVertexInput, // ... and vertex input + vk::PipelineStageFlagBits::eVertexInput + | vk::PipelineStageFlagBits::eFragmentShader, // ... and vertex input {}, // Dependency flags { memory_barrier }, // Memory barrier for synchronization {}, // No buffer barrier diff --git a/src/engine/systems/render/EntityRendererSystem.cpp b/src/engine/systems/render/EntityRendererSystem.cpp index ce07c98..c721f05 100644 --- a/src/engine/systems/render/EntityRendererSystem.cpp +++ b/src/engine/systems/render/EntityRendererSystem.cpp @@ -38,6 +38,8 @@ namespace fgl::engine builder.setAttributeDescriptions( ModelVertex::getAttributeDescriptions() ); builder.setBindingDescriptions( ModelVertex::getBindingDescriptions() ); + builder.addDepthAttachment(); + m_textured_pipeline = builder.create(); m_textured_pipeline->setDebugName( "Textured entity pipeline" ); } diff --git a/src/engine/systems/render/EntityRendererSystem.hpp b/src/engine/systems/render/EntityRendererSystem.hpp index 7166485..e5ec048 100644 --- a/src/engine/systems/render/EntityRendererSystem.hpp +++ b/src/engine/systems/render/EntityRendererSystem.hpp @@ -6,9 +6,6 @@ #include -#include "assets/model/ModelInstance.hpp" -#include "engine/assets/model/Model.hpp" -#include "engine/memory/buffers/vector/HostVector.hpp" #include "engine/rendering/PresentSwapChain.hpp" namespace fgl::engine @@ -32,24 +29,11 @@ namespace fgl::engine std::unique_ptr< Pipeline > m_textured_pipeline; // std::unique_ptr< ComputePipeline > m_cull_pipeline {}; - using DrawParameterBufferSuballocation = HostVector< vk::DrawIndexedIndirectCommand >; - - using ModelMatrixInfoBufferSuballocation = HostVector< ModelMatrixInfo >; - - // Simple parameter buffers - PerFrameArray< std::unique_ptr< DrawParameterBufferSuballocation > > m_draw_simple_parameter_buffers {}; - PerFrameArray< std::unique_ptr< ModelMatrixInfoBufferSuballocation > > m_simple_model_matrix_info_buffers {}; - - // Textured parameter buffers - PerFrameArray< std::unique_ptr< DrawParameterBufferSuballocation > > m_draw_textured_parameter_buffers {}; - PerFrameArray< std::unique_ptr< ModelMatrixInfoBufferSuballocation > > m_textured_model_matrix_info_buffers {}; - CommandBuffer& setupSystem( const FrameInfo& ); public: void pass( FrameInfo& info ); - void texturelessPass( const FrameInfo& info ); void texturedPass( const FrameInfo& info ); EntityRendererSystem(); diff --git a/src/shaders/culling.slang b/src/shaders/culling.slang index 91ed11d..55f78b4 100644 --- a/src/shaders/culling.slang +++ b/src/shaders/culling.slang @@ -20,7 +20,7 @@ StructuredBuffer< PrimitiveRenderInfo > primitives : PRIMITIVES; [[vk::binding(0,1)]] StructuredBuffer< PrimitiveInstanceInfo > primitive_instances : PRIMITIVE_INSTANCES; -[ [ vk::binding( 1, 1 ) ] ] +[[vk::binding(1,1)]] StructuredBuffer< ModelInstanceInfo > model_instances : MODEL_INSTANCES; // out @@ -28,8 +28,8 @@ StructuredBuffer< ModelInstanceInfo > model_instances : MODEL_INSTANCES; RWStructuredBuffer< vk::DrawIndexedIndirectCommand > commands : COMMANDS; // vertex info generated from compute shader. This information is used in the rendering process -[ [ vk::binding( 1, 2 ) ] ] -RWStructuredBuffer< InstanceRenderInfo, ScalarDataLayout > out_instances : OUT_INSTANCES; +[[vk::binding(1,2)]] +RWStructuredBuffer< InstanceRenderInfo > out_instances : OUT_INSTANCES; //TODO: shader command constants struct PushConstants