Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ option(NC_BUILD_TESTS "Enable building tests." OFF)
option(NC_BUILD_INTEGRATION_TESTS "Enable building integration tests." OFF)
option(NC_BUILD_NCCONVERT "Enable building nc-convert asset converter." ON)
option(NC_RUNTIME_SHADER_COMPILATION "Enable compiling shaders at runtime" ON)
option(NC_PROFILING_ENABLED "Enable profiling with Optick" OFF)
option(NC_PROFILING_ENABLED "Enable profiling" OFF)
set(NC_PROFILER "Tracy" CACHE STRING "Profiler to use (Tracy or Optick)")
set_property(CACHE NC_PROFILER PROPERTY STRINGS "Tracy" "Optick")
option(NC_PROD_BUILD "Only build NcEngine production binaries." OFF)

# Variables
Expand Down Expand Up @@ -59,6 +61,11 @@ endif()

if(NC_PROFILING_ENABLED)
list(APPEND NC_COMPILE_DEFINITIONS NC_PROFILING_ENABLED)
if(NC_PROFILER STREQUAL "Tracy")
list(APPEND NC_COMPILE_DEFINITIONS NC_USE_TRACY)
elseif(NC_PROFILER STREQUAL "Optick")
list(APPEND NC_COMPILE_DEFINITIONS NC_USE_OPTICK)
endif()
endif()

