@@ -1222,6 +1222,11 @@ Asset::LoadResult VisualScript::load()
|
||||
method.ProfilerName.Get()[assetName.Length()] = ':';
|
||||
method.ProfilerName.Get()[assetName.Length() + 1] = ':';
|
||||
Platform::MemoryCopy(method.ProfilerName.Get() + assetName.Length() + 2, method.Name.Get(), method.Name.Length());
|
||||
method.ProfilerData.name = method.ProfilerName.Get();
|
||||
method.ProfilerData.function = method.Name.Get();
|
||||
method.ProfilerData.file = nullptr;
|
||||
method.ProfilerData.line = 0;
|
||||
method.ProfilerData.color = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2139,7 +2144,7 @@ VisualScriptingBinaryModule* VisualScripting::GetBinaryModule()
|
||||
Variant VisualScripting::Invoke(VisualScript::Method* method, ScriptingObject* instance, Span<Variant> parameters)
|
||||
{
|
||||
CHECK_RETURN(method && method->Script->IsLoaded(), Variant::Zero);
|
||||
PROFILE_CPU_NAMED(*method->ProfilerName);
|
||||
PROFILE_CPU_SRC_LOC(method->ProfilerData);
|
||||
|
||||
// Add to the calling stack
|
||||
ScopeContext scope;
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
#include "../BinaryAsset.h"
|
||||
#include "Engine/Scripting/BinaryModule.h"
|
||||
#include "Engine/Visject/VisjectGraph.h"
|
||||
#if COMPILE_WITH_PROFILER
|
||||
#include "Engine/Profiler/ProfilerSrcLoc.h"
|
||||
#endif
|
||||
|
||||
#define VISUAL_SCRIPT_GRAPH_MAX_CALL_STACK 250
|
||||
#define VISUAL_SCRIPT_DEBUGGING USE_EDITOR
|
||||
@@ -118,6 +121,7 @@ public:
|
||||
Array<StringAnsi, InlinedAllocation<16>> ParamNames;
|
||||
#if COMPILE_WITH_PROFILER
|
||||
StringAnsi ProfilerName;
|
||||
SourceLocationData ProfilerData;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -386,33 +386,31 @@ struct TIsPODType<ProfilerCPU::Event>
|
||||
enum { Value = true };
|
||||
};
|
||||
|
||||
#include "ProfilerSrcLoc.h"
|
||||
|
||||
// Shortcut macros for profiling a single code block execution on CPU
|
||||
// Use ZoneTransient for Tracy for code that can be hot-reloaded (eg. in Editor) or if name can be a variable
|
||||
#define PROFILE_CPU_USE_TRANSIENT_DATA 0
|
||||
|
||||
#define PROFILE_CPU_NAMED(name) ZoneTransientN(___tracy_scoped_zone, name, true); ScopeProfileBlockCPU ProfileBlockCPU(name)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
#if USE_EDITOR
|
||||
#define PROFILE_CPU() ZoneTransient(___tracy_scoped_zone, true); ScopeProfileBlockCPU ProfileBlockCPU(TEXT(__FUNCTION__))
|
||||
#else
|
||||
#define PROFILE_CPU() ZoneNamed(___tracy_scoped_zone, true); ScopeProfileBlockCPU ProfileBlockCPU(TEXT(__FUNCTION__))
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#if USE_EDITOR
|
||||
#if PROFILE_CPU_USE_TRANSIENT_DATA
|
||||
#define PROFILE_CPU() ZoneTransient(___tracy_scoped_zone, true); ScopeProfileBlockCPU ProfileBlockCPU(__FUNCTION__)
|
||||
#define PROFILE_CPU_NAMED(name) ZoneTransientN(___tracy_scoped_zone, name, true); ScopeProfileBlockCPU ProfileBlockCPU(name)
|
||||
#else
|
||||
#define PROFILE_CPU() ZoneNamed(___tracy_scoped_zone, true); ScopeProfileBlockCPU ProfileBlockCPU(__FUNCTION__)
|
||||
#define PROFILE_CPU_NAMED(name) ZoneNamedN(___tracy_scoped_zone, name, true); ScopeProfileBlockCPU ProfileBlockCPU(name)
|
||||
#endif
|
||||
|
||||
#ifdef TRACY_ENABLE
|
||||
#define PROFILE_CPU_SRC_LOC(srcLoc) tracy::ScopedZone ___tracy_scoped_zone( (tracy::SourceLocationData*)&(srcLoc) ); ScopeProfileBlockCPU ProfileBlockCPU((srcLoc).name)
|
||||
#else
|
||||
#define PROFILE_CPU_SRC_LOC(srcLoc) ScopeProfileBlockCPU ProfileBlockCPU((srcLoc).name)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
// Empty macros for disabled profiler
|
||||
#define PROFILE_CPU_NAMED(name)
|
||||
#define PROFILE_CPU()
|
||||
#define PROFILE_CPU_NAMED(name)
|
||||
#define PROFILE_CPU_SRC_LOC(srcLoc)
|
||||
|
||||
#endif
|
||||
|
||||
18
Source/Engine/Profiler/ProfilerSrcLoc.h
Normal file
18
Source/Engine/Profiler/ProfilerSrcLoc.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if COMPILE_WITH_PROFILER
|
||||
|
||||
#include "Engine/Core/Types/BaseTypes.h"
|
||||
|
||||
struct FLAXENGINE_API SourceLocationData
|
||||
{
|
||||
const char* name;
|
||||
const char* function;
|
||||
const char* file;
|
||||
uint32 line;
|
||||
uint32 color;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -60,18 +60,23 @@ MMethod::MMethod(MonoMethod* monoMethod, const char* name, MClass* parentClass)
|
||||
ProfilerName.Get()[className.Length()] = ':';
|
||||
ProfilerName.Get()[className.Length() + 1] = ':';
|
||||
Platform::MemoryCopy(ProfilerName.Get() + className.Length() + 2, _name.Get(), _name.Length());
|
||||
ProfilerData.name = ProfilerName.Get();
|
||||
ProfilerData.function = _name.Get();
|
||||
ProfilerData.file = nullptr;
|
||||
ProfilerData.line = 0;
|
||||
ProfilerData.color = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
MonoObject* MMethod::Invoke(void* instance, void** params, MonoObject** exception) const
|
||||
{
|
||||
PROFILE_CPU_NAMED(*ProfilerName);
|
||||
PROFILE_CPU_SRC_LOC(ProfilerData);
|
||||
return mono_runtime_invoke(_monoMethod, instance, params, exception);
|
||||
}
|
||||
|
||||
MonoObject* MMethod::InvokeVirtual(MonoObject* instance, void** params, MonoObject** exception) const
|
||||
{
|
||||
PROFILE_CPU_NAMED(*ProfilerName);
|
||||
PROFILE_CPU_SRC_LOC(ProfilerData);
|
||||
MonoMethod* virtualMethod = mono_object_get_virtual_method(instance, _monoMethod);
|
||||
return mono_runtime_invoke(virtualMethod, instance, params, exception);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Core/Collections/Array.h"
|
||||
#if COMPILE_WITH_PROFILER
|
||||
#include "Engine/Profiler/ProfilerSrcLoc.h"
|
||||
#endif
|
||||
#include "MTypes.h"
|
||||
|
||||
/// <summary>
|
||||
@@ -42,6 +45,7 @@ public:
|
||||
|
||||
#if COMPILE_WITH_PROFILER
|
||||
MString ProfilerName;
|
||||
SourceLocationData ProfilerData;
|
||||
#endif
|
||||
|
||||
#if USE_MONO
|
||||
|
||||
@@ -9,13 +9,29 @@
|
||||
#include "Engine/Scripting/ManagedCLR/MUtils.h"
|
||||
#include "Engine/Core/ObjectsRemovalService.h"
|
||||
#include "Engine/Profiler/Profiler.h"
|
||||
#if TRACY_ENABLE && !PROFILE_CPU_USE_TRANSIENT_DATA
|
||||
#include "Engine/Core/Collections/ChunkedArray.h"
|
||||
#endif
|
||||
#include "Engine/Core/Types/Pair.h"
|
||||
#include "Engine/Threading/Threading.h"
|
||||
#include <ThirdParty/mono-2.0/mono/metadata/mono-gc.h>
|
||||
|
||||
namespace ProfilerInternal
|
||||
{
|
||||
#if COMPILE_WITH_PROFILER
|
||||
Array<int32> ManagedEventsGPU;
|
||||
Array<int32, InlinedAllocation<32>> ManagedEventsGPU;
|
||||
#if TRACY_ENABLE && !PROFILE_CPU_USE_TRANSIENT_DATA
|
||||
CriticalSection ManagedSourceLocationsLocker;
|
||||
|
||||
struct Location
|
||||
{
|
||||
String Name;
|
||||
StringAnsi NameAnsi;
|
||||
tracy::SourceLocationData SrcLocation;
|
||||
};
|
||||
|
||||
ChunkedArray<Location, 256> ManagedSourceLocations;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void BeginEvent(MonoString* nameObj)
|
||||
@@ -24,7 +40,34 @@ namespace ProfilerInternal
|
||||
const StringView name((const Char*)mono_string_chars(nameObj), mono_string_length(nameObj));
|
||||
ProfilerCPU::BeginEvent(*name);
|
||||
#if TRACY_ENABLE
|
||||
#if PROFILE_CPU_USE_TRANSIENT_DATA
|
||||
tracy::ScopedZone::Begin(__LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), name.Get(), name.Length() );
|
||||
#else
|
||||
ScopeLock lock(ManagedSourceLocationsLocker);
|
||||
tracy::SourceLocationData* srcLoc = nullptr;
|
||||
for (auto& e = ManagedSourceLocations.Begin(); e.IsNotEnd(); ++e)
|
||||
{
|
||||
if (name == e->Name)
|
||||
{
|
||||
srcLoc = &e->SrcLocation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!srcLoc)
|
||||
{
|
||||
auto& e = ManagedSourceLocations.AddOne();
|
||||
e.Name = name;
|
||||
e.NameAnsi = name.Get();
|
||||
srcLoc = &e.SrcLocation;
|
||||
srcLoc->name = e.NameAnsi.Get();
|
||||
srcLoc->function = nullptr;
|
||||
srcLoc->file = nullptr;
|
||||
srcLoc->line = 0;
|
||||
srcLoc->color = 0;
|
||||
}
|
||||
//static constexpr tracy::SourceLocationData tracySrcLoc{ nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 };
|
||||
tracy::ScopedZone::Begin(srcLoc);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
17
Source/ThirdParty/tracy/client/TracyScoped.hpp
vendored
17
Source/ThirdParty/tracy/client/TracyScoped.hpp
vendored
@@ -12,8 +12,22 @@
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
void ScopedZone::Begin(const SourceLocationData* srcloc)
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if (!GetProfiler().IsConnected()) return;
|
||||
#endif
|
||||
TracyLfqPrepare( QueueType::ZoneBegin );
|
||||
MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
|
||||
MemWrite( &item->zoneBegin.srcloc, (uint64_t)srcloc );
|
||||
TracyLfqCommit;
|
||||
}
|
||||
|
||||
void ScopedZone::Begin(uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const Char* name, size_t nameSz)
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if (!GetProfiler().IsConnected()) return;
|
||||
#endif
|
||||
TracyLfqPrepare( QueueType::ZoneBeginAllocSrcLoc );
|
||||
const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz );
|
||||
MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
|
||||
@@ -23,6 +37,9 @@ void ScopedZone::Begin(uint32_t line, const char* source, size_t sourceSz, const
|
||||
|
||||
void ScopedZone::End()
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if (!GetProfiler().IsConnected()) return;
|
||||
#endif
|
||||
TracyLfqPrepare( QueueType::ZoneEnd );
|
||||
MemWrite( &item->zoneEnd.time, Profiler::GetTime() );
|
||||
TracyLfqCommit;
|
||||
|
||||
@@ -46,6 +46,7 @@ struct TRACY_API SourceLocationData
|
||||
class TRACY_API ScopedZone
|
||||
{
|
||||
public:
|
||||
static void Begin( const SourceLocationData* srcloc );
|
||||
static void Begin( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const Char* name, size_t nameSz );
|
||||
static void End();
|
||||
|
||||
|
||||
@@ -1028,7 +1028,7 @@ namespace Flax.Build.Bindings
|
||||
contents.AppendLine(" auto scriptVTable = (MMethod**)managedTypePtr->Script.ScriptVTable;");
|
||||
contents.AppendLine($" ASSERT(scriptVTable && scriptVTable[{scriptVTableIndex}]);");
|
||||
contents.AppendLine($" auto method = scriptVTable[{scriptVTableIndex}];");
|
||||
contents.AppendLine(" PROFILE_CPU_NAMED(*method->ProfilerName);");
|
||||
contents.AppendLine($" PROFILE_CPU_NAMED(\"{classInfo.FullNameManaged}::{functionInfo.Name}\");");
|
||||
contents.AppendLine(" MonoObject* exception = nullptr;");
|
||||
|
||||
contents.AppendLine(" auto prevWrapperCallInstance = WrapperCallInstance;");
|
||||
@@ -1290,7 +1290,7 @@ namespace Flax.Build.Bindings
|
||||
contents.Append(" if (!mmethod)").AppendLine();
|
||||
contents.AppendFormat(" mmethod = {1}::TypeInitializer.GetType().ManagedClass->GetMethod(\"Internal_{0}_Invoke\", {2});", eventInfo.Name, classTypeNameNative, paramsCount).AppendLine();
|
||||
contents.Append(" CHECK(mmethod);").AppendLine();
|
||||
contents.Append(" PROFILE_CPU_NAMED(*mmethod->ProfilerName);").AppendLine();
|
||||
contents.Append($" PROFILE_CPU_NAMED(\"{classInfo.FullNameManaged}::On{eventInfo.Name}\");").AppendLine();
|
||||
contents.Append(" MonoObject* exception = nullptr;").AppendLine();
|
||||
if (paramsCount == 0)
|
||||
contents.AppendLine(" void** params = nullptr;");
|
||||
|
||||
Reference in New Issue
Block a user