diff --git a/dependencies/tracy b/dependencies/tracy index af73dba..37aff70 160000 --- a/dependencies/tracy +++ b/dependencies/tracy @@ -1 +1 @@ -Subproject commit af73dba73ec90182e5484d3c67197c25fd1a833e +Subproject commit 37aff70dfa50cf6307b3fee6074d627dc2929143 diff --git a/src/engine/Device.cpp b/src/engine/Device.cpp index 7d63a8f..86e6023 100644 --- a/src/engine/Device.cpp +++ b/src/engine/Device.cpp @@ -82,6 +82,7 @@ namespace fgl::engine // class member functions Device::Device( Window& window ) : m_window { window } { + ZoneScoped; createInstance(); setupDebugMessenger(); createSurface(); @@ -97,6 +98,7 @@ namespace fgl::engine Device::~Device() { + ZoneScoped; vkDestroyCommandPool( device_, m_commandPool, nullptr ); vkDestroyDevice( device_, nullptr ); @@ -111,6 +113,7 @@ namespace fgl::engine void Device::createInstance() { + ZoneScoped; if ( enableValidationLayers && !checkValidationLayerSupport() ) { throw std::runtime_error( "validation layers requested, but not available!" ); @@ -153,6 +156,7 @@ namespace fgl::engine void Device::pickPhysicalDevice() { + ZoneScoped; std::vector< vk::PhysicalDevice > devices { m_instance.enumeratePhysicalDevices() }; bool found { false }; @@ -177,6 +181,7 @@ namespace fgl::engine void Device::createLogicalDevice() { + ZoneScoped; const QueueFamilyIndices indices { findQueueFamilies( m_physical_device ) }; std::vector< vk::DeviceQueueCreateInfo > queueCreateInfos; @@ -252,6 +257,7 @@ namespace fgl::engine void Device::createCommandPool() { + ZoneScoped; QueueFamilyIndices queueFamilyIndices = findPhysicalQueueFamilies(); vk::CommandPoolCreateInfo poolInfo = {}; @@ -271,6 +277,7 @@ namespace fgl::engine bool Device::isDeviceSuitable( vk::PhysicalDevice device ) { + ZoneScoped; const QueueFamilyIndices indices { findQueueFamilies( device ) }; const bool extensionsSupported { checkDeviceExtensionSupport( device ) }; @@ -297,6 +304,7 @@ namespace fgl::engine void Device::populateDebugMessengerCreateInfo( vk::DebugUtilsMessengerCreateInfoEXT& createInfo ) { + ZoneScoped; createInfo.messageSeverity = vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning | vk::DebugUtilsMessageSeverityFlagBitsEXT::eError; createInfo.messageType = vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral @@ -308,6 +316,7 @@ namespace fgl::engine void Device::setupDebugMessenger() { + ZoneScoped; if ( !enableValidationLayers ) return; pfnVkCreateDebugUtilsMessengerEXT = reinterpret_cast< @@ -340,6 +349,7 @@ namespace fgl::engine bool Device::checkValidationLayerSupport() { + ZoneScoped; std::vector< vk::LayerProperties > availableLayers { vk::enumerateInstanceLayerProperties() }; for ( const char* layerName : validationLayers ) @@ -366,6 +376,7 @@ namespace fgl::engine std::vector< const char* > Device::getRequiredExtensions() { + ZoneScoped; uint32_t glfwExtensionCount = 0; const char** glfwExtensions; glfwExtensions = glfwGetRequiredInstanceExtensions( &glfwExtensionCount ); @@ -382,6 +393,7 @@ namespace fgl::engine void Device::hasGflwRequiredInstanceExtensions() { + ZoneScoped; std::vector< vk::ExtensionProperties > extensions { vk::enumerateInstanceExtensionProperties() }; std::cout << "available extensions:" << std::endl; @@ -408,6 +420,7 @@ namespace fgl::engine bool Device::checkDeviceExtensionSupport( vk::PhysicalDevice device ) { + ZoneScoped; const std::vector< vk::ExtensionProperties > availableExtensions { device.enumerateDeviceExtensionProperties() }; @@ -433,6 +446,7 @@ namespace fgl::engine QueueFamilyIndices Device::findQueueFamilies( vk::PhysicalDevice device ) { + ZoneScoped; QueueFamilyIndices indices {}; std::vector< vk::QueueFamilyProperties > queueFamilies { device.getQueueFamilyProperties() }; @@ -465,6 +479,7 @@ namespace fgl::engine SwapChainSupportDetails Device::querySwapChainSupport( vk::PhysicalDevice device ) { + ZoneScoped; SwapChainSupportDetails details; if ( device.getSurfaceCapabilitiesKHR( surface_, &details.capabilities ) != vk::Result::eSuccess ) @@ -498,6 +513,7 @@ namespace fgl::engine vk::Format Device::findSupportedFormat( const std::vector< vk::Format >& candidates, vk::ImageTiling tiling, vk::FormatFeatureFlags features ) { + ZoneScoped; for ( vk::Format format : candidates ) { vk::FormatProperties props; @@ -517,6 +533,7 @@ namespace fgl::engine uint32_t Device::findMemoryType( uint32_t typeFilter, vk::MemoryPropertyFlags properties ) { + ZoneScoped; vk::PhysicalDeviceMemoryProperties memProperties; m_physical_device.getMemoryProperties( &memProperties ); for ( uint32_t i = 0; i < memProperties.memoryTypeCount; i++ ) @@ -533,6 +550,7 @@ namespace fgl::engine vk::CommandBuffer Device::beginSingleTimeCommands() { + ZoneScoped; vk::CommandBufferAllocateInfo allocInfo {}; allocInfo.level = vk::CommandBufferLevel::ePrimary; allocInfo.commandPool = m_commandPool; @@ -552,6 +570,7 @@ namespace fgl::engine void Device::endSingleTimeCommands( vk::CommandBuffer commandBuffer ) { + ZoneScoped; vkEndCommandBuffer( commandBuffer ); vk::SubmitInfo submitInfo {}; @@ -569,6 +588,7 @@ namespace fgl::engine void Device:: copyBufferToImage( vk::Buffer buffer, vk::Image image, uint32_t width, uint32_t height, uint32_t layerCount ) { + ZoneScoped; vk::CommandBuffer commandBuffer { beginSingleTimeCommands() }; vk::BufferImageCopy region {}; @@ -590,6 +610,7 @@ namespace fgl::engine void Device::createVMAAllocator() { + ZoneScoped; VmaVulkanFunctions vk_func {}; vk_func.vkGetInstanceProcAddr = vkGetInstanceProcAddr; vk_func.vkGetDeviceProcAddr = vkGetDeviceProcAddr; @@ -608,6 +629,7 @@ namespace fgl::engine void Device::copyBuffer( vk::Buffer dst, vk::Buffer src, vk::DeviceSize dst_offset, vk::DeviceSize src_offset, vk::DeviceSize size ) { + ZoneScoped; vk::CommandBuffer commandBuffer { beginSingleTimeCommands() }; vk::BufferCopy copyRegion {}; diff --git a/src/engine/EngineContext.cpp b/src/engine/EngineContext.cpp index f051a26..c620201 100644 --- a/src/engine/EngineContext.cpp +++ b/src/engine/EngineContext.cpp @@ -8,6 +8,7 @@ #define GLM_FORCE_DEPTH_ZERO_TO_ONE #include #include +#include #include #include @@ -102,6 +103,7 @@ namespace fgl::engine while ( !m_window.shouldClose() ) { + ZoneScopedN( "Poll" ); glfwPollEvents(); const auto new_time { std::chrono::high_resolution_clock::now() }; @@ -121,6 +123,7 @@ namespace fgl::engine if ( auto command_buffer = m_renderer.beginFrame(); command_buffer ) { + ZoneScopedN( "Render" ); //Update const std::uint8_t frame_index { m_renderer.getFrameIndex() }; @@ -135,6 +138,13 @@ namespace fgl::engine draw_parameter_buffers[ frame_index ], m_renderer.getGBufferDescriptor( frame_index ) }; +#ifdef TRACY_ENABLE +#if TRACY_ENABLE + auto& tracy_ctx { frame_info.tracy_ctx }; + +#endif +#endif + CameraInfo current_camera_info { .projection = camera.getProjectionMatrix(), .view = camera.getViewMatrix(), .inverse_view = camera.getInverseView() }; @@ -142,146 +152,163 @@ namespace fgl::engine camera_info[ frame_index ] = current_camera_info; #ifdef ENABLE_IMGUI - ImGui_ImplVulkan_NewFrame(); - ImGui_ImplGlfw_NewFrame(); - ImGui::NewFrame(); - { - ImGui::Begin( "Titor Dev Menu" ); + ZoneScopedN( "ImGui recording" ); + ImGui_ImplVulkan_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); - ImGui::Text( "Framerate" ); - ImGui::SameLine(); - ImGui::Text( "%.1f FPS", ImGui::GetIO().Framerate ); - - ImGui::Text( "Frame Time" ); - ImGui::SameLine(); - ImGui::Text( "%.3f ms", 1000.0f / ImGui::GetIO().Framerate ); - - if ( ImGui::CollapsingHeader( "Camera" ) ) { - ImGui::PushItemWidth( 80 ); - ImGui::DragFloat( "Pos X", &viewer.transform.translation.x, 0.1f ); - ImGui::SameLine(); - ImGui::DragFloat( "Pos Y", &viewer.transform.translation.y, 0.1f ); - ImGui::SameLine(); - ImGui::DragFloat( "Pos Z", &viewer.transform.translation.z, 0.1f ); - ImGui::PopItemWidth(); + ImGui::Begin( "Titor Dev Menu" ); - ImGui::Separator(); - - ImGui::PushItemWidth( 80 ); - ImGui::DragFloat( "Rot X", &viewer.transform.rotation.x, 0.1f, 0.0f, glm::two_pi< float >() ); + ImGui::Text( "Framerate" ); ImGui::SameLine(); - ImGui::DragFloat( "Rot Y", &viewer.transform.rotation.y, 0.1f, 0.0f, glm::two_pi< float >() ); - ImGui::SameLine(); - ImGui::DragFloat( "Rot Z", &viewer.transform.rotation.z, 0.1f, 0.0f, glm::two_pi< float >() ); - ImGui::PopItemWidth(); - } + ImGui::Text( "%.1f FPS", ImGui::GetIO().Framerate ); - if ( ImGui::CollapsingHeader( "Models" ) ) - { - for ( auto& [ id, game_object ] : game_objects ) + ImGui::Text( "Frame Time" ); + ImGui::SameLine(); + ImGui::Text( "%.3f ms", 1000.0f / ImGui::GetIO().Framerate ); + + if ( ImGui::CollapsingHeader( "Camera" ) ) { - if ( game_object.model == nullptr ) continue; + ImGui::PushItemWidth( 80 ); + ImGui::DragFloat( "Pos X", &viewer.transform.translation.x, 0.1f ); + ImGui::SameLine(); + ImGui::DragFloat( "Pos Y", &viewer.transform.translation.y, 0.1f ); + ImGui::SameLine(); + ImGui::DragFloat( "Pos Z", &viewer.transform.translation.z, 0.1f ); + ImGui::PopItemWidth(); - ImGui::PushID( std::to_string( id ).c_str() ); + ImGui::Separator(); - if ( ImGui::TreeNode( game_object.model->getName().c_str() ) ) + ImGui::PushItemWidth( 80 ); + ImGui:: + DragFloat( "Rot X", &viewer.transform.rotation.x, 0.1f, 0.0f, glm::two_pi< float >() ); + ImGui::SameLine(); + ImGui:: + DragFloat( "Rot Y", &viewer.transform.rotation.y, 0.1f, 0.0f, glm::two_pi< float >() ); + ImGui::SameLine(); + ImGui:: + DragFloat( "Rot Z", &viewer.transform.rotation.z, 0.1f, 0.0f, glm::two_pi< float >() ); + ImGui::PopItemWidth(); + } + + if ( ImGui::CollapsingHeader( "Models" ) ) + { + for ( auto& [ id, game_object ] : game_objects ) { - ImGui::PushID( game_object.model->getName().c_str() ); + if ( game_object.model == nullptr ) continue; + + ImGui::PushID( std::to_string( id ).c_str() ); + + if ( ImGui::TreeNode( game_object.model->getName().c_str() ) ) { - ImGui::PushID( "Position" ); - ImGui::PushItemWidth( 80 ); - ImGui::Text( "Position" ); - ImGui::SameLine(); - ImGui::DragFloat( "X", &game_object.transform.translation.x, 0.1f ); - ImGui::SameLine(); - ImGui::DragFloat( "Y", &game_object.transform.translation.y, 0.1f ); - ImGui::SameLine(); - ImGui::DragFloat( "Z", &game_object.transform.translation.z, 0.1f ); - ImGui::PopID(); - } - - ImGui::Separator(); - - { - ImGui::PushID( "Rotation" ); - ImGui::PushItemWidth( 80 ); - ImGui::Text( "Rotation" ); - ImGui::SameLine(); - ImGui::DragFloat( - "X", &game_object.transform.rotation.x, 0.1f, 0.0f, glm::two_pi< float >() ); - ImGui::SameLine(); - ImGui::DragFloat( - "Y", &game_object.transform.rotation.y, 0.1f, 0.0f, glm::two_pi< float >() ); - ImGui::SameLine(); - ImGui::DragFloat( - "Z", &game_object.transform.rotation.z, 0.1f, 0.0f, glm::two_pi< float >() ); - ImGui::PopID(); - } - - ImGui::Separator(); - - { - ImGui::PushID( "Scale" ); - ImGui::PushItemWidth( 80 ); - ImGui::Text( "Scale" ); - ImGui::SameLine(); - ImGui::DragFloat( "X", &game_object.transform.scale.x, 0.1f ); - ImGui::SameLine(); - ImGui::DragFloat( "Y", &game_object.transform.scale.y, 0.1f ); - ImGui::SameLine(); - ImGui::DragFloat( "Z", &game_object.transform.scale.z, 0.1f ); - ImGui::TreePop(); - ImGui::PopID(); - } - - if ( ImGui::CollapsingHeader( "Textures" ) ) - { - std::vector< TextureID > textures; - - ImGui::PushID( "Textures" ); - - for ( auto& primitive : game_object.model->m_primitives ) + ImGui::PushID( game_object.model->getName().c_str() ); { - if ( !primitive.m_texture.has_value() ) continue; + ImGui::PushID( "Position" ); + ImGui::PushItemWidth( 80 ); + ImGui::Text( "Position" ); + ImGui::SameLine(); + ImGui::DragFloat( "X", &game_object.transform.translation.x, 0.1f ); + ImGui::SameLine(); + ImGui::DragFloat( "Y", &game_object.transform.translation.y, 0.1f ); + ImGui::SameLine(); + ImGui::DragFloat( "Z", &game_object.transform.translation.z, 0.1f ); + ImGui::PopID(); + } - auto& texture { primitive.m_texture.value() }; + ImGui::Separator(); - const auto& extent { texture.getExtent() }; + { + ImGui::PushID( "Rotation" ); + ImGui::PushItemWidth( 80 ); + ImGui::Text( "Rotation" ); + ImGui::SameLine(); + ImGui::DragFloat( + "X", + &game_object.transform.rotation.x, + 0.1f, + 0.0f, + glm::two_pi< float >() ); + ImGui::SameLine(); + ImGui::DragFloat( + "Y", + &game_object.transform.rotation.y, + 0.1f, + 0.0f, + glm::two_pi< float >() ); + ImGui::SameLine(); + ImGui::DragFloat( + "Z", + &game_object.transform.rotation.z, + 0.1f, + 0.0f, + glm::two_pi< float >() ); + ImGui::PopID(); + } - auto& image_view { texture.getImageView() }; - auto& sampler { image_view.getSampler() }; + ImGui::Separator(); - if ( !sampler.has_value() ) continue; + { + ImGui::PushID( "Scale" ); + ImGui::PushItemWidth( 80 ); + ImGui::Text( "Scale" ); + ImGui::SameLine(); + ImGui::DragFloat( "X", &game_object.transform.scale.x, 0.1f ); + ImGui::SameLine(); + ImGui::DragFloat( "Y", &game_object.transform.scale.y, 0.1f ); + ImGui::SameLine(); + ImGui::DragFloat( "Z", &game_object.transform.scale.z, 0.1f ); + ImGui::TreePop(); + ImGui::PopID(); + } - ImVec2 size; - size.x = extent.width; - size.y = extent.height; + if ( ImGui::CollapsingHeader( "Textures" ) ) + { + std::vector< TextureID > textures; - if ( std::find( textures.begin(), textures.end(), texture.getID() ) - == textures.end() ) + ImGui::PushID( "Textures" ); + + for ( auto& primitive : game_object.model->m_primitives ) { - textures.emplace_back( texture.getID() ); + if ( !primitive.m_texture.has_value() ) continue; - ImGui::Image( - static_cast< ImTextureID >( primitive.m_texture - ->getImGuiDescriptorSet() ), - size ); + auto& texture { primitive.m_texture.value() }; + + const auto& extent { texture.getExtent() }; + + auto& image_view { texture.getImageView() }; + auto& sampler { image_view.getSampler() }; + + if ( !sampler.has_value() ) continue; + + ImVec2 size; + size.x = extent.width; + size.y = extent.height; + + if ( std::find( textures.begin(), textures.end(), texture.getID() ) + == textures.end() ) + { + textures.emplace_back( texture.getID() ); + + ImGui::Image( + static_cast< ImTextureID >( primitive.m_texture + ->getImGuiDescriptorSet() ), + size ); + } } + + ImGui::PopID(); } ImGui::PopID(); } - ImGui::PopID(); } - ImGui::PopID(); } - } - //TODO: Add in a collapsable header to view all buffers, And their suballocations - /* + //TODO: Add in a collapsable header to view all buffers, And their suballocations + /* if ( ImGui::CollapsingHeader( "Buffer allocations" ) ) { for ( const auto& buffer : Buffer::getActiveBufferHandles() ) @@ -291,11 +318,12 @@ namespace fgl::engine } }*/ - ImGui::End(); - } + ImGui::End(); + } - //Render - ImGui::Render(); + //Render + ImGui::Render(); + } ImDrawData* data { ImGui::GetDrawData() }; #endif @@ -304,10 +332,24 @@ namespace fgl::engine m_entity_renderer.pass( frame_info ); #ifdef ENABLE_IMGUI - ImGui_ImplVulkan_RenderDrawData( data, command_buffer ); + { +#ifdef TRACY_ENABLE +#if TRACY_ENABLE + TracyVkZone( tracy_ctx, command_buffer, "ImGui Rendering" ); +#endif +#endif + ImGui_ImplVulkan_RenderDrawData( data, command_buffer ); + } #endif m_renderer.endSwapchainRendererPass( command_buffer ); + +#ifdef TRACY_ENABLE +#if TRACY_ENABLE + TracyVkCollect( frame_info.tracy_ctx, command_buffer ); +#endif +#endif + m_renderer.endFrame(); FrameMark; } diff --git a/src/engine/Renderer.cpp b/src/engine/Renderer.cpp index 241999b..dd4f0b1 100644 --- a/src/engine/Renderer.cpp +++ b/src/engine/Renderer.cpp @@ -49,6 +49,21 @@ namespace fgl::engine if ( Device::getInstance().device().allocateCommandBuffers( &alloc_info, m_command_buffer.data() ) != vk::Result::eSuccess ) throw std::runtime_error( "Failed to allocate command buffers" ); + +#ifdef TRACY_ENABLE +#if TRACY_ENABLE + m_tracy_ctx.resize( SwapChain::MAX_FRAMES_IN_FLIGHT ); + + for ( int i = 0; i < SwapChain::MAX_FRAMES_IN_FLIGHT; ++i ) + { + VkPhysicalDevice phy_dev { Device::getInstance().phyDevice() }; + VkDevice dev { Device::getInstance().device() }; + + m_tracy_ctx[ i ] = + TracyVkContext( phy_dev, dev, Device::getInstance().graphicsQueue(), m_command_buffer[ i ] ); + } +#endif +#endif } void Renderer::recreateSwapchain() diff --git a/src/engine/Renderer.hpp b/src/engine/Renderer.hpp index 4682f5a..792a031 100644 --- a/src/engine/Renderer.hpp +++ b/src/engine/Renderer.hpp @@ -16,7 +16,6 @@ //clang-format: off #include - //clang-format: on namespace fgl::engine @@ -62,7 +61,7 @@ namespace fgl::engine TracyVkCtx getCurrentTracyCTX() const { -#ifdef TRACY_ENABLED +#ifdef TRACY_ENABLE return m_tracy_ctx[ current_frame_idx ]; #else return nullptr; diff --git a/src/engine/image/ImageHandle.cpp b/src/engine/image/ImageHandle.cpp index 702f4ad..8c494cb 100644 --- a/src/engine/image/ImageHandle.cpp +++ b/src/engine/image/ImageHandle.cpp @@ -41,6 +41,7 @@ namespace fgl::engine m_initial_layout( inital_layout ), m_final_layout( final_layout ) { + ZoneScoped; vk::ImageCreateInfo image_info {}; image_info.imageType = vk::ImageType::e2D; diff --git a/src/engine/systems/EntityRendererSystem.cpp b/src/engine/systems/EntityRendererSystem.cpp index f44c664..9b54066 100644 --- a/src/engine/systems/EntityRendererSystem.cpp +++ b/src/engine/systems/EntityRendererSystem.cpp @@ -32,6 +32,7 @@ namespace fgl::engine EntityRendererSystem::EntityRendererSystem( Device& device, VkRenderPass render_pass ) : m_device( device ) { + ZoneScoped; PipelineConfigInfo info { render_pass }; for ( int i = 0; i < 4; ++i ) PipelineConfigInfo::addColorAttachmentConfig( info ); @@ -61,6 +62,7 @@ namespace fgl::engine void EntityRendererSystem::pass( FrameInfo& info ) { + ZoneScoped; auto& command_buffer { info.command_buffer }; { TracyVkZone( info.tracy_ctx, command_buffer, "Render game objects" ); @@ -81,6 +83,7 @@ namespace fgl::engine for ( const auto& primitive : obj.model->m_primitives ) { + ZoneScopedN( "Render primitive" ); const ModelMatrixInfo matrix_info { .model_matrix = obj.transform.mat4(), .texture_idx = primitive.m_texture->getID() }; //.normal_matrix = obj.transform.normalMatrix() }; diff --git a/src/engine/texture/Texture.cpp b/src/engine/texture/Texture.cpp index fd48602..b585430 100644 --- a/src/engine/texture/Texture.cpp +++ b/src/engine/texture/Texture.cpp @@ -22,6 +22,7 @@ namespace fgl::engine std::tuple< std::vector< unsigned char >, int, int, int > loadTexture( const std::filesystem::path& path ) { + ZoneScoped; if ( !std::filesystem::exists( path ) ) throw std::runtime_error( "Failed to open file: " + path.string() ); int x { 0 }; @@ -46,6 +47,7 @@ namespace fgl::engine Texture Texture::loadFromFile( const std::filesystem::path& path ) { + ZoneScoped; //TODO: Make some way of cleaning the map when loading textures if ( texture_map.contains( path.string() ) ) @@ -87,6 +89,7 @@ namespace fgl::engine void Texture::stage( vk::CommandBuffer& cmd ) { + ZoneScoped; assert( m_handle && "Attempted to stage invalid texture (No handle)" ); //assert( m_handle->m_staging && "Can't stage. No staging buffer made" ); diff --git a/src/engine/texture/TextureHandle.cpp b/src/engine/texture/TextureHandle.cpp index 4b56623..f2b452c 100644 --- a/src/engine/texture/TextureHandle.cpp +++ b/src/engine/texture/TextureHandle.cpp @@ -16,6 +16,7 @@ namespace fgl::engine TextureHandle( const std::vector< unsigned char >& data, const vk::Extent2D extent, const int channels ) : m_extent( extent ) { + ZoneScoped; static TextureID tex_counter { 0 }; constexpr auto format { vk::Format::eR8G8B8A8Unorm };