# Get dependencies
Expand Down
25 changes: 22 additions & 3 deletions cmake/FetchDependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ FetchContent_Declare(taskflow

# Optick
set(OPTICK_INSTALL_TARGETS OFF CACHE BOOL "" FORCE)
if(${NC_PROFILING_ENABLED})
if(NC_PROFILING_ENABLED AND NC_PROFILER STREQUAL "Optick")
set(OPTICK_ENABLED ON CACHE BOOL "" FORCE)
else()
set(OPTICK_ENABLED OFF CACHE BOOL "" FORCE)
Expand All @@ -84,6 +84,20 @@ FetchContent_Declare(optick
GIT_SHALLOW TRUE
)

# Tracy
if(NC_PROFILING_ENABLED AND NC_PROFILER STREQUAL "Tracy")
set(TRACY_ENABLE ON CACHE BOOL "" FORCE)
else()
set(TRACY_ENABLE OFF CACHE BOOL "" FORCE)
endif()
set(TRACY_ON_DEMAND ON CACHE BOOL "" FORCE)

FetchContent_Declare(tracy
GIT_REPOSITORY https://github.com/wolfpld/tracy.git
GIT_TAG v0.13.1
GIT_SHALLOW TRUE
)

# Jolt
set(CPP_EXCEPTIONS_ENABLED ON CACHE BOOL "" FORCE)
set(CPP_RTTI_ENABLED ON CACHE BOOL "" FORCE)
Expand Down Expand Up @@ -156,7 +170,7 @@ FetchContent_Declare(fmt
)

# Fetch all required sources
FetchContent_MakeAvailable(taskflow optick JoltPhysics DirectXMath fmt DiligentCore DiligentTools)
FetchContent_MakeAvailable(taskflow optick tracy JoltPhysics DirectXMath fmt DiligentCore DiligentTools)

# Silence warnings
disable_warnings_for_headers(Taskflow)
Expand All @@ -172,10 +186,15 @@ disable_warnings_for_target(Diligent-Imgui)
if(NC_PROFILING_ENABLED AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_compile_definitions(Jolt
PUBLIC
-DJPH_EXTERNAL_PROFILE
JPH_EXTERNAL_PROFILE
)
endif()

# Silence Tracy warnings
if(NC_PROFILING_ENABLED AND NC_PROFILER STREQUAL "Tracy")
disable_warnings_for_headers(TracyClient)
endif()

# Optional Dependencies

if(NC_BUILD_NCCONVERT)
Expand Down
52 changes: 47 additions & 5 deletions include/ncengine/debug/Profile.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,45 @@

#ifdef NC_PROFILING_ENABLED

#if defined(NC_USE_TRACY)

#include "tracy/Tracy.hpp"

namespace nc
{
/** @cond internal */
namespace detail
{
struct TaskMeasurement
{
explicit TaskMeasurement()
{
tracy::SetThreadName("NcEngine Worker");
}

~TaskMeasurement() noexcept = default;
};
} // namespace detail
} // namespace nc
/** @endcond */

/** @brief Mark frame boundary. */
#define NC_PROFILE_FRAME(name) FrameMark

/** @brief Profile a function or inner scope. */
#define NC_PROFILE_SCOPE(name, category) ZoneScopedN(name)

/** @brief Profile a task. Use this at the top level of a task instead of NC_PROFILE_SCOPE for proper thread tracking. */
#define NC_PROFILE_TASK(name, category) \
const auto _ncTaskMeasurement ## __LINE__ = nc::detail::TaskMeasurement{}; \
NC_PROFILE_SCOPE(name, category)

#elif defined(NC_USE_OPTICK)

#include "optick.h"

namespace nc
{
/** @brief Color and filter for a profile event. */
using ProfileCategory = Optick::Category;

/** @cond internal */
Expand All @@ -32,15 +66,23 @@ struct TaskMeasurement
} // namespace nc
/** @endcond */

/** @brief Mark frame boundary. */
#define NC_PROFILE_FRAME(name) OPTICK_FRAME(name)

/** @brief Profile a function or inner scope. */
#define NC_PROFILE_SCOPE(name, category) OPTICK_CATEGORY(name, category);
#define NC_PROFILE_SCOPE(name, category) OPTICK_CATEGORY(name, category)

/** @brief Profile a task. Use this at the top level of a task instead of NC_PROFILE_SCOPE for proper thread tracking. */
#define NC_PROFILE_TASK(name, category) \
const auto _ncTaskMeasurement ## __LINE__ = nc::detail::TaskMeasurement{}; \
NC_PROFILE_SCOPE(name, category);
NC_PROFILE_SCOPE(name, category)

#else
#endif // NC_USE_TRACY / NC_USE_OPTICK

#else // NC_PROFILING_ENABLED not defined

#define NC_PROFILE_FRAME(name)
#define NC_PROFILE_SCOPE(name, category)
#define NC_PROFILE_TASK(name, category)
#endif

#endif // NC_PROFILING_ENABLED
Binary file modified resources/shaders/compiled/ToonPixel.spv
Binary file not shown.
9 changes: 8 additions & 1 deletion source/ncengine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ set_target_properties(${NC_ENGINE_LIB}
PROPERTIES CMAKE_DEBUG_POSTFIX d
)

# Profiler library selection
if(NC_PROFILING_ENABLED AND NC_PROFILER STREQUAL "Tracy")
set(NC_PROFILER_LIB TracyClient)
else()
set(NC_PROFILER_LIB OptickCore)
endif()

# Link libraries
target_link_libraries(${NC_ENGINE_LIB}
PUBLIC
Expand All @@ -40,7 +47,7 @@ target_link_libraries(${NC_ENGINE_LIB}
glfw
imgui
Taskflow
OptickCore
${NC_PROFILER_LIB}
RtAudio
${DILIGENT_LIBRARIES}
)
Expand Down
4 changes: 2 additions & 2 deletions source/ncengine/engine/NcEngineImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include "utility/Log.h"
#include "window/Window.h"

#include "optick.h"
#include "ncengine/debug/Profile.h"

#include <sstream>
#include <thread>
Expand Down Expand Up @@ -171,7 +171,7 @@ void NcEngineImpl::Run()
auto* ncScene = m_modules->Get<NcScene>();
auto update = [this, ncWindow = m_modules->Get<window::NcWindow>()](float dt)
{
OPTICK_FRAME("Main Thread");
NC_PROFILE_FRAME("Main Thread");
time::SetDeltaTime(dt);
input::Flush();
ncWindow->ProcessSystemMessages();
Expand Down
2 changes: 1 addition & 1 deletion source/ncengine/graphics2/NcGraphicsImpl2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ void NcGraphicsImpl2::OnBuildTaskGraph(task::UpdateTasks& update, task::RenderTa

void NcGraphicsImpl2::Run()
{
NC_PROFILE_TASK("Render", Optick::Category::Rendering);
NC_PROFILE_TASK("Render", ProfileCategory::Rendering);

if (m_resizeNeeded)
{
Expand Down
3 changes: 3 additions & 0 deletions source/ncengine/graphics2/diligent/UIBackend.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "UIBackend.h"

#include "ncengine/debug/Profile.h"
#include "imgui.h"
#include "ImGuizmo.h"

Expand All @@ -16,13 +17,15 @@ UIBackend::UIBackend(Diligent::IRenderDevice& device,

void UIBackend::FrameBegin(Diligent::ISwapChain& swapChain)
{
NC_PROFILE_SCOPE("UIBackend::FrameBegin", ProfileCategory::Rendering);
const auto& scDesc = swapChain.GetDesc();
m_imguiBackend.NewFrame(scDesc.Width, scDesc.Height, scDesc.PreTransform);
ImGuizmo::BeginFrame();
}

void UIBackend::Render(Diligent::IDeviceContext& context)
{
NC_PROFILE_SCOPE("UIBackend::Render", ProfileCategory::Rendering);
m_imguiBackend.Render(&context);
}

Expand Down
3 changes: 2 additions & 1 deletion source/ncengine/graphics2/diligent/pass/PassBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ void PassBackend::RenderShadowPass(IDeviceContext& context,
const std::vector<Batch>& skinnedBatches,
const std::span<const LightData>& lights)
{
NC_PROFILE_SCOPE("PassBackend::RenderShadowPass", ProfileCategory::Rendering);
auto& sinkIndexBuffer = perPassResourceSignature.GetSinkIndexBufferResource();
auto& uniShadowMapsBuffer = perPassResourceSignature.GetUniShadowMapSinksResource();
auto& pointShadowMapsBuffer = perPassResourceSignature.GetPointShadowMapSinksResource();
Expand Down Expand Up @@ -418,8 +419,8 @@ void PassBackend::RenderParticle(IDeviceContext& context,
PerPassResourceSignature& perPassResourceSignature,
const ParticleRenderState& state,
const Viewport& viewport)

{
NC_PROFILE_SCOPE("PassBackend::RenderParticle", ProfileCategory::Rendering);
if (state.particleData.instances.empty() || !m_particlePass)
{
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "CubeMapBufferResource.h"
#include "ncengine/debug/Profile.h"
#include "ResourceTypes.h"

#include "TextureLoader.h"
Expand Down Expand Up @@ -36,6 +37,7 @@ void CubeMapBufferResource::Load(std::span<const asset::CubeMapWithId> cubeMaps,
IDeviceContext& context,
IRenderDevice& device)
{
NC_PROFILE_SCOPE("CubeMapBufferResource::Load", ProfileCategory::Rendering);
const auto cubeMapCount = cubeMaps.size();
if (cubeMapCount == 0)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "EnvironmentBufferResource.h"
#include "graphics2/frontend/subsystem/CameraRenderState.h"
#include "ncengine/debug/Profile.h"
#include "graphics2/frontend/subsystem/EnvironmentRenderState.h"
#include "graphics2/frontend/subsystem/LightRenderState.h"
#include "ncengine/graphics/Environment.h"
Expand All @@ -25,6 +26,7 @@ void EnvironmentBufferResource::Update(Diligent::IDeviceContext& context,
const LightRenderState& lightRenderState,
const EnvironmentRenderState& environmentRenderState)
{
NC_PROFILE_SCOPE("EnvironmentBufferResource::Update", ProfileCategory::Rendering);
const auto data = GlobalEnvironmentData{
.cameraViewProjection = cameraState.viewProjection,
.cameraInvProjection = cameraState.invProjection,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "SinkBufferResource.h"
#include "graphics2/diligent/pass/PassTypes.h"
#include "ncengine/debug/Profile.h"
#include "ResourceTypes.h"

#include "ncutility/NcError.h"
Expand Down Expand Up @@ -210,6 +211,7 @@ void SinkBufferResource::Clear()

void SinkBufferResource::Update()
{
NC_PROFILE_SCOPE("SinkBufferResource::Update", ProfileCategory::Rendering);
SetArrayRegion(m_variable, std::span<Diligent::IDeviceObject*>(m_shaderResourceViews), 0u, m_shaderResourceViews.size());
}
} // namespace nc::graphics
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "TextureBufferResource.h"
#include "ncengine/debug/Profile.h"
#include "ResourceTypes.h"

#include "TextureLoader.h"
Expand Down Expand Up @@ -31,6 +32,7 @@ void TextureBufferResource::Load(std::span<const asset::TextureWithId> textures,
Diligent::IDeviceContext& context,
Diligent::IRenderDevice& device)
{
NC_PROFILE_SCOPE("TextureBufferResource::Load", ProfileCategory::Rendering);
if (!m_initialLoadComplete)
{
InitializeArray(context, device, m_variable, m_maxTextures);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "WireframeBufferResource.h"
#include "ncengine/debug/Profile.h"

namespace nc::graphics
{
Expand All @@ -19,6 +20,7 @@ WireframeBufferResource::WireframeBufferResource(Diligent::IDeviceContext& conte
void WireframeBufferResource::Update(Diligent::IDeviceContext& context,
const WireframeData& data)
{
NC_PROFILE_SCOPE("WireframeBufferResource::Update", ProfileCategory::Rendering);
m_buffer.Write(context, data);
}
} // namespace nc::graphics
2 changes: 2 additions & 0 deletions source/ncengine/graphics2/frontend/GraphicsFrontend.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#include "GraphicsFrontend.h"
#include "FrontendRenderState.h"
#include "ncengine/debug/Profile.h"
#include "ncengine/ecs/Ecs.h"

namespace nc::graphics
{
auto GraphicsFrontend::BuildRenderState(ecs::Ecs world) -> FrontendRenderState
{
NC_PROFILE_SCOPE("GraphicsFrontend::BuildRenderState", ProfileCategory::Rendering);
return FrontendRenderState{
.cameraState = m_cameraSystem.BuildState(world),
.environmentRenderState = m_environmentSystem.BuildState(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "CameraSubsystem.h"
#include "CameraRenderState.h"

#include "ncengine/debug/Profile.h"
#include "ncengine/ecs/Ecs.h"
#include "ncengine/graphics/Camera.h"
#include "ncengine/window/Window.h"
Expand All @@ -20,6 +21,7 @@ namespace nc::graphics
{
auto CameraSubsystem::BuildState(ecs::ExplicitEcs<Transform> ecs) -> CameraRenderState
{
NC_PROFILE_SCOPE("CameraSubsystem::BuildState", ProfileCategory::Rendering);
if (m_mainCamera)
{
const auto& transform = ecs.Get<Transform>(m_mainCamera->ParentEntity());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ void InstanceCache<T>::CommitPendingChanges()
template<class T>
auto InstanceCache<T>::BuildState() -> BufferUpdateInfo<T>
{
NC_PROFILE_SCOPE("InstanceCache::BuildState", ProfileCategory::Rendering);
// For simplicity, we're only tracking one dirty range from the first modified index to the buffer
// end. This can result in more copies than necessary for non-shifting insertions and removals, but the
// data is pretty cheap to copy.
Expand Down Expand Up @@ -181,6 +182,7 @@ auto InstanceCache<T>::BuildBatches(std::span<const MaterialPassFlag::type> pass
template<class T>
void InstanceCache<T>::Purge() noexcept
{
NC_PROFILE_SCOPE("InstanceCache::Purge", ProfileCategory::Rendering);
CommitPendingChanges();
m_dirtyBegin = 0u;
auto bufferEnd = 0u;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "LightSubsystem.h"

#include "ncengine/debug/Profile.h"
#include "ncengine/ecs/Ecs.h"
#include "ncengine/ecs/Transform.h"
#include "ncengine/graphics/Light.h"
Expand Down Expand Up @@ -37,6 +38,7 @@ namespace nc::graphics
{
auto LightSubsystem::BuildState(ecs::ExplicitEcs<DirectionalLight, PointLight, SpotLight, Transform> ecs) -> LightRenderState
{
NC_PROFILE_SCOPE("LightSubsystem::BuildState", ProfileCategory::Rendering);
m_lightData.clear();
m_lightMatrixData.clear();
auto lightMatrixIndex = 0u;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "PostProcessSubsystem.h"
#include "ncengine/debug/Profile.h"
#include "ncengine/graphics/GraphicsUtility.h"

#include "ncutility/NcError.h"
Expand Down Expand Up @@ -121,6 +122,7 @@ void PostProcessSubsystem::SetProperties(PostProcessEffectId effectId,

auto PostProcessSubsystem::BuildState() -> PostProcessState
{
NC_PROFILE_SCOPE("PostProcessSubsystem::BuildState", ProfileCategory::Rendering);
return PostProcessState{
.toggledEffects = std::move(m_toggledEffects),
.modifiedProperties = std::move(m_modifiedProperties)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ void TransformCache::RemoveInstance(TransformDataHandle instance)

void TransformCache::CommitPendingChanges()
{
NC_PROFILE_SCOPE("TransformCache::CommitPendingChanges", ProfileCategory::Rendering);
m_buffer.CommitPendingChanges();
}

Expand Down
Loading