summaryrefslogtreecommitdiffstats
path: root/external/optick
diff options
context:
space:
mode:
Diffstat (limited to 'external/optick')
-rw-r--r--external/optick/optick.config.h51
-rw-r--r--external/optick/optick.h872
-rw-r--r--external/optick/optick_common.h142
-rw-r--r--external/optick/optick_core.cpp1657
-rw-r--r--external/optick/optick_core.h568
-rw-r--r--external/optick/optick_core.linux.h410
-rw-r--r--external/optick/optick_core.macos.h289
-rw-r--r--external/optick/optick_core.platform.h92
-rw-r--r--external/optick/optick_core.win.h1664
-rw-r--r--external/optick/optick_gpu.cpp136
-rw-r--r--external/optick/optick_gpu.d3d12.cpp382
-rw-r--r--external/optick/optick_gpu.h129
-rw-r--r--external/optick/optick_gpu.vulkan.cpp365
-rw-r--r--external/optick/optick_memory.h419
-rw-r--r--external/optick/optick_message.cpp172
-rw-r--r--external/optick/optick_message.h130
-rw-r--r--external/optick/optick_serialization.cpp178
-rw-r--r--external/optick/optick_serialization.h120
-rw-r--r--external/optick/optick_server.cpp338
-rw-r--r--external/optick/optick_server.h42
20 files changed, 0 insertions, 8156 deletions
diff --git a/external/optick/optick.config.h b/external/optick/optick.config.h
deleted file mode 100644
index dcc6e98..0000000
--- a/external/optick/optick.config.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#pragma once
-
-#define OPTICK_ENABLE_GPU_D3D12 false
-#define OPTICK_ENABLE_GPU_VULKAN false
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// GLOBAL SETTINGS
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// [x] USE_OPTICK - (Master Switch)
-// [x] OPTICK_ENABLE_TRACING - (Enable Kernel-level tracing)
-// [x] OPTICK_ENABLE_GPU_D3D12 - (GPU D3D12)
-// [ ] OPTICK_ENABLE_GPU_VULKAN - (GPU VULKAN)
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// MASTER SWITCH - use it for disabling profiler in final builds //
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-#if !defined(USE_OPTICK)
-#define USE_OPTICK (1)
-#endif
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Enable Low-level platform-specific tracing (Switch Contexts, Autosampling, etc.)
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-#if !defined(OPTICK_ENABLE_TRACING)
-#define OPTICK_ENABLE_TRACING (USE_OPTICK /*&& 0*/)
-#endif //OPTICK_ENABLE_TRACING
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// GPU Counters
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-#if !defined(OPTICK_ENABLE_GPU)
-#define OPTICK_ENABLE_GPU (USE_OPTICK /*&& 0*/)
-#endif //OPTICK_ENABLE_GPU
-
-// D3D12
-#if !defined(OPTICK_ENABLE_GPU_D3D12)
-#if defined(_MSC_VER)
-#define OPTICK_ENABLE_GPU_D3D12 (OPTICK_ENABLE_GPU /*&& 0*/)
-#else
-#define OPTICK_ENABLE_GPU_D3D12 (0)
-#endif
-#endif
-
-// VUKLAN
-#if !defined(OPTICK_ENABLE_GPU_VULKAN)
-#define OPTICK_ENABLE_GPU_VULKAN (OPTICK_ENABLE_GPU && 0)
-#endif
-
diff --git a/external/optick/optick.h b/external/optick/optick.h
deleted file mode 100644
index e3eb512..0000000
--- a/external/optick/optick.h
+++ /dev/null
@@ -1,872 +0,0 @@
-#pragma once
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Config
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-#include "optick.config.h"
-
-#if USE_OPTICK
-#include <stdint.h>
-
-#if defined(__clang__) || defined(__GNUC__)
-# define OPTICK_GCC (1)
-# if defined(__APPLE_CC__)
-# define OPTICK_OSX (1)
-# elif defined(__linux__)
-# define OPTICK_LINUX (1)
-# elif defined(__ORBIS__)
-# define OPTICK_PS4 (1)
-# endif
-#elif defined(_MSC_VER)
-# define OPTICK_MSVC (1)
-# if defined(_DURANGO)
-# define OPTICK_XBOX (1)
-# else
-# define OPTICK_PC (1)
-#endif
-#else
-#error Compiler not supported
-#endif
-
-////////////////////////////////////////////////////////////////////////
-// Target Platform
-////////////////////////////////////////////////////////////////////////
-
-#if defined(OPTICK_GCC)
-#define OPTICK_FUNC __PRETTY_FUNCTION__
-#elif defined(OPTICK_MSVC)
-#define OPTICK_FUNC __FUNCSIG__
-#else
-#error Compiler not supported
-#endif
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// EXPORTS
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-#ifdef OPTICK_EXPORTS
-#define OPTICK_API __declspec(dllexport)
-#else
-#define OPTICK_API //__declspec(dllimport)
-#endif
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-#define OPTICK_CONCAT_IMPL(x, y) x##y
-#define OPTICK_CONCAT(x, y) OPTICK_CONCAT_IMPL(x, y)
-
-#if defined(OPTICK_MSVC)
-#define OPTICK_INLINE __forceinline
-#elif defined(OPTICK_GCC)
-#define OPTICK_INLINE __attribute__((always_inline)) inline
-#else
-#error Compiler is not supported
-#endif
-
-
-// Vulkan Forward Declarations
-#define OPTICK_DEFINE_HANDLE(object) typedef struct object##_T* object;
-OPTICK_DEFINE_HANDLE(VkDevice);
-OPTICK_DEFINE_HANDLE(VkPhysicalDevice);
-OPTICK_DEFINE_HANDLE(VkQueue);
-OPTICK_DEFINE_HANDLE(VkCommandBuffer);
-
-// D3D12 Forward Declarations
-struct ID3D12CommandList;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-namespace Optick
-{
- // Source: http://msdn.microsoft.com/en-us/library/system.windows.media.colors(v=vs.110).aspx
- // Image: http://i.msdn.microsoft.com/dynimg/IC24340.png
- struct Color
- {
- enum
- {
- Null = 0x00000000,
- AliceBlue = 0xFFF0F8FF,
- AntiqueWhite = 0xFFFAEBD7,
- Aqua = 0xFF00FFFF,
- Aquamarine = 0xFF7FFFD4,
- Azure = 0xFFF0FFFF,
- Beige = 0xFFF5F5DC,
- Bisque = 0xFFFFE4C4,
- Black = 0xFF000000,
- BlanchedAlmond = 0xFFFFEBCD,
- Blue = 0xFF0000FF,
- BlueViolet = 0xFF8A2BE2,
- Brown = 0xFFA52A2A,
- BurlyWood = 0xFFDEB887,
- CadetBlue = 0xFF5F9EA0,
- Chartreuse = 0xFF7FFF00,
- Chocolate = 0xFFD2691E,
- Coral = 0xFFFF7F50,
- CornflowerBlue = 0xFF6495ED,
- Cornsilk = 0xFFFFF8DC,
- Crimson = 0xFFDC143C,
- Cyan = 0xFF00FFFF,
- DarkBlue = 0xFF00008B,
- DarkCyan = 0xFF008B8B,
- DarkGoldenRod = 0xFFB8860B,
- DarkGray = 0xFFA9A9A9,
- DarkGreen = 0xFF006400,
- DarkKhaki = 0xFFBDB76B,
- DarkMagenta = 0xFF8B008B,
- DarkOliveGreen = 0xFF556B2F,
- DarkOrange = 0xFFFF8C00,
- DarkOrchid = 0xFF9932CC,
- DarkRed = 0xFF8B0000,
- DarkSalmon = 0xFFE9967A,
- DarkSeaGreen = 0xFF8FBC8F,
- DarkSlateBlue = 0xFF483D8B,
- DarkSlateGray = 0xFF2F4F4F,
- DarkTurquoise = 0xFF00CED1,
- DarkViolet = 0xFF9400D3,
- DeepPink = 0xFFFF1493,
- DeepSkyBlue = 0xFF00BFFF,
- DimGray = 0xFF696969,
- DodgerBlue = 0xFF1E90FF,
- FireBrick = 0xFFB22222,
- FloralWhite = 0xFFFFFAF0,
- ForestGreen = 0xFF228B22,
- Fuchsia = 0xFFFF00FF,
- Gainsboro = 0xFFDCDCDC,
- GhostWhite = 0xFFF8F8FF,
- Gold = 0xFFFFD700,
- GoldenRod = 0xFFDAA520,
- Gray = 0xFF808080,
- Green = 0xFF008000,
- GreenYellow = 0xFFADFF2F,
- HoneyDew = 0xFFF0FFF0,
- HotPink = 0xFFFF69B4,
- IndianRed = 0xFFCD5C5C,
- Indigo = 0xFF4B0082,
- Ivory = 0xFFFFFFF0,
- Khaki = 0xFFF0E68C,
- Lavender = 0xFFE6E6FA,
- LavenderBlush = 0xFFFFF0F5,
- LawnGreen = 0xFF7CFC00,
- LemonChiffon = 0xFFFFFACD,
- LightBlue = 0xFFADD8E6,
- LightCoral = 0xFFF08080,
- LightCyan = 0xFFE0FFFF,
- LightGoldenRodYellow = 0xFFFAFAD2,
- LightGray = 0xFFD3D3D3,
- LightGreen = 0xFF90EE90,
- LightPink = 0xFFFFB6C1,
- LightSalmon = 0xFFFFA07A,
- LightSeaGreen = 0xFF20B2AA,
- LightSkyBlue = 0xFF87CEFA,
- LightSlateGray = 0xFF778899,
- LightSteelBlue = 0xFFB0C4DE,
- LightYellow = 0xFFFFFFE0,
- Lime = 0xFF00FF00,
- LimeGreen = 0xFF32CD32,
- Linen = 0xFFFAF0E6,
- Magenta = 0xFFFF00FF,
- Maroon = 0xFF800000,
- MediumAquaMarine = 0xFF66CDAA,
- MediumBlue = 0xFF0000CD,
- MediumOrchid = 0xFFBA55D3,
- MediumPurple = 0xFF9370DB,
- MediumSeaGreen = 0xFF3CB371,
- MediumSlateBlue = 0xFF7B68EE,
- MediumSpringGreen = 0xFF00FA9A,
- MediumTurquoise = 0xFF48D1CC,
- MediumVioletRed = 0xFFC71585,
- MidnightBlue = 0xFF191970,
- MintCream = 0xFFF5FFFA,
- MistyRose = 0xFFFFE4E1,
- Moccasin = 0xFFFFE4B5,
- NavajoWhite = 0xFFFFDEAD,
- Navy = 0xFF000080,
- OldLace = 0xFFFDF5E6,
- Olive = 0xFF808000,
- OliveDrab = 0xFF6B8E23,
- Orange = 0xFFFFA500,
- OrangeRed = 0xFFFF4500,
- Orchid = 0xFFDA70D6,
- PaleGoldenRod = 0xFFEEE8AA,
- PaleGreen = 0xFF98FB98,
- PaleTurquoise = 0xFFAFEEEE,
- PaleVioletRed = 0xFFDB7093,
- PapayaWhip = 0xFFFFEFD5,
- PeachPuff = 0xFFFFDAB9,
- Peru = 0xFFCD853F,
- Pink = 0xFFFFC0CB,
- Plum = 0xFFDDA0DD,
- PowderBlue = 0xFFB0E0E6,
- Purple = 0xFF800080,
- Red = 0xFFFF0000,
- RosyBrown = 0xFFBC8F8F,
- RoyalBlue = 0xFF4169E1,
- SaddleBrown = 0xFF8B4513,
- Salmon = 0xFFFA8072,
- SandyBrown = 0xFFF4A460,
- SeaGreen = 0xFF2E8B57,
- SeaShell = 0xFFFFF5EE,
- Sienna = 0xFFA0522D,
- Silver = 0xFFC0C0C0,
- SkyBlue = 0xFF87CEEB,
- SlateBlue = 0xFF6A5ACD,
- SlateGray = 0xFF708090,
- Snow = 0xFFFFFAFA,
- SpringGreen = 0xFF00FF7F,
- SteelBlue = 0xFF4682B4,
- Tan = 0xFFD2B48C,
- Teal = 0xFF008080,
- Thistle = 0xFFD8BFD8,
- Tomato = 0xFFFF6347,
- Turquoise = 0xFF40E0D0,
- Violet = 0xFFEE82EE,
- Wheat = 0xFFF5DEB3,
- White = 0xFFFFFFFF,
- WhiteSmoke = 0xFFF5F5F5,
- Yellow = 0xFFFFFF00,
- YellowGreen = 0xFF9ACD32,
- };
- };
-
- struct Filter
- {
- enum Type : uint32_t
- {
- None,
-
- // CPU
- AI,
- Animation,
- Audio,
- Debug,
- Camera,
- Cloth,
- GameLogic,
- Input,
- Navigation,
- Network,
- Physics,
- Rendering,
- Scene,
- Script,
- Streaming,
- UI,
- VFX,
- Visibility,
- Wait,
-
- // IO
- IO,
-
- // GPU
- GPU_Cloth,
- GPU_Lighting,
- GPU_PostFX,
- GPU_Reflections,
- GPU_Scene,
- GPU_Shadows,
- GPU_UI,
- GPU_VFX,
- GPU_Water,
-
- };
- };
-
- #define OPTICK_MAKE_CATEGORY(filter, color) (((uint64_t)(1ull) << (filter + 32)) | (uint64_t)color)
-
- struct Category
- {
- enum Type : uint64_t
- {
- // CPU
- None = OPTICK_MAKE_CATEGORY(Filter::None, Color::Null),
- AI = OPTICK_MAKE_CATEGORY(Filter::AI, Color::Purple),
- Animation = OPTICK_MAKE_CATEGORY(Filter::Animation, Color::LightSkyBlue),
- Audio = OPTICK_MAKE_CATEGORY(Filter::Audio, Color::HotPink),
- Debug = OPTICK_MAKE_CATEGORY(Filter::Debug, Color::Black),
- Camera = OPTICK_MAKE_CATEGORY(Filter::Camera, Color::Black),
- Cloth = OPTICK_MAKE_CATEGORY(Filter::Cloth, Color::DarkGreen),
- GameLogic = OPTICK_MAKE_CATEGORY(Filter::GameLogic, Color::RoyalBlue),
- Input = OPTICK_MAKE_CATEGORY(Filter::Input, Color::Ivory),
- Navigation = OPTICK_MAKE_CATEGORY(Filter::Navigation, Color::Magenta),
- Network = OPTICK_MAKE_CATEGORY(Filter::Network, Color::Olive),
- Physics = OPTICK_MAKE_CATEGORY(Filter::Physics, Color::LawnGreen),
- Rendering = OPTICK_MAKE_CATEGORY(Filter::Rendering, Color::BurlyWood),
- Scene = OPTICK_MAKE_CATEGORY(Filter::Scene, Color::RoyalBlue),
- Script = OPTICK_MAKE_CATEGORY(Filter::Script, Color::Plum),
- Streaming = OPTICK_MAKE_CATEGORY(Filter::Streaming, Color::Gold),
- UI = OPTICK_MAKE_CATEGORY(Filter::UI, Color::PaleTurquoise),
- VFX = OPTICK_MAKE_CATEGORY(Filter::VFX, Color::SaddleBrown),
- Visibility = OPTICK_MAKE_CATEGORY(Filter::Visibility, Color::Snow),
- Wait = OPTICK_MAKE_CATEGORY(Filter::Wait, Color::Tomato),
- WaitEmpty = OPTICK_MAKE_CATEGORY(Filter::Wait, Color::White),
- // IO
- IO = OPTICK_MAKE_CATEGORY(Filter::IO, Color::Khaki),
- // GPU
- GPU_Cloth = OPTICK_MAKE_CATEGORY(Filter::GPU_Cloth, Color::DarkGreen),
- GPU_Lighting = OPTICK_MAKE_CATEGORY(Filter::GPU_Lighting, Color::Khaki),
- GPU_PostFX = OPTICK_MAKE_CATEGORY(Filter::GPU_PostFX, Color::Maroon),
- GPU_Reflections = OPTICK_MAKE_CATEGORY(Filter::GPU_Reflections, Color::CadetBlue),
- GPU_Scene = OPTICK_MAKE_CATEGORY(Filter::GPU_Scene, Color::RoyalBlue),
- GPU_Shadows = OPTICK_MAKE_CATEGORY(Filter::GPU_Shadows, Color::LightSlateGray),
- GPU_UI = OPTICK_MAKE_CATEGORY(Filter::GPU_UI, Color::PaleTurquoise),
- GPU_VFX = OPTICK_MAKE_CATEGORY(Filter::GPU_VFX, Color::SaddleBrown),
- GPU_Water = OPTICK_MAKE_CATEGORY(Filter::GPU_Water, Color::SteelBlue),
- };
-
- static uint32_t GetMask(Type t) { return (uint32_t)(t >> 32); }
- static uint32_t GetColor(Type t) { return (uint32_t)(t); }
- };
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-}
-
-
-namespace Optick
-{
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct Mode
-{
- enum Type
- {
- OFF = 0x0,
- INSTRUMENTATION_CATEGORIES = (1 << 0),
- INSTRUMENTATION_EVENTS = (1 << 1),
- INSTRUMENTATION = (INSTRUMENTATION_CATEGORIES | INSTRUMENTATION_EVENTS),
- SAMPLING = (1 << 2),
- TAGS = (1 << 3),
- AUTOSAMPLING = (1 << 4),
- SWITCH_CONTEXT = (1 << 5),
- IO = (1 << 6),
- GPU = (1 << 7),
- END_SCREENSHOT = (1 << 8),
- RESERVED_0 = (1 << 9),
- RESERVED_1 = (1 << 10),
- HW_COUNTERS = (1 << 11),
- LIVE = (1 << 12),
- RESERVED_2 = (1 << 13),
- RESERVED_3 = (1 << 14),
- RESERVED_4 = (1 << 15),
- SYS_CALLS = (1 << 16),
- OTHER_PROCESSES = (1 << 17),
-
- TRACER = AUTOSAMPLING | SWITCH_CONTEXT | SYS_CALLS,
- DEFAULT = INSTRUMENTATION | TAGS | AUTOSAMPLING | SWITCH_CONTEXT | IO | GPU | SYS_CALLS | OTHER_PROCESSES,
- };
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API int64_t GetHighPrecisionTime();
-OPTICK_API int64_t GetHighPrecisionFrequency();
-OPTICK_API uint32_t NextFrame();
-OPTICK_API bool IsActive(Mode::Type mode = Mode::INSTRUMENTATION_EVENTS);
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct EventStorage;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool RegisterFiber(uint64_t fiberId, EventStorage** slot);
-OPTICK_API bool RegisterThread(const char* name);
-OPTICK_API bool RegisterThread(const wchar_t* name);
-OPTICK_API bool UnRegisterThread(bool keepAlive);
-OPTICK_API EventStorage** GetEventStorageSlotForCurrentThread();
-OPTICK_API bool IsFiberStorage(EventStorage* fiberStorage);
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct ThreadMask
-{
- enum Type
- {
- None = 0,
- Main = 1 << 0,
- GPU = 1 << 1,
- IO = 1 << 2,
- Idle = 1 << 3,
- };
-};
-
-OPTICK_API EventStorage* RegisterStorage(const char* name, uint64_t threadID = uint64_t(-1), ThreadMask::Type type = ThreadMask::None);
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct State
-{
- enum Type
- {
- // Starting a new capture
- START_CAPTURE,
-
- // Stopping current capture
- STOP_CAPTURE,
-
- // Dumping capture to the GUI
- // Useful for attaching summary and screenshot to the capture
- DUMP_CAPTURE,
-
- // Cancel current capture
- CANCEL_CAPTURE,
- };
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Sets a state change callback
-typedef bool (*StateCallback)(State::Type state);
-OPTICK_API bool SetStateChangedCallback(StateCallback cb);
-
-// Attaches a key-value pair to the capture's summary
-// Example: AttachSummary("Version", "v12.0.1");
-// AttachSummary("Platform", "Windows");
-// AttachSummary("Config", "Release_x64");
-// AttachSummary("Settings", "Ultra");
-// AttachSummary("Map", "Atlantida");
-// AttachSummary("Position", "123.0,120.0,41.1");
-// AttachSummary("CPU", "Intel(R) Xeon(R) CPU E5410@2.33GHz");
-// AttachSummary("GPU", "NVIDIA GeForce GTX 980 Ti");
-OPTICK_API bool AttachSummary(const char* key, const char* value);
-
-struct File
-{
- enum Type
- {
- // Supported formats: PNG, JPEG, BMP, TIFF
- OPTICK_IMAGE,
-
- // Text file
- OPTICK_TEXT,
-
- // Any other type
- OPTICK_OTHER,
- };
-};
-// Attaches a file to the current capture
-OPTICK_API bool AttachFile(File::Type type, const char* name, const uint8_t* data, uint32_t size);
-OPTICK_API bool AttachFile(File::Type type, const char* name, const char* path);
-OPTICK_API bool AttachFile(File::Type type, const char* name, const wchar_t* path);
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct EventDescription;
-struct Frame;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct EventTime
-{
- static const int64_t INVALID_TIMESTAMP = (int64_t)-1;
-
- int64_t start;
- int64_t finish;
-
- OPTICK_INLINE void Start() { start = Optick::GetHighPrecisionTime(); }
- OPTICK_INLINE void Stop() { finish = Optick::GetHighPrecisionTime(); }
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct EventData : public EventTime
-{
- const EventDescription* description;
-
- bool operator<(const EventData& other) const
- {
- if (start != other.start)
- return start < other.start;
-
- // Reversed order for finish intervals (parent first)
- return finish > other.finish;
- }
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct OPTICK_API SyncData : public EventTime
-{
- uint64_t newThreadId;
- uint64_t oldThreadId;
- uint8_t core;
- int8_t reason;
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct OPTICK_API FiberSyncData : public EventTime
-{
- uint64_t threadId;
-
- static void AttachToThread(EventStorage* storage, uint64_t threadId);
- static void DetachFromThread(EventStorage* storage);
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-template<class T>
-struct TagData
-{
- const EventDescription* description;
- int64_t timestamp;
- T data;
- TagData() {}
- TagData(const EventDescription& desc, T d) : description(&desc), timestamp(Optick::GetHighPrecisionTime()), data(d) {}
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct OPTICK_API EventDescription
-{
- // HOT \\
- // Have to place "hot" variables at the beginning of the class (here will be some padding)
- // COLD //
-
- const char* name;
- const char* file;
- uint32_t line;
- uint32_t index;
- uint32_t color;
- uint32_t filter;
- float budget;
-
- static EventDescription* Create(const char* eventName, const char* fileName, const unsigned long fileLine, const unsigned long eventColor = Color::Null, const unsigned long filter = 0);
- static EventDescription* CreateShared(const char* eventName, const char* fileName = nullptr, const unsigned long fileLine = 0, const unsigned long eventColor = Color::Null, const unsigned long filter = 0);
-
- EventDescription();
-private:
- friend class EventDescriptionBoard;
- EventDescription& operator=(const EventDescription&);
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct OPTICK_API Event
-{
- EventData* data;
-
- static EventData* Start(const EventDescription& description);
- static void Stop(EventData& data);
-
- static void Push(const char* name);
- static void Push(const EventDescription& description);
- static void Pop();
-
- static void Add(EventStorage* storage, const EventDescription* description, int64_t timestampStart, int64_t timestampFinish);
- static void Push(EventStorage* storage, const EventDescription* description, int64_t timestampStart);
- static void Pop(EventStorage* storage, int64_t timestampStart);
-
-
- Event(const EventDescription& description)
- {
- data = Start(description);
- }
-
- ~Event()
- {
- if (data)
- Stop(*data);
- }
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_INLINE Optick::EventDescription* CreateDescription(const char* functionName, const char* fileName, int fileLine, const char* eventName = nullptr, const ::Optick::Category::Type category = ::Optick::Category::None)
-{
- return ::Optick::EventDescription::Create(eventName != nullptr ? eventName : functionName, fileName, (unsigned long)fileLine, ::Optick::Category::GetColor(category), ::Optick::Category::GetMask(category));
-}
-OPTICK_INLINE Optick::EventDescription* CreateDescription(const char* functionName, const char* fileName, int fileLine, const ::Optick::Category::Type category)
-{
- return ::Optick::EventDescription::Create(functionName, fileName, (unsigned long)fileLine, ::Optick::Category::GetColor(category), ::Optick::Category::GetMask(category));
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct OPTICK_API GPUEvent
-{
- EventData* data;
-
- static EventData* Start(const EventDescription& description);
- static void Stop(EventData& data);
-
- GPUEvent(const EventDescription& description)
- {
- data = Start(description);
- }
-
- ~GPUEvent()
- {
- if (data)
- Stop(*data);
- }
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct OPTICK_API Tag
-{
- static void Attach(const EventDescription& description, float val);
- static void Attach(const EventDescription& description, int32_t val);
- static void Attach(const EventDescription& description, uint32_t val);
- static void Attach(const EventDescription& description, uint64_t val);
- static void Attach(const EventDescription& description, float val[3]);
- static void Attach(const EventDescription& description, const char* val);
-
- // Derived
- static void Attach(const EventDescription& description, float x, float y, float z)
- {
- float p[3] = { x, y, z }; Attach(description, p);
- }
-
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct ThreadScope
-{
- bool keepAlive;
-
- ThreadScope(const char* name, bool bKeepAlive = false) : keepAlive(bKeepAlive)
- {
- RegisterThread(name);
- }
-
- ThreadScope(const wchar_t* name)
- {
- RegisterThread(name);
- }
-
- ~ThreadScope()
- {
- UnRegisterThread(keepAlive);
- }
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-enum OPTICK_API GPUQueueType
-{
- GPU_QUEUE_GRAPHICS,
- GPU_QUEUE_COMPUTE,
- GPU_QUEUE_TRANSFER,
- GPU_QUEUE_VSYNC,
-
- GPU_QUEUE_COUNT,
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct OPTICK_API GPUContext
-{
- void* cmdBuffer;
- GPUQueueType queue;
- int node;
- GPUContext(void* c = nullptr, GPUQueueType q = GPU_QUEUE_GRAPHICS, int n = 0) : cmdBuffer(c), queue(q), node(n) {}
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API void InitGpuD3D12(void* device, void** cmdQueues, uint32_t numQueues);
-OPTICK_API void InitGpuVulkan(void* vkDevices, void* vkPhysicalDevices, void* vkQueues, uint32_t* cmdQueuesFamily, uint32_t numQueues);
-OPTICK_API void GpuFlip(void* swapChain);
-OPTICK_API GPUContext SetGpuContext(GPUContext context);
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct OPTICK_API GPUContextScope
-{
- GPUContext prevContext;
-
- GPUContextScope(ID3D12CommandList* cmdList, GPUQueueType queue = GPU_QUEUE_GRAPHICS, int node = 0)
- {
- prevContext = SetGpuContext(GPUContext(cmdList, queue, node));
- }
-
- GPUContextScope(VkCommandBuffer cmdBuffer, GPUQueueType queue = GPU_QUEUE_GRAPHICS, int node = 0)
- {
- prevContext = SetGpuContext(GPUContext(cmdBuffer, queue, node));
- }
-
- ~GPUContextScope()
- {
- SetGpuContext(prevContext);
- }
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct FrameType
-{
- enum Type
- {
- CPU,
- GPU,
- Render,
- COUNT,
- };
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API const EventDescription* GetFrameDescription(FrameType::Type frame);
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-}
-
-#define OPTICK_UNUSED(x) (void)(x)
-// Workaround for gcc compiler
-#define OPTICK_VA_ARGS(...) , ##__VA_ARGS__
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Scoped profiling event which automatically grabs current function name.
-// Use tis macro 95% of the time.
-// Example A:
-// void Function()
-// {
-// OPTICK_EVENT();
-// ... code ...
-// }
-// or
-// void Function()
-// {
-// OPTICK_EVENT("CustomFunctionName");
-// ... code ...
-// }
-// Notes:
-// Optick captures full name of the function including name space and arguments.
-// Full name is usually shortened in the Optick GUI in order to highlight the most important bits.
-#define OPTICK_EVENT(...) static ::Optick::EventDescription* OPTICK_CONCAT(autogen_description_, __LINE__) = nullptr; \
- if (OPTICK_CONCAT(autogen_description_, __LINE__) == nullptr) OPTICK_CONCAT(autogen_description_, __LINE__) = ::Optick::CreateDescription(OPTICK_FUNC, __FILE__, __LINE__ OPTICK_VA_ARGS(__VA_ARGS__)); \
- ::Optick::Event OPTICK_CONCAT(autogen_event_, __LINE__)( *(OPTICK_CONCAT(autogen_description_, __LINE__)) );
-
-// Backward compatibility with previous versions of Optick
-//#if !defined(PROFILE)
-//#define PROFILE OPTICK_EVENT()
-//#endif
-
-// Scoped profiling macro with predefined color.
-// Use this macro for high-level function calls (e.g. AI, Physics, Audio, Render etc.).
-// Example:
-// void UpdateAI()
-// {
-// OPTICK_CATEGORY("UpdateAI", Optick::Category::AI);
-// ... code ...
-// }
-//
-// Macro could automatically capture current function name:
-// void UpdateAI()
-// {
-// OPTICK_CATEGORY(OPTICK_FUNC, Optick::Category::AI);
-// ... code ...
-// }
-#define OPTICK_CATEGORY(NAME, CATEGORY) OPTICK_EVENT(NAME, CATEGORY)
-
-// Profiling event for Main Loop update.
-// You need to call this function in the beginning of the each new frame.
-// Example:
-// while (true)
-// {
-// OPTICK_FRAME("MainThread");
-// ... code ...
-// }
-#define OPTICK_FRAME(FRAME_NAME) static ::Optick::ThreadScope mainThreadScope(FRAME_NAME); \
- OPTICK_UNUSED(mainThreadScope); \
- uint32_t frameNumber = ::Optick::NextFrame(); \
- ::Optick::Event OPTICK_CONCAT(autogen_event_, __LINE__)(*::Optick::GetFrameDescription(::Optick::FrameType::CPU)); \
- OPTICK_TAG("Frame", frameNumber);
-
-
-// Thread registration macro.
-// Example:
-// void WorkerThread(...)
-// {
-// OPTICK_THREAD("Worker");
-// while (isRunning)
-// {
-// ...
-// }
-// }
-#define OPTICK_THREAD(THREAD_NAME) ::Optick::ThreadScope brofilerThreadScope(THREAD_NAME); \
- OPTICK_UNUSED(brofilerThreadScope); \
-
-
-// Thread registration macros.
-// Useful for integration with custom job-managers.
-#define OPTICK_START_THREAD(FRAME_NAME) ::Optick::RegisterThread(FRAME_NAME);
-#define OPTICK_STOP_THREAD() ::Optick::UnRegisterThread(false);
-
-// Attaches a custom data-tag.
-// Supported types: int32, uint32, uint64, vec3, string (cut to 32 characters)
-// Example:
-// OPTICK_TAG("PlayerName", name[index]);
-// OPTICK_TAG("Health", 100);
-// OPTICK_TAG("Score", 0x80000000u);
-// OPTICK_TAG("Height(cm)", 176.3f);
-// OPTICK_TAG("Address", (uint64)*this);
-// OPTICK_TAG("Position", 123.0f, 456.0f, 789.0f);
-#define OPTICK_TAG(NAME, ...) static ::Optick::EventDescription* OPTICK_CONCAT(autogen_tag_, __LINE__) = nullptr; \
- if (OPTICK_CONCAT(autogen_tag_, __LINE__) == nullptr) OPTICK_CONCAT(autogen_tag_, __LINE__) = ::Optick::EventDescription::Create( NAME, __FILE__, __LINE__ ); \
- ::Optick::Tag::Attach(*OPTICK_CONCAT(autogen_tag_, __LINE__), __VA_ARGS__); \
-
-// Scoped macro with DYNAMIC name.
-// Optick holds a copy of the provided name.
-// Each scope does a search in hashmap for the name.
-// Please use variations with STATIC names where it's possible.
-// Use this macro for quick prototyping or intergratoin with other profiling systems (e.g. UE4)
-// Example:
-// const char* name = ... ;
-// OPTICK_EVENT_DYNAMIC(name);
-#define OPTICK_EVENT_DYNAMIC(NAME) OPTICK_CUSTOM_EVENT(::Optick::EventDescription::CreateShared(NAME, __FILE__, __LINE__));
-// Push\Pop profiling macro with DYNAMIC name.
-#define OPTICK_PUSH_DYNAMIC(NAME) ::Optick::Event::Push(NAME);
-
-// Push\Pop profiling macro with STATIC name.
-// Please avoid using Push\Pop approach in favor for scoped macros.
-// For backward compatibility with some engines.
-// Example:
-// OPTICK_PUSH("ScopeName");
-// ...
-// OPTICK_POP();
-#define OPTICK_PUSH(NAME) static ::Optick::EventDescription* OPTICK_CONCAT(autogen_description_, __LINE__) = nullptr; \
- if (OPTICK_CONCAT(autogen_description_, __LINE__) == nullptr) OPTICK_CONCAT(autogen_description_, __LINE__) = ::Optick::EventDescription::Create( NAME, __FILE__, __LINE__ ); \
- ::Optick::Event::Push(*OPTICK_CONCAT(autogen_description_, __LINE__));
-#define OPTICK_POP() ::Optick::Event::Pop();
-
-
-// Scoped macro with predefined Optick::EventDescription.
-// Use these events instead of DYNAMIC macros to minimize overhead.
-// Common use-case: integrating Optick with internal script languages (e.g. Lua, Actionscript(Scaleform), etc.).
-// Example:
-// Generating EventDescription once during initialization:
-// Optick::EventDescription* description = Optick::EventDescription::CreateShared("FunctionName");
-//
-// Then we could just use a pointer to cached description later for profiling:
-// OPTICK_CUSTOM_EVENT(description);
-#define OPTICK_CUSTOM_EVENT(DESCRIPTION) ::Optick::Event OPTICK_CONCAT(autogen_event_, __LINE__)( *DESCRIPTION ); \
-
-// Registration of a custom EventStorage (e.g. GPU, IO, etc.)
-// Use it to present any extra information on the timeline.
-// Example:
-// Optick::EventStorage* IOStorage = Optick::RegisterStorage("I/O");
-// Notes:
-// Registration of a new storage is thread-safe.
-#define OPTICK_STORAGE_REGISTER(STORAGE_NAME) ::Optick::RegisterStorage(STORAGE_NAME);
-
-// Adding events to the custom storage.
-// Helps to integrate Optick into already existing profiling systems (e.g. GPU Profiler, I/O profiler, etc.).
-// Example:
-// //Registering a storage - should be done once during initialization
-// static Optick::EventStorage* IOStorage = Optick::RegisterStorage("I/O");
-//
-// int64_t cpuTimestampStart = Optick::GetHighPrecisionTime();
-// ...
-// int64_t cpuTimestampFinish = Optick::GetHighPrecisionTime();
-//
-// //Creating a shared event-description
-// static Optick::EventDescription* IORead = Optick::EventDescription::CreateShared("IO Read");
-//
-// OPTICK_STORAGE_EVENT(IOStorage, IORead, cpuTimestampStart, cpuTimestampFinish);
-// Notes:
-// It's not thread-safe to add events to the same storage from multiple threads.
-// Please guarantee thread-safety on the higher level if access from multiple threads to the same storage is required.
-#define OPTICK_STORAGE_EVENT(STORAGE, DESCRIPTION, CPU_TIMESTAMP_START, CPU_TIMESTAMP_FINISH) if (::Optick::IsActive()) { ::Optick::Event::Add(STORAGE, DESCRIPTION, CPU_TIMESTAMP_START, CPU_TIMESTAMP_FINISH); }
-#define OPTICK_STORAGE_PUSH(STORAGE, DESCRIPTION, CPU_TIMESTAMP_START) if (::Optick::IsActive()) { ::Optick::Event::Push(STORAGE, DESCRIPTION, CPU_TIMESTAMP_START); }
-#define OPTICK_STORAGE_POP(STORAGE, CPU_TIMESTAMP_FINISH) if (::Optick::IsActive()) { ::Optick::Event::Pop(STORAGE, CPU_TIMESTAMP_FINISH); }
-
-
-// Registers state change callback
-// If callback returns false - the call is repeated the next frame
-#define OPTICK_SET_STATE_CHANGED_CALLBACK(CALLBACK) ::Optick::SetStateChangedCallback(CALLBACK);
-
-
-// GPU events
-#define OPTICK_GPU_INIT_D3D12(DEVICE, CMD_QUEUES, NUM_CMD_QUEUS) ::Optick::InitGpuD3D12(DEVICE, CMD_QUEUES, NUM_CMD_QUEUS);
-#define OPTICK_GPU_INIT_VULKAN(DEVICES, PHYSICAL_DEVICES, CMD_QUEUES, CMD_QUEUES_FAMILY, NUM_CMD_QUEUS) ::Optick::InitGpuVulkan(DEVICES, PHYSICAL_DEVICES, CMD_QUEUES, CMD_QUEUES_FAMILY, NUM_CMD_QUEUS);
-
-// Setup GPU context:
-// Params:
-// (CommandBuffer\CommandList, [Optional] Optick::GPUQueue queue, [Optional] int NodeIndex)
-// Examples:
-// OPTICK_GPU_CONTEXT(cmdBuffer); - all OPTICK_GPU_EVENT will use the same command buffer within the scope
-// OPTICK_GPU_CONTEXT(cmdBuffer, Optick::GPU_QUEUE_COMPUTE); - all events will use the same command buffer and queue for the scope
-// OPTICK_GPU_CONTEXT(cmdBuffer, Optick::GPU_QUEUE_COMPUTE, gpuIndex); - all events will use the same command buffer and queue for the scope
-#define OPTICK_GPU_CONTEXT(...) ::Optick::GPUContextScope OPTICK_CONCAT(gpu_autogen_context_, __LINE__)(__VA_ARGS__); \
- (void)OPTICK_CONCAT(gpu_autogen_context_, __LINE__);
-
-#define OPTICK_GPU_EVENT(NAME) OPTICK_EVENT(NAME); \
- static ::Optick::EventDescription* OPTICK_CONCAT(gpu_autogen_description_, __LINE__) = nullptr; \
- if (OPTICK_CONCAT(gpu_autogen_description_, __LINE__) == nullptr) OPTICK_CONCAT(gpu_autogen_description_, __LINE__) = ::Optick::EventDescription::Create( NAME, __FILE__, __LINE__ ); \
- ::Optick::GPUEvent OPTICK_CONCAT(gpu_autogen_event_, __LINE__)( *(OPTICK_CONCAT(gpu_autogen_description_, __LINE__)) ); \
-
-#define OPTICK_GPU_FLIP(SWAP_CHAIN) ::Optick::GpuFlip(SWAP_CHAIN);
-
-#else
-#define OPTICK_EVENT(...)
-#define OPTICK_CATEGORY(NAME, COLOR)
-#define OPTICK_FRAME(NAME)
-#define OPTICK_THREAD(FRAME_NAME)
-#define OPTICK_START_THREAD(FRAME_NAME)
-#define OPTICK_STOP_THREAD()
-#define OPTICK_TAG(NAME, DATA)
-#define OPTICK_EVENT_DYNAMIC(NAME)
-#define OPTICK_PUSH_DYNAMIC(NAME)
-#define OPTICK_PUSH(NAME)
-#define OPTICK_POP()
-#define OPTICK_CUSTOM_EVENT(DESCRIPTION)
-#define OPTICK_STORAGE_REGISTER(STORAGE_NAME)
-#define OPTICK_STORAGE_EVENT(STORAGE, DESCRIPTION, CPU_TIMESTAMP_START, CPU_TIMESTAMP_FINISH)
-#define OPTICK_STORAGE_PUSH(STORAGE, DESCRIPTION, CPU_TIMESTAMP_START)
-#define OPTICK_STORAGE_POP(STORAGE, CPU_TIMESTAMP_FINISH)
-#define OPTICK_SET_STATE_CHANGED_CALLBACK(CALLBACK)
-#define OPTICK_GPU_INIT_D3D12(DEVICE, CMD_QUEUES, NUM_CMD_QUEUS)
-#define OPTICK_GPU_INIT_VULKAN(DEVICES, PHYSICAL_DEVICES, CMD_QUEUES, CMD_QUEUES_FAMILY, NUM_CMD_QUEUS)
-#define OPTICK_GPU_CONTEXT(...)
-#define OPTICK_GPU_EVENT(NAME)
-#define OPTICK_GPU_FLIP(SWAP_CHAIN)
-#endif
diff --git a/external/optick/optick_common.h b/external/optick/optick_common.h
deleted file mode 100644
index 4468911..0000000
--- a/external/optick/optick_common.h
+++ /dev/null
@@ -1,142 +0,0 @@
-#pragma once
-
-#include "optick.config.h"
-
-#if USE_OPTICK
-
-#include "optick.h"
-
-#include <cstdio>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#if defined(OPTICK_MSVC)
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN
-#endif
-#define NOMINMAX
-#include <windows.h>
-#endif
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Types
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-typedef signed char int8;
-typedef unsigned char uint8;
-typedef unsigned char byte;
-typedef short int16;
-typedef unsigned short uint16;
-typedef int int32;
-typedef unsigned int uint32;
-#if defined(OPTICK_MSVC)
-typedef __int64 int64;
-typedef unsigned __int64 uint64;
-#elif defined(OPTICK_GCC)
-typedef int64_t int64;
-typedef uint64_t uint64;
-#else
-#error Compiler is not supported
-#endif
-static_assert(sizeof(int8) == 1, "Invalid type size, int8");
-static_assert(sizeof(uint8) == 1, "Invalid type size, uint8");
-static_assert(sizeof(byte) == 1, "Invalid type size, byte");
-static_assert(sizeof(int16) == 2, "Invalid type size, int16");
-static_assert(sizeof(uint16) == 2, "Invalid type size, uint16");
-static_assert(sizeof(int32) == 4, "Invalid type size, int32");
-static_assert(sizeof(uint32) == 4, "Invalid type size, uint32");
-static_assert(sizeof(int64) == 8, "Invalid type size, int64");
-static_assert(sizeof(uint64) == 8, "Invalid type size, uint64");
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-typedef uint64 ThreadID;
-static const ThreadID INVALID_THREAD_ID = (ThreadID)-1;
-typedef uint32 ProcessID;
-static const ProcessID INVALID_PROCESS_ID = (ProcessID)-1;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Memory
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-#if defined(OPTICK_MSVC)
-#define OPTICK_ALIGN(N) __declspec( align( N ) )
-#elif defined(OPTICK_GCC)
-#define OPTICK_ALIGN(N) __attribute__((aligned(N)))
-#else
-#error Can not define OPTICK_ALIGN. Unknown platform.
-#endif
-#define OPTICK_CACHE_LINE_SIZE 64
-#define OPTICK_ALIGN_CACHE OPTICK_ALIGN(OPTICK_CACHE_LINE_SIZE)
-#define OPTICK_ARRAY_SIZE(ARR) (sizeof(ARR)/sizeof((ARR)[0]))
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-#if defined(OPTICK_MSVC)
-#define OPTICK_NOINLINE __declspec(noinline)
-#elif defined(OPTICK_GCC)
-#define OPTICK_NOINLINE __attribute__((__noinline__))
-#else
-#error Compiler is not supported
-#endif
-////////////////////////////////////////////////////////////////////////
-// OPTICK_THREAD_LOCAL
-////////////////////////////////////////////////////////////////////////
-#if defined(OPTICK_MSVC)
-#define OPTICK_THREAD_LOCAL __declspec(thread)
-#elif defined(OPTICK_GCC)
-#define OPTICK_THREAD_LOCAL __thread
-#else
-#error Can not define OPTICK_THREAD_LOCAL. Unknown platform.
-#endif
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Asserts
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-#if defined(OPTICK_MSVC)
-#define OPTICK_DEBUG_BREAK __debugbreak()
-#elif defined(OPTICK_GCC)
-#define OPTICK_DEBUG_BREAK __builtin_trap()
-#else
- #error Can not define OPTICK_DEBUG_BREAK. Unknown platform.
-#endif
-#define OPTICK_UNUSED(x) (void)(x)
-#ifdef _DEBUG
- #define OPTICK_ASSERT(arg, description) if (!(arg)) { OPTICK_DEBUG_BREAK; }
- #define OPTICK_FAILED(description) { OPTICK_DEBUG_BREAK; }
-#else
- #define OPTICK_ASSERT(arg, description)
- #define OPTICK_FAILED(description)
-#endif
-#define OPTICK_VERIFY(arg, description, operation) if (!(arg)) { OPTICK_DEBUG_BREAK; operation; }
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Safe functions
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-#if defined(OPTICK_LINUX) || defined(OPTICK_OSX)
-template<size_t sizeOfBuffer>
-inline int sprintf_s(char(&buffer)[sizeOfBuffer], const char* format, ...)
-{
- va_list ap;
- va_start(ap, format);
- int result = vsnprintf(buffer, sizeOfBuffer, format, ap);
- va_end(ap);
- return result;
-}
-#endif
-
-#if defined(OPTICK_GCC)
-template<size_t sizeOfBuffer>
-inline int wcstombs_s(char(&buffer)[sizeOfBuffer], const wchar_t* src, size_t maxCount)
-{
- return wcstombs(buffer, src, maxCount);
-}
-#endif
-
-#if defined(OPTICK_MSVC)
-template<size_t sizeOfBuffer>
-inline int wcstombs_s(char(&buffer)[sizeOfBuffer], const wchar_t* src, size_t maxCount)
-{
- size_t converted = 0;
- return wcstombs_s(&converted, buffer, src, maxCount);
-}
-#endif
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#endif //USE_OPTICK \ No newline at end of file
diff --git a/external/optick/optick_core.cpp b/external/optick/optick_core.cpp
deleted file mode 100644
index 1d533d0..0000000
--- a/external/optick/optick_core.cpp
+++ /dev/null
@@ -1,1657 +0,0 @@
-#include "optick.config.h"
-
-#if USE_OPTICK
-
-#include "optick_core.h"
-#include "optick_server.h"
-
-#include <algorithm>
-#include <fstream>
-
-//////////////////////////////////////////////////////////////////////////
-// Start of the Platform-specific stuff
-//////////////////////////////////////////////////////////////////////////
-#if defined(OPTICK_MSVC)
-#include "optick_core.win.h"
-#endif
-#if defined(OPTICK_LINUX)
-#include "optick_core.linux.h"
-#endif
-#if defined(OPTICK_OSX)
-#include "optick_core.macos.h"
-#endif
-#if defined(OPTICK_PS4)
-#include "optick_core.ps4.h"
-#endif
-//////////////////////////////////////////////////////////////////////////
-// End of the Platform-specific stuff
-//////////////////////////////////////////////////////////////////////////
-
-extern "C" Optick::EventData* NextEvent()
-{
- if (Optick::EventStorage* storage = Optick::Core::storage)
- {
- return &storage->NextEvent();
- }
-
- return nullptr;
-}
-
-namespace Optick
-{
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void* (*Memory::allocate)(size_t) = operator new;
-void (*Memory::deallocate)(void* p) = operator delete;
-std::atomic<uint64_t> Memory::memAllocated;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-uint64_t MurmurHash64A(const void * key, int len, uint64_t seed)
-{
- const uint64_t m = 0xc6a4a7935bd1e995;
- const int r = 47;
-
- uint64_t h = seed ^ (len * m);
-
- const uint64_t * data = (const uint64_t *)key;
- const uint64_t * end = data + (len / 8);
-
- while (data != end)
- {
- uint64_t k = *data++;
-
- k *= m;
- k ^= k >> r;
- k *= m;
-
- h ^= k;
- h *= m;
- }
-
- const unsigned char * data2 = (const unsigned char*)data;
-
- switch (len & 7)
- {
- case 7: h ^= uint64_t(data2[6]) << 48;
- case 6: h ^= uint64_t(data2[5]) << 40;
- case 5: h ^= uint64_t(data2[4]) << 32;
- case 4: h ^= uint64_t(data2[3]) << 24;
- case 3: h ^= uint64_t(data2[2]) << 16;
- case 2: h ^= uint64_t(data2[1]) << 8;
- case 1: h ^= uint64_t(data2[0]);
- h *= m;
- };
-
- h ^= h >> r;
- h *= m;
- h ^= h >> r;
-
- return h;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-uint64_t StringHash::CalcHash(const char* str)
-{
- return MurmurHash64A(str, (int)strlen(str), 0);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Base 64
-// https://renenyffenegger.ch/notes/development/Base64/Encoding-and-decoding-base-64-with-cpp
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-static inline bool is_base64(unsigned char c) {
- return (isalnum(c) || (c == '+') || (c == '/'));
-}
-string base64_decode(string const& encoded_string) {
- static string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- int in_len = (int)encoded_string.size();
- int i = 0;
- int j = 0;
- int in_ = 0;
- unsigned char char_array_4[4], char_array_3[3];
- string ret;
-
- while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
- char_array_4[i++] = encoded_string[in_]; in_++;
- if (i == 4) {
- for (i = 0; i < 4; i++)
- char_array_4[i] = (unsigned char)base64_chars.find(char_array_4[i]);
-
- char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
- char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
- char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
-
- for (i = 0; (i < 3); i++)
- ret += char_array_3[i];
- i = 0;
- }
- }
-
- if (i) {
- for (j = i; j < 4; j++)
- char_array_4[j] = 0;
-
- for (j = 0; j < 4; j++)
- char_array_4[j] = (unsigned char)base64_chars.find(char_array_4[j]);
-
- char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
- char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
- char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
-
- for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
- }
-
- return ret;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Get current time in milliseconds
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-int64 GetTimeMilliSeconds()
-{
- return Platform::GetTime() * 1000 / Platform::GetFrequency();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-int64 TicksToMs(int64 ticks)
-{
- return ticks * 1000 / Platform::GetFrequency();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-int64 TicksToUs(int64 ticks)
-{
- return ticks * 1000000 / Platform::GetFrequency();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-template<class T>
-OutputDataStream& operator<<(OutputDataStream& stream, const TagData<T>& ob)
-{
- return stream << ob.timestamp << ob.description->index << ob.data;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& os, const Symbol * const symbol)
-{
- OPTICK_VERIFY(symbol, "Can't serialize NULL symbol!", return os);
- return os << symbol->address << symbol->function << symbol->file << symbol->line;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& os, const Module& module)
-{
- return os << module.path << (uint64)module.address << (uint64)module.size;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// VS TODO: Replace with random access iterator for MemoryPool
-template<class T, uint32 SIZE>
-void SortMemoryPool(MemoryPool<T, SIZE>& memoryPool)
-{
- size_t count = memoryPool.Size();
- if (count == 0)
- return;
-
- vector<T> memoryArray;
- memoryArray.resize(count);
- memoryPool.ToArray(&memoryArray[0]);
-
- std::sort(memoryArray.begin(), memoryArray.end());
-
- memoryPool.Clear(true);
-
- for (const T& item : memoryArray)
- memoryPool.Add(item);
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventDescription* EventDescription::Create(const char* eventName, const char* fileName, const unsigned long fileLine, const unsigned long eventColor /*= Color::Null*/, const unsigned long filter /*= 0*/)
-{
- return EventDescriptionBoard::Get().CreateDescription(eventName, fileName, fileLine, eventColor, filter);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventDescription* EventDescription::CreateShared(const char* eventName, const char* fileName, const unsigned long fileLine, const unsigned long eventColor /*= Color::Null*/, const unsigned long filter /*= 0*/)
-{
- return EventDescriptionBoard::Get().CreateSharedDescription(eventName, fileName, fileLine, eventColor, filter);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventDescription::EventDescription() : name(""), file(""), line(0), color(0)
-{
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventDescription& EventDescription::operator=(const EventDescription&)
-{
- OPTICK_FAILED("It is pointless to copy EventDescription. Please, check you logic!"); return *this;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventData* Event::Start(const EventDescription& description)
-{
- EventData* result = nullptr;
-
- if (EventStorage* storage = Core::storage)
- {
- result = &storage->NextEvent();
- result->description = &description;
- result->Start();
- }
- return result;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Event::Stop(EventData& data)
-{
- if (EventStorage* storage = Core::storage)
- {
- data.Stop();
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void OPTICK_INLINE PushEvent(EventStorage* pStorage, const EventDescription* description, int64_t timestampStart)
-{
- if (EventStorage* storage = pStorage)
- {
- EventData& result = storage->NextEvent();
- result.description = description;
- result.start = timestampStart;
- result.finish = EventTime::INVALID_TIMESTAMP;
- storage->pushPopEventStack[storage->pushPopEventStackIndex++] = &result;
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void OPTICK_INLINE PopEvent(EventStorage* pStorage, int64_t timestampFinish)
-{
- if (EventStorage* storage = pStorage)
- if (storage->pushPopEventStackIndex > 0)
- storage->pushPopEventStack[--storage->pushPopEventStackIndex]->finish = timestampFinish;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Event::Push(const char* name)
-{
- if (EventStorage* storage = Core::storage)
- {
- EventDescription* desc = EventDescription::CreateShared(name);
- Push(*desc);
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Event::Push(const EventDescription& description)
-{
- PushEvent(Core::storage, &description, GetHighPrecisionTime());
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Event::Pop()
-{
- PopEvent(Core::storage, GetHighPrecisionTime());
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Event::Add(EventStorage* storage, const EventDescription* description, int64_t timestampStart, int64_t timestampFinish)
-{
- EventData& data = storage->eventBuffer.Add();
- data.description = description;
- data.start = timestampStart;
- data.finish = timestampFinish;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Event::Push(EventStorage* storage, const EventDescription* description, int64_t timestampStart)
-{
- PushEvent(storage, description, timestampStart);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Event::Pop(EventStorage* storage, int64_t timestampFinish)
-{
- PopEvent(storage, timestampFinish);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventData* GPUEvent::Start(const EventDescription& description)
-{
- EventData* result = nullptr;
-
- if (EventStorage* storage = Core::storage)
- result = storage->gpuStorage.Start(description);
-
- return result;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void GPUEvent::Stop(EventData& data)
-{
- if (EventStorage* storage = Core::storage)
- storage->gpuStorage.Stop(data);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void FiberSyncData::AttachToThread(EventStorage* storage, uint64_t threadId)
-{
- if (storage)
- {
- FiberSyncData& data = storage->fiberSyncBuffer.Add();
- data.Start();
- data.finish = EventTime::INVALID_TIMESTAMP;
- data.threadId = threadId;
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void FiberSyncData::DetachFromThread(EventStorage* storage)
-{
- if (storage)
- {
- if (FiberSyncData* syncData = storage->fiberSyncBuffer.Back())
- {
- syncData->Stop();
- }
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Tag::Attach(const EventDescription& description, float val)
-{
- if (EventStorage* storage = Core::storage)
- if (storage->currentMode & Mode::TAGS)
- storage->tagFloatBuffer.Add(TagFloat(description, val));
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Tag::Attach(const EventDescription& description, int32_t val)
-{
- if (EventStorage* storage = Core::storage)
- if (storage->currentMode & Mode::TAGS)
- storage->tagS32Buffer.Add(TagS32(description, val));
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Tag::Attach(const EventDescription& description, uint32_t val)
-{
- if (EventStorage* storage = Core::storage)
- if (storage->currentMode & Mode::TAGS)
- storage->tagU32Buffer.Add(TagU32(description, val));
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Tag::Attach(const EventDescription& description, uint64_t val)
-{
- if (EventStorage* storage = Core::storage)
- if (storage->currentMode & Mode::TAGS)
- storage->tagU64Buffer.Add(TagU64(description, val));
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Tag::Attach(const EventDescription& description, float val[3])
-{
- if (EventStorage* storage = Core::storage)
- if (storage->currentMode & Mode::TAGS)
- storage->tagPointBuffer.Add(TagPoint(description, val));
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Tag::Attach(const EventDescription& description, const char* val)
-{
- if (EventStorage* storage = Core::storage)
- if (storage->currentMode & Mode::TAGS)
- storage->tagStringBuffer.Add(TagString(description, val));
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream & operator<<(OutputDataStream &stream, const EventDescription &ob)
-{
- byte flags = 0;
- return stream << ob.name << ob.file << ob.line << ob.filter << ob.color << (float)0.0f << flags;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const EventTime& ob)
-{
- return stream << ob.start << ob.finish;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const EventData& ob)
-{
- return stream << (EventTime)(ob) << (ob.description ? ob.description->index : (uint32)-1);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const SyncData& ob)
-{
- return stream << (EventTime)(ob) << ob.core << ob.reason << ob.newThreadId;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const FiberSyncData& ob)
-{
- return stream << (EventTime)(ob) << ob.threadId;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-static std::mutex& GetBoardLock()
-{
- // Initialize as static local variable to prevent problems with static initialization order
- static std::mutex lock;
- return lock;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventDescriptionBoard& EventDescriptionBoard::Get()
-{
- static EventDescriptionBoard instance;
- return instance;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-const EventDescriptionList& EventDescriptionBoard::GetEvents() const
-{
- return boardDescriptions;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventDescription* EventDescriptionBoard::CreateDescription(const char* name, const char* file /*= nullptr*/, uint32_t line /*= 0*/, uint32_t color /*= Color::Null*/, uint32_t filter /*= 0*/)
-{
- std::lock_guard<std::mutex> lock(GetBoardLock());
-
- size_t index = boardDescriptions.Size();
-
- EventDescription& desc = boardDescriptions.Add();
- desc.index = (uint32)index;
- desc.name = name;
- desc.file = file;
- desc.line = line;
- desc.color = color;
- desc.filter = filter;
-
- return &desc;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventDescription* EventDescriptionBoard::CreateSharedDescription(const char* name, const char* file /*= nullptr*/, uint32_t line /*= 0*/, uint32_t color /*= Color::Null*/, uint32_t filter /*= 0*/)
-{
- StringHash nameHash(name);
-
- std::lock_guard<std::mutex> lock(sharedLock);
-
- std::pair<DescriptionMap::iterator, bool> cached = sharedDescriptions.insert({ nameHash, nullptr });
-
- if (cached.second)
- {
- const char* nameCopy = sharedNames.Add(name, strlen(name) + 1, false);
- cached.first->second = CreateDescription(nameCopy, file, line, color, filter);
- }
-
- return cached.first->second;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator << (OutputDataStream& stream, const EventDescriptionBoard& ob)
-{
- std::lock_guard<std::mutex> lock(GetBoardLock());
- stream << ob.GetEvents();
- return stream;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-ProcessDescription::ProcessDescription(const char* processName, ProcessID pid, uint64 key) : name(processName), processID(pid), uniqueKey(key)
-{
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-ThreadDescription::ThreadDescription(const char* threadName, ThreadID tid, ProcessID pid, int32 _maxDepth /*= 1*/, int32 _priority /*= 0*/, uint32 _mask /*= 0*/)
- : name(threadName), threadID(tid), processID(pid), maxDepth(_maxDepth), priority(_priority), mask(_mask)
-{
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-int64_t GetHighPrecisionTime()
-{
- return Platform::GetTime();
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-int64_t GetHighPrecisionFrequency()
-{
- return Platform::GetFrequency();
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream & operator<<(OutputDataStream &stream, const SysCallData &ob)
-{
- return stream << (const EventData&)ob << ob.threadID << ob.id;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-SysCallData& SysCallCollector::Add()
-{
- return syscallPool.Add();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void SysCallCollector::Clear()
-{
- syscallPool.Clear(false);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool SysCallCollector::Serialize(OutputDataStream& stream)
-{
- stream << syscallPool;
-
- if (!syscallPool.IsEmpty())
- {
- syscallPool.Clear(false);
- return true;
- }
-
- return false;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void CallstackCollector::Add(const CallstackDesc& desc)
-{
- if (uint64* storage = callstacksPool.TryAdd(desc.count + 3))
- {
- storage[0] = desc.threadID;
- storage[1] = desc.timestamp;
- storage[2] = desc.count;
-
- for (uint64 i = 0; i < desc.count; ++i)
- {
- storage[3 + i] = desc.callstack[desc.count - i - 1];
- }
- }
- else
- {
- uint64& item0 = callstacksPool.Add();
- uint64& item1 = callstacksPool.Add();
- uint64& item2 = callstacksPool.Add();
-
- item0 = desc.threadID;
- item1 = desc.timestamp;
- item2 = desc.count;
-
- for (uint64 i = 0; i < desc.count; ++i)
- {
- callstacksPool.Add() = desc.callstack[desc.count - i - 1];
- }
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void CallstackCollector::Clear()
-{
- callstacksPool.Clear(false);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool CallstackCollector::SerializeModules(OutputDataStream& stream)
-{
- if (SymbolEngine* symEngine = Core::Get().symbolEngine)
- {
- stream << symEngine->GetModules();
- return true;
- }
- else
- {
- stream << (int)0;
- }
- return false;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool CallstackCollector::SerializeSymbols(OutputDataStream& stream)
-{
- typedef unordered_set<uint64> SymbolSet;
- SymbolSet symbolSet;
-
- for (CallstacksPool::const_iterator it = callstacksPool.begin(); it != callstacksPool.end();)
- {
- CallstacksPool::const_iterator startIt = it;
- OPTICK_UNUSED(startIt);
-
- uint64 threadID = *it;
- OPTICK_UNUSED(threadID);
- ++it; //Skip ThreadID
- uint64 timestamp = *it;
- OPTICK_UNUSED
- (timestamp);
- ++it; //Skip Timestamp
- uint64 count = *it;
- count = (count & 0xFF);
- ++it; //Skip Count
-
- bool isBadAddrFound = false;
-
- for (uint64 i = 0; i < count; ++i)
- {
- uint64 address = *it;
- ++it;
-
- if (address == 0)
- {
- isBadAddrFound = true;
- }
-
- if (!isBadAddrFound)
- {
- symbolSet.insert(address);
- }
- }
- }
-
- SymbolEngine* symEngine = Core::Get().symbolEngine;
-
- vector<const Symbol*> symbols;
- symbols.reserve(symbolSet.size());
-
- size_t callstackIndex = 0;
-
- Core::Get().DumpProgress("Resolving addresses... ");
-
- if (symEngine)
- {
- for (auto it = symbolSet.begin(); it != symbolSet.end(); ++it)
- {
- callstackIndex++;
-
- uint64 address = *it;
- if (const Symbol* symbol = symEngine->GetSymbol(address))
- {
- symbols.push_back(symbol);
- }
- }
- }
-
- stream << symbols;
- return true;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool CallstackCollector::SerializeCallstacks(OutputDataStream& stream)
-{
- stream << callstacksPool;
-
- if (!callstacksPool.IsEmpty())
- {
- callstacksPool.Clear(false);
- return true;
- }
-
- return false;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool CallstackCollector::IsEmpty() const
-{
- return callstacksPool.IsEmpty();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream & operator<<(OutputDataStream &stream, const SwitchContextDesc &ob)
-{
- return stream << ob.timestamp << ob.oldThreadId << ob.newThreadId << ob.cpuId << ob.reason;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void SwitchContextCollector::Add(const SwitchContextDesc& desc)
-{
- switchContextPool.Add() = desc;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void SwitchContextCollector::Clear()
-{
- switchContextPool.Clear(false);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool SwitchContextCollector::Serialize(OutputDataStream& stream)
-{
- stream << switchContextPool;
-
- if (!switchContextPool.IsEmpty())
- {
- switchContextPool.Clear(false);
- return true;
- }
-
- return false;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-#if defined(OPTICK_MSVC)
-#define CPUID(INFO, ID) __cpuid(INFO, ID)
-#include <intrin.h>
-#elif defined(OPTICK_GCC)
-#include <cpuid.h>
-#define CPUID(INFO, ID) __cpuid(ID, INFO[0], INFO[1], INFO[2], INFO[3])
-#else
-#error Platform is not supported!
-#endif
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-string GetCPUName()
-{
- int cpuInfo[4] = { -1 };
- char cpuBrandString[0x40] = { 0 };
- CPUID(cpuInfo, 0x80000000);
- unsigned nExIds = cpuInfo[0];
- for (unsigned i = 0x80000000; i <= nExIds; ++i)
- {
- CPUID(cpuInfo, i);
- if (i == 0x80000002)
- memcpy(cpuBrandString, cpuInfo, sizeof(cpuInfo));
- else if (i == 0x80000003)
- memcpy(cpuBrandString + 16, cpuInfo, sizeof(cpuInfo));
- else if (i == 0x80000004)
- memcpy(cpuBrandString + 32, cpuInfo, sizeof(cpuInfo));
- }
- return string(cpuBrandString);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-Core& Core::Get()
-{
- static Core instance;
- return instance;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::StartCapture()
-{
- pendingState = State::START_CAPTURE;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::StopCapture()
-{
- pendingState = State::STOP_CAPTURE;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::CancelCapture()
-{
- pendingState = State::CANCEL_CAPTURE;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::DumpCapture()
-{
- pendingState = State::DUMP_CAPTURE;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::DumpProgress(const char* message)
-{
- progressReportedLastTimestampMS = GetTimeMilliSeconds();
-
- OutputDataStream stream;
- stream << message;
-
- Server::Get().Send(DataResponse::ReportProgress, stream);
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::DumpEvents(EventStorage& entry, const EventTime& timeSlice, ScopeData& scope)
-{
- if (!entry.eventBuffer.IsEmpty())
- {
- const EventData* rootEvent = nullptr;
-
- entry.eventBuffer.ForEach([&](const EventData& data)
- {
- if (data.finish >= data.start && data.start >= timeSlice.start && timeSlice.finish >= data.finish)
- {
- if (!rootEvent)
- {
- rootEvent = &data;
- scope.InitRootEvent(*rootEvent);
- }
- else if (rootEvent->finish < data.finish)
- {
- scope.Send();
-
- rootEvent = &data;
- scope.InitRootEvent(*rootEvent);
- }
- else
- {
- scope.AddEvent(data);
- }
- }
- });
-
- scope.Send();
-
- entry.eventBuffer.Clear(false);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::DumpTags(EventStorage& entry, ScopeData& scope)
-{
- if (!entry.tagFloatBuffer.IsEmpty() ||
- !entry.tagS32Buffer.IsEmpty() ||
- !entry.tagU32Buffer.IsEmpty() ||
- !entry.tagU64Buffer.IsEmpty() ||
- !entry.tagPointBuffer.IsEmpty() ||
- !entry.tagStringBuffer.IsEmpty())
- {
- OutputDataStream tagStream;
- tagStream << scope.header.boardNumber << scope.header.threadNumber;
- tagStream
- << (uint32)0
- << entry.tagFloatBuffer
- << entry.tagU32Buffer
- << entry.tagS32Buffer
- << entry.tagU64Buffer
- << entry.tagPointBuffer
- << (uint32)0
- << (uint32)0
- << entry.tagStringBuffer;
- Server::Get().Send(DataResponse::TagsPack, tagStream);
-
- entry.ClearTags(false);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::DumpThread(ThreadEntry& entry, const EventTime& timeSlice, ScopeData& scope)
-{
- // We need to sort events for all the custom thread storages
- if (entry.description.threadID == INVALID_THREAD_ID)
- entry.Sort();
-
- // Events
- DumpEvents(entry.storage, timeSlice, scope);
- DumpTags(entry.storage, scope);
- OPTICK_ASSERT(entry.storage.fiberSyncBuffer.IsEmpty(), "Fiber switch events in native threads?");
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::DumpFiber(FiberEntry& entry, const EventTime& timeSlice, ScopeData& scope)
-{
- // Events
- DumpEvents(entry.storage, timeSlice, scope);
-
- if (!entry.storage.fiberSyncBuffer.IsEmpty())
- {
- OutputDataStream fiberSynchronizationStream;
- fiberSynchronizationStream << scope.header.boardNumber;
- fiberSynchronizationStream << scope.header.fiberNumber;
- fiberSynchronizationStream << entry.storage.fiberSyncBuffer;
- Server::Get().Send(DataResponse::FiberSynchronizationData, fiberSynchronizationStream);
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventTime CalculateRange(const ThreadEntry& entry, const EventDescription* rootDescription)
-{
- EventTime timeSlice = { INT64_MAX, INT64_MIN };
- entry.storage.eventBuffer.ForEach([&](const EventData& data)
- {
- if (data.description == rootDescription)
- {
- timeSlice.start = std::min(timeSlice.start, data.start);
- timeSlice.finish = std::max(timeSlice.finish, data.finish);
- }
- });
- return timeSlice;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::DumpFrames(uint32 mode)
-{
- std::lock_guard<std::recursive_mutex> lock(threadsLock);
-
- if (frames.empty() || threads.empty())
- return;
-
- ++boardNumber;
-
- DumpProgress("Generating summary...");
-
- GenerateCommonSummary();
- DumpSummary();
-
- DumpProgress("Collecting Frame Events...");
-
-
- ThreadID mainThreadID = Platform::GetThreadID();
- uint32 mainThreadIndex = 0;
- for (size_t i = 0; i < threads.size(); ++i)
- if (threads[i]->description.threadID == mainThreadID)
- mainThreadIndex = (uint32)i;
-
- EventTime timeSlice = CalculateRange(*threads[mainThreadIndex], GetFrameDescription(FrameType::CPU));
- if (timeSlice.start >= timeSlice.finish)
- {
- timeSlice.start = frames.front().start;
- timeSlice.finish = frames.back().finish;
- }
-
- DumpBoard(mode, timeSlice, mainThreadIndex);
-
- ScopeData threadScope;
- threadScope.header.boardNumber = boardNumber;
- threadScope.header.fiberNumber = -1;
-
- if (gpuProfiler)
- gpuProfiler->Dump(mode);
-
- for (size_t i = 0; i < threads.size(); ++i)
- {
- threadScope.header.threadNumber = (uint32)i;
- DumpThread(*threads[i], timeSlice, threadScope);
- }
-
- ScopeData fiberScope;
- fiberScope.header.boardNumber = (uint32)boardNumber;
- fiberScope.header.threadNumber = -1;
- for (size_t i = 0; i < fibers.size(); ++i)
- {
- fiberScope.header.fiberNumber = (uint32)i;
- DumpFiber(*fibers[i], timeSlice, fiberScope);
- }
-
- frames.clear();
- CleanupThreadsAndFibers();
-
- {
- DumpProgress("Serializing SwitchContexts");
- OutputDataStream switchContextsStream;
- switchContextsStream << boardNumber;
- switchContextCollector.Serialize(switchContextsStream);
- Server::Get().Send(DataResponse::SynchronizationData, switchContextsStream);
- }
-
- {
- DumpProgress("Serializing SysCalls");
- OutputDataStream callstacksStream;
- callstacksStream << boardNumber;
- syscallCollector.Serialize(callstacksStream);
- Server::Get().Send(DataResponse::SyscallPack, callstacksStream);
- }
-
- if (!callstackCollector.IsEmpty())
- {
- DumpProgress("Resolving callstacks");
- OutputDataStream symbolsStream;
- symbolsStream << boardNumber;
- callstackCollector.SerializeModules(symbolsStream);
- callstackCollector.SerializeSymbols(symbolsStream);
- Server::Get().Send(DataResponse::CallstackDescriptionBoard, symbolsStream);
-
- DumpProgress("Serializing callstacks");
- OutputDataStream callstacksStream;
- callstacksStream << boardNumber;
- callstackCollector.SerializeCallstacks(callstacksStream);
- Server::Get().Send(DataResponse::CallstackPack, callstacksStream);
- }
-
- Server::Get().Send(DataResponse::NullFrame, OutputDataStream::Empty);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::DumpSummary()
-{
- OutputDataStream stream;
-
- // Board Number
- stream << boardNumber;
-
- // Frames
- double frequency = (double)Platform::GetFrequency();
- stream << (uint32_t)frames.size();
- for (const EventTime& frame : frames)
- {
- double frameTimeMs = 1000.0 * (frame.finish - frame.start) / frequency;
- stream << (float)frameTimeMs;
- }
-
- // Summary
- stream << (uint32_t)summary.size();
- for (size_t i = 0; i < summary.size(); ++i)
- stream << summary[i].first << summary[i].second;
- summary.clear();
-
- // Attachments
- stream << (uint32_t)attachments.size();
- for (const Attachment& att : attachments)
- stream << (uint32_t)att.type << att.name << att.data;
- attachments.clear();
-
- // Send
- Server::Get().Send(DataResponse::SummaryPack, stream);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::CleanupThreadsAndFibers()
-{
- std::lock_guard<std::recursive_mutex> lock(threadsLock);
-
- for (ThreadList::iterator it = threads.begin(); it != threads.end();)
- {
- if (!(*it)->isAlive)
- {
- Memory::Delete(*it);
- it = threads.erase(it);
- }
- else
- {
- ++it;
- }
- }
-}
-
-void Core::DumpBoard(uint32 mode, EventTime timeSlice, uint32 mainThreadIndex)
-{
- OutputDataStream boardStream;
-
- boardStream << boardNumber;
- boardStream << Platform::GetFrequency();
- boardStream << (uint64)0; // Origin
- boardStream << (uint32)0; // Precision
- boardStream << timeSlice;
- boardStream << threads;
- boardStream << fibers;
- boardStream << mainThreadIndex;
- boardStream << EventDescriptionBoard::Get();
- boardStream << (uint32)0; // Tags
- boardStream << (uint32)0; // Run
- boardStream << (uint32)0; // Filters
- boardStream << (uint32)0; // ThreadDescs
- boardStream << mode; // Mode
- boardStream << processDescs;
- boardStream << threadDescs;
- boardStream << (uint32)Platform::GetProcessID();
- boardStream << (uint32)std::thread::hardware_concurrency();
- Server::Get().Send(DataResponse::FrameDescriptionBoard, boardStream);
-
- // Cleanup
- processDescs.clear();
- threadDescs.clear();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::GenerateCommonSummary()
-{
- AttachSummary("Platform", Platform::GetName());
- AttachSummary("CPU", GetCPUName().c_str());
- if (gpuProfiler)
- AttachSummary("GPU", gpuProfiler->GetName().c_str());
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-Core::Core()
- : progressReportedLastTimestampMS(0)
- , boardNumber(0)
- , frameNumber(0)
- , stateCallback(nullptr)
- , currentState(State::DUMP_CAPTURE)
- , pendingState(State::DUMP_CAPTURE)
- , currentMode(Mode::OFF)
- , symbolEngine(nullptr)
- , tracer(nullptr)
- , gpuProfiler(nullptr)
-{
-#if OPTICK_ENABLE_TRACING
- tracer = Platform::GetTrace();
- symbolEngine = Platform::GetSymbolEngine();
-#endif
-
- frameDescriptions[FrameType::CPU] = EventDescription::Create("CPU Frame", __FILE__, __LINE__);
- frameDescriptions[FrameType::GPU] = EventDescription::Create("GPU Frame", __FILE__, __LINE__);
- frameDescriptions[FrameType::Render] = EventDescription::Create("Render Frame", __FILE__, __LINE__);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::UpdateState()
-{
- if (currentState != pendingState)
- {
- State::Type nextState = pendingState;
- if (pendingState == State::DUMP_CAPTURE && currentState == State::START_CAPTURE)
- nextState = State::STOP_CAPTURE;
-
- if ((stateCallback != nullptr) && !stateCallback(nextState))
- return false;
-
- switch (nextState)
- {
- case State::START_CAPTURE:
- Activate((Mode::Type)settings.mode);
- break;
-
- case State::STOP_CAPTURE:
- case State::CANCEL_CAPTURE:
- Activate(Mode::OFF);
- break;
-
- case State::DUMP_CAPTURE:
- DumpFrames();
- break;
- }
- currentState = nextState;
- return true;
- }
- return false;
-}
-
-
-uint32_t Core::Update()
-{
- std::lock_guard<std::recursive_mutex> lock(coreLock);
-
- if (currentMode != Mode::OFF)
- {
- if (!frames.empty())
- frames.back().Stop();
-
- if (settings.frameLimit > 0 && frames.size() >= settings.frameLimit)
- DumpCapture();
-
- if (settings.timeLimitUs > 0)
- {
- if (TicksToUs(frames.back().finish - frames.front().start) >= settings.timeLimitUs)
- DumpCapture();
- }
-
- if (settings.spikeLimitUs > 0)
- {
- if (TicksToUs(frames.back().finish - frames.back().start) >= settings.spikeLimitUs)
- DumpCapture();
- }
-
- if (IsTimeToReportProgress())
- DumpCapturingProgress();
- }
-
- UpdateEvents();
-
- while (UpdateState()) {}
-
- if (currentMode != Mode::OFF)
- {
- frames.push_back(EventTime());
- frames.back().Start();
- }
-
- return ++frameNumber;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::UpdateEvents()
-{
- Server::Get().Update();
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::ReportSwitchContext(const SwitchContextDesc& desc)
-{
- switchContextCollector.Add(desc);
- return true;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::ReportStackWalk(const CallstackDesc& desc)
-{
- callstackCollector.Add(desc);
- return true;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::Activate(Mode::Type mode)
-{
- if (mode != currentMode)
- {
- Mode::Type prevMode = currentMode;
- currentMode = mode;
-
- {
- std::lock_guard<std::recursive_mutex> lock(threadsLock);
- for(auto it = threads.begin(); it != threads.end(); ++it)
- {
- ThreadEntry* entry = *it;
- entry->Activate(mode);
- }
- }
-
-
- if (mode != Mode::OFF)
- {
- CaptureStatus::Type status = CaptureStatus::ERR_TRACER_FAILED;
-
- if (tracer && (mode & Mode::TRACER))
- {
- std::lock_guard<std::recursive_mutex> lock(threadsLock);
- tracer->SetPassword(settings.password.c_str());
- status = tracer->Start(mode, settings.samplingFrequency, threads);
- // Let's retry with more narrow setup
- if (status != CaptureStatus::OK && (mode & Mode::AUTOSAMPLING))
- status = tracer->Start((Mode::Type)(mode & ~Mode::AUTOSAMPLING), settings.samplingFrequency, threads);
- }
-
- if (gpuProfiler && (mode & Mode::GPU))
- gpuProfiler->Start(mode);
-
- SendHandshakeResponse(status);
- }
- else
- {
- if (tracer)
- tracer->Stop();
-
- if (gpuProfiler)
- gpuProfiler->Stop(prevMode);
- }
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::DumpCapturingProgress()
-{
- stringstream stream;
-
- if (currentMode != Mode::OFF)
- {
- size_t memUsedKb = Memory::GetAllocatedSize() >> 10;
- float memUsedMb = memUsedKb / 1024.0f;
- // VS TODO: Format to 3 digits
- stream << "Capturing Frame " << (uint32)frames.size() << "..." << std::endl << "Memory Used: " << memUsedMb << " Mb";
- }
-
- DumpProgress(stream.str().c_str());
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::IsTimeToReportProgress() const
-{
- return GetTimeMilliSeconds() > progressReportedLastTimestampMS + 200;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::SendHandshakeResponse(CaptureStatus::Type status)
-{
- OutputDataStream stream;
- stream << (uint32)status;
- stream << Platform::GetName();
- stream << Server::Get().GetHostName();
- Server::Get().Send(DataResponse::Handshake, stream);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::IsRegistredThread(ThreadID id)
-{
- std::lock_guard<std::recursive_mutex> lock(threadsLock);
-
- for (ThreadList::iterator it = threads.begin(); it != threads.end(); ++it)
- {
- ThreadEntry* entry = *it;
- if (entry->description.threadID == id)
- {
- return true;
- }
- }
- return false;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-ThreadEntry* Core::RegisterThread(const ThreadDescription& description, EventStorage** slot)
-{
- std::lock_guard<std::recursive_mutex> lock(threadsLock);
-
- ThreadEntry* entry = Memory::New<ThreadEntry>(description, slot);
- threads.push_back(entry);
-
- if ((currentMode != Mode::OFF) && slot != nullptr)
- *slot = &entry->storage;
-
- return entry;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::UnRegisterThread(ThreadID threadID, bool keepAlive)
-{
- std::lock_guard<std::recursive_mutex> lock(threadsLock);
-
- for (ThreadList::iterator it = threads.begin(); it != threads.end(); ++it)
- {
- ThreadEntry* entry = *it;
- if (entry->description.threadID == threadID && entry->isAlive)
- {
- if ((currentMode == Mode::OFF) && !keepAlive)
- {
- Memory::Delete(entry);
- threads.erase(it);
- return true;
- }
- else
- {
- entry->isAlive = false;
- return true;
- }
- }
- }
-
- return false;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::RegisterFiber(const FiberDescription& description, EventStorage** slot)
-{
- std::lock_guard<std::recursive_mutex> lock(coreLock);
- FiberEntry* entry = Memory::New<FiberEntry>(description);
- fibers.push_back(entry);
- entry->storage.isFiberStorage = true;
- *slot = &entry->storage;
- return true;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::RegisterProcessDescription(const ProcessDescription& description)
-{
- processDescs.push_back(description);
- return false;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::RegisterThreadDescription(const ThreadDescription& description)
-{
- threadDescs.push_back(description);
- return false;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::SetStateChangedCallback(StateCallback cb)
-{
- stateCallback = cb;
- return stateCallback != nullptr;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::AttachSummary(const char* key, const char* value)
-{
- summary.push_back(make_pair(string(key), string(value)));
- return true;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::AttachFile(File::Type type, const char* name, const uint8_t* data, uint32_t size)
-{
- if (size > 0)
- {
- attachments.push_back(Attachment(type, name));
- Attachment& attachment = attachments.back();
- attachment.data.resize(size);
- memcpy(&attachment.data[0], data, size);
- return true;
- }
- return false;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::AttachFile(File::Type type, const char* name, std::istream& stream)
-{
- std::streampos beg = stream.tellg();
- stream.seekg(0, std::ios::end);
- std::streampos end = stream.tellg();
- stream.seekg(beg, std::ios::beg);
-
- size_t size =(size_t)(end - beg);
- void* buffer = Memory::Alloc(size);
-
- stream.read((char*)buffer, size);
- bool result = AttachFile(type, name, (uint8*)buffer, (uint32_t)size);
-
- Memory::Free(buffer);
- return result;
-
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::AttachFile(File::Type type, const char* name, const char* path)
-{
- std::ifstream stream(path, std::ios::binary);
- return AttachFile(type, name, stream);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::AttachFile(File::Type type, const char* name, const wchar_t* path)
-{
-#if defined(OPTICK_MSVC)
- std::ifstream stream(path, std::ios::binary);
- return AttachFile(type, name, stream);
-#else
- char p[256] = { 0 };
- wcstombs(p, path, sizeof(p));
- std::ifstream stream(p, std::ios::binary);
- return AttachFile(type, name, stream);
-#endif
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Core::InitGPUProfiler(GPUProfiler* profiler)
-{
- OPTICK_ASSERT(gpuProfiler == nullptr, "Can't reinitialize GPU profiler! Not supported yet!");
- Memory::Delete<GPUProfiler>(gpuProfiler);
- gpuProfiler = profiler;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Core::SetSettings(const CaptureSettings& captureSettings)
-{
- settings = captureSettings;
-
- //if (tracer)
- //{
- // string decoded = base64_decode(encodedPassword);
- // tracer->SetPassword(decoded.c_str());
- // return true;
- //}
- return false;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-const EventDescription* Core::GetFrameDescription(FrameType::Type frame) const
-{
- return frameDescriptions[frame];
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-Core::~Core()
-{
- std::lock_guard<std::recursive_mutex> lock(threadsLock);
-
- for (ThreadList::iterator it = threads.begin(); it != threads.end(); ++it)
- {
- Memory::Delete(*it);
- }
- threads.clear();
-
- for (FiberList::iterator it = fibers.begin(); it != fibers.end(); ++it)
- {
- Memory::Delete(*it);
- }
- fibers.clear();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-const vector<ThreadEntry*>& Core::GetThreads() const
-{
- return threads;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_THREAD_LOCAL EventStorage* Core::storage = nullptr;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-ScopeHeader::ScopeHeader() : boardNumber(0), threadNumber(0)
-{
-
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const ScopeHeader& header)
-{
- return stream << header.boardNumber << header.threadNumber << header.fiberNumber << header.event;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const ScopeData& ob)
-{
- return stream << ob.header << ob.categories << ob.events;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const ThreadDescription& description)
-{
- return stream << description.threadID << description.processID << description.name << description.maxDepth << description.priority << description.mask;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const ThreadEntry* entry)
-{
- return stream << entry->description;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const FiberDescription& description)
-{
- return stream << description.id;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const FiberEntry* entry)
-{
- return stream << entry->description;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const ProcessDescription& description)
-{
- return stream << description.processID << description.name << description.uniqueKey;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool SetStateChangedCallback(StateCallback cb)
-{
- return Core::Get().SetStateChangedCallback(cb);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool AttachSummary(const char* key, const char* value)
-{
- return Core::Get().AttachSummary(key, value);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool AttachFile(File::Type type, const char* name, const uint8_t* data, uint32_t size)
-{
- return Core::Get().AttachFile(type, name, data, size);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool AttachFile(File::Type type, const char* name, const char* path)
-{
- return Core::Get().AttachFile(type, name, path);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool AttachFile(File::Type type, const char* name, const wchar_t* path)
-{
- return Core::Get().AttachFile(type, name, path);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& stream, const Point& ob)
-{
- return stream << ob.x << ob.y << ob.z;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API uint32_t NextFrame()
-{
- return Core::NextFrame();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool IsActive(Mode::Type mode /*= Mode::INSTRUMENTATION_EVENTS*/)
-{
- return (Core::Get().currentMode & mode) != 0;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API EventStorage** GetEventStorageSlotForCurrentThread()
-{
- return &Core::Get().storage;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool IsFiberStorage(EventStorage* fiberStorage)
-{
- return fiberStorage->isFiberStorage;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool RegisterThread(const char* name)
-{
- return Core::Get().RegisterThread(ThreadDescription(name, Platform::GetThreadID(), Platform::GetProcessID()), &Core::storage) != nullptr;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool RegisterThread(const wchar_t* name)
-{
- const int THREAD_NAME_LENGTH = 128;
- char mbName[THREAD_NAME_LENGTH];
- wcstombs_s(mbName, name, THREAD_NAME_LENGTH);
-
- return Core::Get().RegisterThread(ThreadDescription(mbName, Platform::GetThreadID(), Platform::GetProcessID()), &Core::storage) != nullptr;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool UnRegisterThread(bool keepAlive)
-{
- return Core::Get().UnRegisterThread(Platform::GetThreadID(), keepAlive);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API bool RegisterFiber(uint64 fiberId, EventStorage** slot)
-{
- return Core::Get().RegisterFiber(FiberDescription(fiberId), slot);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API EventStorage* RegisterStorage(const char* name, uint64_t threadID, ThreadMask::Type type)
-{
- ThreadEntry* entry = Core::Get().RegisterThread(ThreadDescription(name, threadID, Platform::GetProcessID(), 1, 0, type), nullptr);
- return entry ? &entry->storage : nullptr;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API void GpuFlip(void* swapChain)
-{
- if (GPUProfiler* gpuProfiler = Core::Get().gpuProfiler)
- gpuProfiler->Flip(swapChain);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API GPUContext SetGpuContext(GPUContext context)
-{
- if (EventStorage* storage = Core::storage)
- {
- GPUContext prevContext = storage->gpuStorage.context;
- storage->gpuStorage.context = context;
- return prevContext;
- }
- return GPUContext();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OPTICK_API const EventDescription* GetFrameDescription(FrameType::Type frame)
-{
- return Core::Get().GetFrameDescription(frame);
-
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventStorage::EventStorage(): currentMode(Mode::OFF), pushPopEventStackIndex(0), isFiberStorage(false)
-{
-
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void ThreadEntry::Activate(Mode::Type mode)
-{
- if (!isAlive)
- return;
-
- if (mode != Mode::OFF)
- storage.Clear(true);
-
- if (threadTLS != nullptr)
- {
- storage.currentMode = mode;
- *threadTLS = mode != Mode::OFF ? &storage : nullptr;
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void ThreadEntry::Sort()
-{
- SortMemoryPool(storage.eventBuffer);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool IsSleepOnlyScope(const ScopeData& scope)
-{
- //if (!scope.categories.empty())
- // return false;
-
- const vector<EventData>& events = scope.events;
- for(auto it = events.begin(); it != events.end(); ++it)
- {
- const EventData& data = *it;
-
- if (data.description->color != Color::White)
- {
- return false;
- }
- }
-
- return true;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void ScopeData::Send()
-{
- if (!events.empty() || !categories.empty())
- {
- if (!IsSleepOnlyScope(*this))
- {
- OutputDataStream frameStream;
- frameStream << *this;
- Server::Get().Send(DataResponse::EventFrame, frameStream);
- }
- }
-
- Clear();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void ScopeData::Clear()
-{
- events.clear();
- categories.clear();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void EventStorage::GPUStorage::Clear(bool preserveMemory)
-{
- for (size_t i = 0; i < gpuBuffer.size(); ++i)
- for (int j = 0; j < GPU_QUEUE_COUNT; ++j)
- gpuBuffer[i][j].Clear(preserveMemory);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-EventData* EventStorage::GPUStorage::Start(const EventDescription &desc)
-{
- if (GPUProfiler* gpuProfiler = Core::Get().gpuProfiler)
- {
- EventData& result = gpuBuffer[context.node][context.queue].Add();
- result.description = &desc;
- result.start = EventTime::INVALID_TIMESTAMP;
- result.finish = EventTime::INVALID_TIMESTAMP;
- gpuProfiler->QueryTimestamp(context.cmdBuffer, &result.start);
- return &result;
- }
- return nullptr;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void EventStorage::GPUStorage::Stop(EventData& data)
-{
- if (GPUProfiler* gpuProfiler = Core::Get().gpuProfiler)
- {
- gpuProfiler->QueryTimestamp(context.cmdBuffer, &data.finish);
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-}
-
-#endif //USE_OPTICK \ No newline at end of file
diff --git a/external/optick/optick_core.h b/external/optick/optick_core.h
deleted file mode 100644
index 9ddf46b..0000000
--- a/external/optick/optick_core.h
+++ /dev/null
@@ -1,568 +0,0 @@
-#pragma once
-#include "optick.config.h"
-
-#if USE_OPTICK
-
-#include <mutex>
-#include <thread>
-
-#include "optick_common.h"
-
-#include "optick_memory.h"
-#include "optick_message.h"
-#include "optick_serialization.h"
-
-#include "optick_gpu.h"
-
-#include <atomic>
-
-// We expect to have 1k unique strings going through Optick at once
-// The chances to hit a collision are 1 in 10 trillion (odds of a meteor landing on your house)
-// We should be quite safe here :)
-// https://preshing.com/20110504/hash-collision-probabilities/
-// Feel free to add a seed and wait for another strike if armageddon starts
-namespace Optick
-{
- struct StringHash
- {
- uint64 hash;
-
- StringHash(size_t h) : hash(h) {}
- StringHash(const char* str) : hash(CalcHash(str)) {}
-
- bool operator==(const StringHash& other) const { return hash == other.hash; }
- bool operator<(const StringHash& other) const { return hash < other.hash; }
-
- static uint64 CalcHash(const char* str);
- };
-}
-
-// Overriding default hash function to return hash value directly
-namespace std
-{
- template<>
- struct hash<Optick::StringHash>
- {
- size_t operator()(const Optick::StringHash& x) const
- {
- return (size_t)x.hash;
- }
- };
-}
-
-namespace Optick
-{
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct Trace;
-struct SymbolEngine;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct ScopeHeader
-{
- EventTime event;
- uint32 boardNumber;
- int32 threadNumber;
- int32 fiberNumber;
-
- ScopeHeader();
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator << ( OutputDataStream& stream, const ScopeHeader& ob);
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct ScopeData
-{
- ScopeHeader header;
- vector<EventData> categories;
- vector<EventData> events;
-
- void AddEvent(const EventData& data)
- {
- events.push_back(data);
- if (data.description->color != Color::Null)
- {
- categories.push_back(data);
- }
- }
-
- void InitRootEvent(const EventData& data)
- {
- header.event = data;
- AddEvent(data);
- }
-
- void Send();
- void Clear();
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-#if defined(OPTICK_MSVC)
-#pragma warning( push )
-#pragma warning( disable : 4996 )
-#endif //OPTICK_MSVC
-template<int N>
-struct OptickString
-{
- char data[N];
- OptickString() {}
- OptickString<N>& operator=(const char* text) { strncpy(data, text ? text : "null", N - 1); data[N - 1] = 0; return *this; }
- OptickString(const char* text) { *this = text; }
-};
-#if defined(OPTICK_MSVC)
-#pragma warning( pop )
-#endif
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct Point
-{
- float x, y, z;
- Point() {}
- Point(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}
- Point(float pos[3]) : x(pos[0]), y(pos[1]), z(pos[2]) {}
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-template<int N>
-OutputDataStream& operator<<(OutputDataStream &stream, const OptickString<N>& ob)
-{
- size_t length = strnlen(ob.data, N);
- stream << (uint32)length;
- return stream.Write(ob.data, length);
-}
-OutputDataStream& operator<<(OutputDataStream& stream, const Point& ob);
-OutputDataStream& operator<<(OutputDataStream& stream, const ScopeData& ob);
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-typedef MemoryPool<EventData, 1024> EventBuffer;
-typedef MemoryPool<const EventData*, 32> CategoryBuffer;
-typedef MemoryPool<SyncData, 1024> SynchronizationBuffer;
-typedef MemoryPool<FiberSyncData, 1024> FiberSyncBuffer;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-typedef OptickString<32> ShortString;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-typedef TagData<float> TagFloat;
-typedef TagData<int32> TagS32;
-typedef TagData<uint32> TagU32;
-typedef TagData<uint64> TagU64;
-typedef TagData<Point> TagPoint;
-typedef TagData<ShortString> TagString;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-typedef MemoryPool<TagFloat, 1024> TagFloatBuffer;
-typedef MemoryPool<TagS32, 1024> TagS32Buffer;
-typedef MemoryPool<TagU32, 1024> TagU32Buffer;
-typedef MemoryPool<TagU64, 1024> TagU64Buffer;
-typedef MemoryPool<TagPoint, 64> TagPointBuffer;
-typedef MemoryPool<TagString, 1024> TagStringBuffer;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Base64
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-string base64_decode(string const& encoded_string);
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Board
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-typedef MemoryPool<EventDescription, 4096> EventDescriptionList;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-class EventDescriptionBoard
-{
- // List of stored Event Descriptions
- EventDescriptionList boardDescriptions;
-
- // Shared Descriptions
- typedef unordered_map<StringHash, EventDescription*> DescriptionMap;
- DescriptionMap sharedDescriptions;
- MemoryBuffer<64 * 1024> sharedNames;
- std::mutex sharedLock;
-
-public:
- EventDescription* CreateDescription(const char* name, const char* file = nullptr, uint32_t line = 0, uint32_t color = Color::Null, uint32_t filter = 0);
- EventDescription* CreateSharedDescription(const char* name, const char* file = nullptr, uint32_t line = 0, uint32_t color = Color::Null, uint32_t filter = 0);
-
- static EventDescriptionBoard& Get();
-
- const EventDescriptionList& GetEvents() const;
-
- friend OutputDataStream& operator << (OutputDataStream& stream, const EventDescriptionBoard& ob);
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct EventStorage
-{
- Mode::Type currentMode;
- EventBuffer eventBuffer;
- FiberSyncBuffer fiberSyncBuffer;
-
- TagFloatBuffer tagFloatBuffer;
- TagS32Buffer tagS32Buffer;
- TagU32Buffer tagU32Buffer;
- TagU64Buffer tagU64Buffer;
- TagPointBuffer tagPointBuffer;
- TagStringBuffer tagStringBuffer;
-
- struct GPUStorage
- {
- static const int MAX_GPU_NODES = 2;
- array<array<EventBuffer, GPU_QUEUE_COUNT>, MAX_GPU_NODES> gpuBuffer;
- GPUContext context;
-
- void Clear(bool preserveMemory);
-
- EventData* Start(const EventDescription& desc);
- void Stop(EventData& data);
- };
- GPUStorage gpuStorage;
-
- uint32 pushPopEventStackIndex;
- array<EventData*, 32> pushPopEventStack;
-
- bool isFiberStorage;
-
- EventStorage();
-
- OPTICK_INLINE EventData& NextEvent()
- {
- return eventBuffer.Add();
- }
-
- // Free all temporary memory
- void Clear(bool preserveContent)
- {
- currentMode = Mode::OFF;
- eventBuffer.Clear(preserveContent);
- fiberSyncBuffer.Clear(preserveContent);
- gpuStorage.Clear(preserveContent);
- ClearTags(preserveContent);
-
- while (pushPopEventStackIndex)
- {
- pushPopEventStack[--pushPopEventStackIndex] = nullptr;
- }
- }
-
- void ClearTags(bool preserveContent)
- {
- tagFloatBuffer.Clear(preserveContent);
- tagS32Buffer.Clear(preserveContent);
- tagU32Buffer.Clear(preserveContent);
- tagU64Buffer.Clear(preserveContent);
- tagPointBuffer.Clear(preserveContent);
- tagStringBuffer.Clear(preserveContent);
- }
-
- void Reset()
- {
- Clear(true);
- }
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct ProcessDescription
-{
- string name;
- ProcessID processID;
- uint64 uniqueKey;
- ProcessDescription(const char* processName, ProcessID pid, uint64 key);
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct ThreadDescription
-{
- string name;
- ThreadID threadID;
- ProcessID processID;
- int32 maxDepth;
- int32 priority;
- uint32 mask;
-
- ThreadDescription(const char* threadName, ThreadID tid, ProcessID pid, int32 maxDepth = 1, int32 priority = 0, uint32 mask = 0);
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct FiberDescription
-{
- uint64 id;
-
- FiberDescription(uint64 _id)
- : id(_id)
- {}
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct ThreadEntry
-{
- ThreadDescription description;
- EventStorage storage;
- EventStorage** threadTLS;
-
- bool isAlive;
-
- ThreadEntry(const ThreadDescription& desc, EventStorage** tls) : description(desc), threadTLS(tls), isAlive(true) {}
- void Activate(Mode::Type mode);
- void Sort();
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct FiberEntry
-{
- FiberDescription description;
- EventStorage storage;
-
- FiberEntry(const FiberDescription& desc) : description(desc) {}
-};
-
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-typedef vector<ThreadEntry*> ThreadList;
-typedef vector<FiberEntry*> FiberList;
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct SysCallData : EventData
-{
- uint64 id;
- uint64 threadID;
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream &operator << (OutputDataStream &stream, const SysCallData &ob);
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-class SysCallCollector
-{
- typedef MemoryPool<SysCallData, 1024 * 32> SysCallPool;
-public:
- SysCallPool syscallPool;
-
- SysCallData& Add();
- void Clear();
-
- bool Serialize(OutputDataStream& stream);
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct CallstackDesc
-{
- uint64 threadID;
- uint64 timestamp;
- uint64* callstack;
- uint8 count;
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-class CallstackCollector
-{
- // Packed callstack list: {ThreadID, Timestamp, Count, Callstack[Count]}
- typedef MemoryPool<uint64, 1024 * 32> CallstacksPool;
- CallstacksPool callstacksPool;
-public:
- void Add(const CallstackDesc& desc);
- void Clear();
-
- bool SerializeModules(OutputDataStream& stream);
- bool SerializeSymbols(OutputDataStream& stream);
- bool SerializeCallstacks(OutputDataStream& stream);
-
- bool IsEmpty() const;
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct SwitchContextDesc
-{
- int64_t timestamp;
- uint64 oldThreadId;
- uint64 newThreadId;
- uint8 cpuId;
- uint8 reason;
-};
-//////////////////////////////////////////////////////////////////////////
-OutputDataStream &operator << (OutputDataStream &stream, const SwitchContextDesc &ob);
-//////////////////////////////////////////////////////////////////////////
-class SwitchContextCollector
-{
- typedef MemoryPool<SwitchContextDesc, 1024 * 32> SwitchContextPool;
- SwitchContextPool switchContextPool;
-public:
- void Add(const SwitchContextDesc& desc);
- void Clear();
- bool Serialize(OutputDataStream& stream);
-};
-//////////////////////////////////////////////////////////////////////////
-
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct CaptureStatus
-{
- enum Type
- {
- OK = 0,
- ERR_TRACER_ALREADY_EXISTS = 1,
- ERR_TRACER_ACCESS_DENIED = 2,
- ERR_TRACER_FAILED = 3,
- ERR_TRACER_INVALID_PASSWORD = 4,
- };
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-class Core
-{
- std::recursive_mutex coreLock;
- std::recursive_mutex threadsLock;
-
- ThreadList threads;
- FiberList fibers;
-
- int64 progressReportedLastTimestampMS;
-
- vector<EventTime> frames;
- uint32 boardNumber;
-
- CallstackCollector callstackCollector;
- SwitchContextCollector switchContextCollector;
-
- vector<std::pair<string, string>> summary;
-
- std::atomic<uint32_t> frameNumber;
-
- struct Attachment
- {
- string name;
- vector<uint8_t> data;
- File::Type type;
- Attachment(File::Type t, const char* n) : name(n), type(t) {}
- };
- list<Attachment> attachments;
-
- StateCallback stateCallback;
-
- vector<ProcessDescription> processDescs;
- vector<ThreadDescription> threadDescs;
-
- array<const EventDescription*, FrameType::COUNT> frameDescriptions;
-
- State::Type currentState;
- State::Type pendingState;
-
- CaptureSettings settings;
-
- void UpdateEvents();
- uint32_t Update();
- bool UpdateState();
-
- Core();
- ~Core();
-
- static Core notThreadSafeInstance;
-
- void DumpCapturingProgress();
- void SendHandshakeResponse(CaptureStatus::Type status);
-
-
- void DumpEvents(EventStorage& entry, const EventTime& timeSlice, ScopeData& scope);
- void DumpTags(EventStorage& entry, ScopeData& scope);
- void DumpThread(ThreadEntry& entry, const EventTime& timeSlice, ScopeData& scope);
- void DumpFiber(FiberEntry& entry, const EventTime& timeSlice, ScopeData& scope);
-
- void CleanupThreadsAndFibers();
-
- void DumpBoard(uint32 mode, EventTime timeSlice, uint32 mainThreadIndex);
-
- void GenerateCommonSummary();
-public:
- void Activate(Mode::Type mode);
- volatile Mode::Type currentMode;
-
- // Active Frame (is used as buffer)
- static OPTICK_THREAD_LOCAL EventStorage* storage;
-
- // Resolves symbols
- SymbolEngine* symbolEngine;
-
- // Controls GPU activity
- // Graphics graphics;
-
- // System scheduler trace
- Trace* tracer;
-
- // SysCall Collector
- SysCallCollector syscallCollector;
-
- // GPU Profiler
- GPUProfiler* gpuProfiler;
-
- // Returns thread collection
- const vector<ThreadEntry*>& GetThreads() const;
-
- // Request to start a new capture
- void StartCapture();
-
- // Request to stop an active capture
- void StopCapture();
-
- // Request to stop an active capture
- void CancelCapture();
-
- // Requests to dump current capture
- void DumpCapture();
-
- // Report switch context event
- bool ReportSwitchContext(const SwitchContextDesc& desc);
-
- // Report switch context event
- bool ReportStackWalk(const CallstackDesc& desc);
-
- // Serialize and send current profiling progress
- void DumpProgress(const char* message = "");
-
- // Too much time from last report
- bool IsTimeToReportProgress() const;
-
- // Serialize and send frames
- void DumpFrames(uint32 mode = Mode::DEFAULT);
-
- // Serialize and send frames
- void DumpSummary();
-
- // Registers thread and create EventStorage
- ThreadEntry* RegisterThread(const ThreadDescription& description, EventStorage** slot);
-
- // UnRegisters thread
- bool UnRegisterThread(ThreadID threadId, bool keepAlive = false);
-
- // Check is registered thread
- bool IsRegistredThread(ThreadID id);
-
- // Registers finer and create EventStorage
- bool RegisterFiber(const FiberDescription& description, EventStorage** slot);
-
- // Registers ProcessDescription
- bool RegisterProcessDescription(const ProcessDescription& description);
-
- // Registers ThreaDescription (used for threads from other processes)
- bool RegisterThreadDescription(const ThreadDescription& description);
-
- // Sets state change callback
- bool SetStateChangedCallback(StateCallback cb);
-
- // Attaches a key-value pair to the next capture
- bool AttachSummary(const char* key, const char* value);
-
- // Attaches a screenshot to the current capture
- bool AttachFile(File::Type type, const char* name, const uint8_t* data, uint32_t size);
- bool AttachFile(File::Type type, const char* name, std::istream& stream);
- bool AttachFile(File::Type type, const char* name, const char* path);
- bool AttachFile(File::Type type, const char* name, const wchar_t* path);
-
- // Initalizes GPU profiler
- void InitGPUProfiler(GPUProfiler* profiler);
-
- // Initializes root password for the device
- bool SetSettings(const CaptureSettings& settings);
-
- // Current Frame Number (since the game started)
- uint32_t GetCurrentFrame() const { return frameNumber; }
-
- // Returns Frame Description
- const EventDescription* GetFrameDescription(FrameType::Type frame) const;
-
- // NOT Thread Safe singleton (performance)
- static Core& Get();
-
- // Main Update Function
- static uint32_t NextFrame() { return Get().Update(); }
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-}
-
-#endif //USE_OPTICK \ No newline at end of file
diff --git a/external/optick/optick_core.linux.h b/external/optick/optick_core.linux.h
deleted file mode 100644
index e0f4b49..0000000
--- a/external/optick/optick_core.linux.h
+++ /dev/null
@@ -1,410 +0,0 @@
-#pragma once
-#if defined(__linux__)
-
-#include "optick.config.h"
-#if USE_OPTICK
-
-#include "optick_core.platform.h"
-
-#include <sys/syscall.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <pthread.h>
-#include <unistd.h>
-
-namespace Optick
-{
- const char* Platform::GetName()
- {
- return "Linux";
- }
-
- ThreadID Platform::GetThreadID()
- {
- return syscall(SYS_gettid);
- }
-
- ProcessID Platform::GetProcessID()
- {
- return (ProcessID)getpid();
- }
-
- int64 Platform::GetFrequency()
- {
- return 1000000000;
- }
-
- int64 Platform::GetTime()
- {
- struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- return ts.tv_sec * 1000000000LL + ts.tv_nsec;
- }
-}
-
-#if OPTICK_ENABLE_TRACING
-
-#include "optick_memory.h"
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-namespace ft
-{
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- struct base_event
- {
- int64_t timestamp;
- short common_type;
- uint8_t cpu_id;
- base_event(short type) : timestamp(-1), common_type(type), cpu_id(uint8_t(-1)) {}
-};
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- template<short TYPE>
- struct event : public base_event
- {
- static const short type = TYPE;
- event() : base_event(TYPE) {}
- };
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- struct process_state
- {
- enum type
- {
- Unknown,
- //D Uninterruptible sleep(usually IO)
- UninterruptibleSleep,
- //R Running or runnable(on run queue)
- Running,
- //S Interruptible sleep(waiting for an event to complete)
- InterruptibleSleep,
- //T Stopped, either by a job control signal or because it is being traced.
- Stopped,
- //X dead(should never be seen)
- Dead,
- //Z Defunct(“zombie”) process, terminated but not reaped by its parent.
- Zombie,
- };
- };
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- struct sched_switch : public event<305>
- {
- char prev_comm[16];
- pid_t prev_pid;
- int prev_prio;
- process_state::type prev_state;
- char next_comm[16];
- pid_t next_pid;
- int next_prio;
- };
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-} // namespace ft
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-namespace Optick
-{
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-static const char* KERNEL_TRACING_PATH = "/sys/kernel/debug/tracing";
-static const char* FTRACE_TRACE = "trace";
-static const char* FTRACE_TRACING_ON = "tracing_on";
-static const char* FTRACE_TRACE_CLOCK = "trace_clock";
-static const char* FTRACE_OPTIONS_IRQ_INFO = "options/irq-info";
-static const char* FTRACE_SCHED_SWITCH = "events/sched/sched_switch/enable";
-static const uint8_t PROCESS_STATE_REASON_START = 38;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-class FTrace : public Trace
-{
- bool isActive;
- string password;
-
- bool Parse(const char* line);
- bool ProcessEvent(const ft::base_event& ev);
-
- void Set(const char* name, bool value);
- void Set(const char* name, const char* value);
- void Exec(const char* cmd);
-public:
-
- FTrace();
- ~FTrace();
-
- virtual void SetPassword(const char* pwd) override { password = pwd; }
- virtual CaptureStatus::Type Start(Mode::Type mode, int frequency, const ThreadList& threads) override;
- virtual bool Stop() override;
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-FTrace g_FTrace;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct Parser
-{
- const char* cursor;
- const char* finish;
- size_t length;
-
- Parser(const char* b) : cursor(b), finish(b + strlen(b)) {}
-
- bool Skip(size_t count)
- {
- if ((size_t)(finish - cursor) > count)
- {
- cursor += count;
- return true;
- }
- return false;
- }
-
- bool Skip(const char* text, char* output = nullptr, size_t size = 0)
- {
- if (const char* ptr = strstr(cursor, text))
- {
- if (output != nullptr)
- {
- size_t count = std::min(size - 1, (size_t)(ptr - cursor));
- strncpy(output, cursor, count);
- output[count] = '\0';
- }
- cursor = ptr + strlen(text);
- return true;
- }
- return false;
- }
-
- void SkipSpaces()
- {
- while (cursor != finish && (*cursor == ' ' || *cursor == '\t' || *cursor == '\n'))
- ++cursor;
- }
-
- bool Starts(const char* text) const
- {
- return strncmp(cursor, text, strlen(text)) == 0;
- }
-
- int GetInt() const
- {
- return atoi(cursor);
- }
-
- char GetChar() const
- {
- return *cursor;
- }
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-CaptureStatus::Type FTrace::Start(Mode::Type mode, int /*frequency*/, const ThreadList& /*threads*/)
-{
- if (!isActive)
- {
- // Disable tracing
- Set(FTRACE_TRACING_ON, false);
- // Cleanup old data
- Set(FTRACE_TRACE, "");
- // Set clock type
- Set(FTRACE_TRACE_CLOCK, "mono");
- // Disable irq info
- Set(FTRACE_OPTIONS_IRQ_INFO, false);
- // Enable switch events
- Set(FTRACE_SCHED_SWITCH, (mode & Mode::SWITCH_CONTEXT) != 0);
-
- // Enable tracing
- Set(FTRACE_TRACING_ON, true);
-
- isActive = true;
- }
-
- return CaptureStatus::OK;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool FTrace::Stop()
-{
- if (!isActive)
- {
- return false;
- }
-
- // Reset variables
- Set(FTRACE_TRACING_ON, false);
- Set(FTRACE_SCHED_SWITCH, false);
-
- // Parsing the output
- char buffer[256] = { 0 };
- sprintf_s(buffer, "echo \'%s\' | sudo -S sh -c \'cat %s/%s\'", password.c_str(), KERNEL_TRACING_PATH, FTRACE_TRACE);
- if (FILE* pipe = popen(buffer, "r"))
- {
- char* line = NULL;
- size_t len = 0;
- while ((getline(&line, &len, pipe)) != -1)
- Parse(line);
- fclose(pipe);
- }
-
- // Cleanup data
- Set(FTRACE_TRACE, "");
-
- isActive = false;
-
- return true;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool FTrace::Parse(const char * line)
-{
- // sched_switch:
- // ConsoleApp-8687 [000] 181944.352057: sched_switch: prev_comm=ConsoleApp prev_pid=8687 prev_prio=120 prev_state=S ==> next_comm=ConsoleApp next_pid=8686 next_prio=120
-
- Parser p(line);
- if (p.Starts("#"))
- return true;
-
- if (!p.Skip(16))
- return false;
-
- if (!p.Skip("["))
- return false;
-
- int cpu = p.GetInt();
- if (!p.Skip("]"))
- return false;
-
- int64 timestampInt = p.GetInt();
- if (!p.Skip("."))
- return false;
-
- int64 timestampFraq = p.GetInt();
- if (!p.Skip(": "))
- return false;
-
- int64 timestamp = ((timestampInt * 1000000) + timestampFraq) * 1000;
-
- if (p.Starts("sched_switch:"))
- {
- ft::sched_switch ev;
- ev.cpu_id = cpu;
- ev.timestamp = timestamp;
-
- if (!p.Skip("prev_comm="))
- return false;
-
- if (!p.Skip(" prev_pid=", ev.prev_comm, OPTICK_ARRAY_SIZE(ev.prev_comm)))
- return false;
-
- ev.prev_pid = p.GetInt();
-
- if (!p.Skip(" prev_prio="))
- return false;
-
- ev.prev_prio = p.GetInt();
-
- if (!p.Skip(" prev_state="))
- return false;
-
- switch (p.GetChar())
- {
- case 'D':
- ev.prev_state = ft::process_state::UninterruptibleSleep;
- break;
-
- case 'R':
- ev.prev_state = ft::process_state::Running;
- break;
-
- case 'S':
- ev.prev_state = ft::process_state::InterruptibleSleep;
- break;
-
- case 'T':
- ev.prev_state = ft::process_state::Stopped;
- break;
-
- case 'X':
- ev.prev_state = ft::process_state::Dead;
- break;
-
- case 'Z':
- ev.prev_state = ft::process_state::Zombie;
- break;
-
- default:
- ev.prev_state = ft::process_state::Unknown;
- break;
- }
-
- if (!p.Skip("==> next_comm="))
- return false;
-
- if (!p.Skip(" next_pid=", ev.next_comm, OPTICK_ARRAY_SIZE(ev.prev_comm)))
- return false;
-
- ev.next_pid = p.GetInt();
-
- if (!p.Skip(" next_prio="))
- return false;
-
- ev.next_prio = p.GetInt();
-
- return ProcessEvent(ev);
- }
- return true;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool FTrace::ProcessEvent(const ft::base_event& ev)
-{
- switch (ev.common_type)
- {
- case ft::sched_switch::type:
- {
- const ft::sched_switch& switchEv = (const ft::sched_switch&)ev;
- SwitchContextDesc desc;
- desc.reason = switchEv.prev_state + PROCESS_STATE_REASON_START;
- desc.cpuId = switchEv.cpu_id;
- desc.oldThreadId = (uint64)switchEv.prev_pid;
- desc.newThreadId = (uint64)switchEv.next_pid;
- desc.timestamp = switchEv.timestamp;
- Core::Get().ReportSwitchContext(desc);
- return true;
- }
- break;
- }
-
- return false;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void FTrace::Set(const char * name, bool value)
-{
- Set(name, value ? "1" : "0");
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void FTrace::Set(const char* name, const char* value)
-{
- char buffer[256] = { 0 };
- sprintf_s(buffer, "echo %s > %s/%s", value, KERNEL_TRACING_PATH, name);
- Exec(buffer);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void FTrace::Exec(const char* cmd)
-{
- char buffer[256] = { 0 };
- sprintf_s(buffer, "echo \'%s\' | sudo -S sh -c \'%s\'", password.c_str(), cmd);
- std::system(buffer);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-FTrace::FTrace() : isActive(false)
-{
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-FTrace::~FTrace()
-{
- Stop();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-Trace* Platform::GetTrace()
-{
- return &g_FTrace;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-SymbolEngine* Platform::GetSymbolEngine()
-{
- return nullptr;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-}
-#endif //OPTICK_ENABLE_TRACING
-#endif //USE_OPTICK
-#endif //__linux__ \ No newline at end of file
diff --git a/external/optick/optick_core.macos.h b/external/optick/optick_core.macos.h
deleted file mode 100644
index 3d19bfd..0000000
--- a/external/optick/optick_core.macos.h
+++ /dev/null
@@ -1,289 +0,0 @@
-#pragma once
-#if defined(__APPLE_CC__)
-
-#include "optick.config.h"
-#if USE_OPTICK
-
-#include "optick_core.platform.h"
-
-#include <mach/mach_time.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <pthread.h>
-#include <unistd.h>
-
-namespace Optick
-{
- const char* Platform::GetName()
- {
- return "MacOS";
- }
-
- ThreadID Platform::GetThreadID()
- {
- uint64_t tid;
- pthread_threadid_np(pthread_self(), &tid);
- return tid;
- }
-
- ProcessID Platform::GetProcessID()
- {
- return (ProcessID)getpid();
- }
-
- int64 Platform::GetFrequency()
- {
- return 1000000000;
- }
-
- int64 Platform::GetTime()
- {
- struct timespec ts;
- clock_gettime(CLOCK_REALTIME, &ts);
- return ts.tv_sec * 1000000000LL + ts.tv_nsec;
- }
-}
-
-#if OPTICK_ENABLE_TRACING
-
-#include "optick_core.h"
-
-namespace Optick
-{
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-class DTrace : public Trace
-{
- static const bool isSilent = true;
-
- std::thread processThread;
- string password;
-
- enum State
- {
- STATE_IDLE,
- STATE_RUNNING,
- STATE_ABORT,
- };
-
- volatile State state;
- volatile int64 timeout;
-
- struct CoreState
- {
- ProcessID pid;
- ThreadID tid;
- int prio;
- bool IsValid() const { return tid != INVALID_THREAD_ID; }
- CoreState() : pid(INVALID_PROCESS_ID), tid(INVALID_THREAD_ID), prio(0) {}
- };
- static const int MAX_CPU_CORES = 256;
- array<CoreState, MAX_CPU_CORES> cores;
-
- static void AsyncProcess(DTrace* trace);
- void Process();
-
- bool CheckRootAccess();
-
- enum ParseResult
- {
- PARSE_OK,
- PARSE_TIMEOUT,
- PARSE_FAILED,
- };
- ParseResult Parse(const char* line);
-public:
-
- DTrace();
-
- virtual void SetPassword(const char* pwd) override { password = pwd; }
- virtual CaptureStatus::Type Start(Mode::Type mode, int frequency, const ThreadList& threads) override;
- virtual bool Stop() override;
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-DTrace g_DTrace;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-DTrace::DTrace() : state(STATE_IDLE), timeout(0)
-{
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool DTrace::CheckRootAccess()
-{
- char cmd[256] = { 0 };
- sprintf_s(cmd, "echo \'%s\' | sudo -S echo %s", password.c_str(), isSilent ? "2> /dev/null" : "");
- return system(cmd) == 0;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-CaptureStatus::Type DTrace::Start(Mode::Type mode, int /*frequency*/, const ThreadList& /*threads*/)
-{
- if (state == STATE_IDLE && (mode & Mode::SWITCH_CONTEXT) != 0)
- {
- if (!CheckRootAccess())
- return CaptureStatus::ERR_TRACER_INVALID_PASSWORD;
-
- state = STATE_RUNNING;
- timeout = INT64_MAX;
- cores.fill(CoreState());
- processThread = std::thread(AsyncProcess, this);
- }
-
- return CaptureStatus::OK;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool DTrace::Stop()
-{
- if (state != STATE_RUNNING)
- {
- return false;
- }
-
- timeout = Platform::GetTime();
- processThread.join();
- state = STATE_IDLE;
-
- return true;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-FILE* popen2(const char *program, const char *type, pid_t* outPid)
-{
- FILE *iop;
- int pdes[2];
- pid_t pid;
- if ((*type != 'r' && *type != 'w') || type[1] != '\0') {
- errno = EINVAL;
- return (NULL);
- }
-
- if (pipe(pdes) < 0) {
- return (NULL);
- }
-
- switch (pid = fork()) {
- case -1: /* Error. */
- (void)close(pdes[0]);
- (void)close(pdes[1]);
- return (NULL);
- /* NOTREACHED */
- case 0: /* Child. */
- {
- if (*type == 'r') {
- (void)close(pdes[0]);
- if (pdes[1] != STDOUT_FILENO) {
- (void)dup2(pdes[1], STDOUT_FILENO);
- (void)close(pdes[1]);
- }
- }
- else {
- (void)close(pdes[1]);
- if (pdes[0] != STDIN_FILENO) {
- (void)dup2(pdes[0], STDIN_FILENO);
- (void)close(pdes[0]);
- }
- }
- execl("/bin/sh", "sh", "-c", program, NULL);
- perror("execl");
- exit(1);
- /* NOTREACHED */
- }
- }
- /* Parent; assume fdopen can't fail. */
- if (*type == 'r') {
- iop = fdopen(pdes[0], type);
- (void)close(pdes[1]);
- }
- else {
- iop = fdopen(pdes[1], type);
- (void)close(pdes[0]);
- }
-
- if (outPid)
- *outPid = pid;
-
- return (iop);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void DTrace::Process()
-{
- const char* command = "dtrace -n fbt::thread_dispatch:return'\\''{printf(\"@%d %d %d %d\", pid, tid, curthread->sched_pri, walltimestamp)}'\\''";
-
- char buffer[256] = { 0 };
- sprintf_s(buffer, "echo \'%s\' | sudo -S sh -c \'%s\' %s", password.c_str(), command, isSilent ? "2> /dev/null" : "");
- pid_t pid;
- if (FILE* pipe = popen2(buffer, "r", &pid))
- {
- char* line = NULL;
- size_t len = 0;
- while (state == STATE_RUNNING && (getline(&line, &len, pipe)) != -1)
- {
- if (Parse(line) == PARSE_TIMEOUT)
- break;
- }
- fclose(pipe);
-
- int internal_stat;
- waitpid(pid, &internal_stat, 0);
- }
- else
- {
- OPTICK_FAILED("Failed to open communication pipe!");
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-DTrace::ParseResult DTrace::Parse(const char* line)
-{
- if (const char* cmd = strchr(line, '@'))
- {
- int cpu = atoi(line);
-
- CoreState currState;
-
- currState.pid = atoi(cmd + 1);
- cmd = strchr(cmd, ' ') + 1;
-
- currState.tid = atoi(cmd);
- cmd = strchr(cmd, ' ') + 1;
-
- currState.prio = atoi(cmd);
- cmd = strchr(cmd, ' ') + 1;
-
- int64_t timestamp = (int64_t)atoll(cmd);
-
- if (timestamp > timeout)
- return PARSE_TIMEOUT;
-
- const CoreState& prevState = cores[cpu];
-
- if (prevState.IsValid())
- {
- SwitchContextDesc desc;
- desc.reason = 0;
- desc.cpuId = cpu;
- desc.oldThreadId = prevState.tid;
- desc.newThreadId = currState.tid;
- desc.timestamp = timestamp;
- Core::Get().ReportSwitchContext(desc);
- }
-
- cores[cpu] = currState;
- }
- return PARSE_FAILED;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void DTrace::AsyncProcess(DTrace *trace) {
- trace->Process();
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-Trace* Platform::GetTrace()
-{
- return &g_DTrace;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-SymbolEngine* Platform::GetSymbolEngine()
-{
- return nullptr;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-}
-#endif //OPTICK_ENABLE_TRACING
-#endif //USE_OPTICK
-#endif //__APPLE_CC__ \ No newline at end of file
diff --git a/external/optick/optick_core.platform.h b/external/optick/optick_core.platform.h
deleted file mode 100644
index 683376d..0000000
--- a/external/optick/optick_core.platform.h
+++ /dev/null
@@ -1,92 +0,0 @@
-#pragma once
-#include "optick.config.h"
-
-#if USE_OPTICK
-
-#include "optick_common.h"
-#include "optick_memory.h"
-
-//////////////////////////////////////////////////////////////////////////
-// Platform-specific stuff
-//////////////////////////////////////////////////////////////////////////
-namespace Optick
-{
- struct Trace;
- struct Module;
- struct Symbol;
- struct SymbolEngine;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Platform API
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- struct Platform
- {
- // Platform Name
- static OPTICK_INLINE const char* GetName();
- // Thread ID (system thread id)
- static OPTICK_INLINE ThreadID GetThreadID();
- // Process ID
- static OPTICK_INLINE ProcessID GetProcessID();
- // CPU Frequency
- static OPTICK_INLINE int64 GetFrequency();
- // CPU Time (Ticks)
- static OPTICK_INLINE int64 GetTime();
- // System Tracer
- static OPTICK_INLINE Trace* GetTrace();
- // Symbol Resolver
- static OPTICK_INLINE SymbolEngine* GetSymbolEngine();
- };
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Tracing API
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- struct Trace
- {
- virtual void SetPassword(const char* /*pwd*/) {};
- virtual CaptureStatus::Type Start(Mode::Type mode, int frequency, const ThreadList& threads) = 0;
- virtual bool Stop() = 0;
- virtual ~Trace() {};
- };
-
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Symbol API
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- struct Module
- {
- string path;
- void* address;
- size_t size;
- Module(const char* p, void* a, size_t s) : path(p), address(a), size(s) {}
- };
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- struct Symbol
- {
- uint64 address;
- uint64 offset;
- wstring file;
- wstring function;
- uint32 line;
- Symbol()
- : address(0)
- , offset(0)
- , line(0)
- {}
- };
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- struct SymbolEngine
- {
- // Get list of loaded modules
- virtual const vector<Module>& GetModules() = 0;
-
- // Get Symbol from address
- virtual const Symbol* GetSymbol(uint64 dwAddress) = 0;
-
- virtual ~SymbolEngine() {};
- };
-}
-//////////////////////////////////////////////////////////////////////////
-
-#endif //USE_OPTICK \ No newline at end of file
diff --git a/external/optick/optick_core.win.h b/external/optick/optick_core.win.h
deleted file mode 100644
index 0d8a11a..0000000
--- a/external/optick/optick_core.win.h
+++ /dev/null
@@ -1,1664 +0,0 @@
-#pragma once
-#if defined(_MSC_VER)
-
-#include "optick.config.h"
-
-#if USE_OPTICK
-
-#include "optick_core.platform.h"
-
-namespace Optick
-{
- const char* Platform::GetName()
- {
- #if defined(OPTICK_PC)
- return "Windows";
- #else
- return "XBox";
- #endif
- }
-
- ThreadID Platform::GetThreadID()
- {
- return GetCurrentThreadId();
- }
-
- ProcessID Platform::GetProcessID()
- {
- return GetCurrentProcessId();
- }
-
- int64 Platform::GetFrequency()
- {
- LARGE_INTEGER frequency;
- QueryPerformanceFrequency(&frequency);
- return frequency.QuadPart;
- }
-
- int64 Platform::GetTime()
- {
- LARGE_INTEGER largeInteger;
- QueryPerformanceCounter(&largeInteger);
- return largeInteger.QuadPart;
- }
-}
-
-#if OPTICK_ENABLE_TRACING
-#include <psapi.h>
-#include "optick_core.h"
-
-/*
-Event Tracing Functions - API
-https://msdn.microsoft.com/en-us/library/windows/desktop/aa363795(v=vs.85).aspx
-*/
-
-#define DECLARE_ETW (!OPTICK_PC)
-
-#if DECLARE_ETW
-// Copied from Windows SDK
-#ifndef WMIAPI
-#ifndef MIDL_PASS
-#ifdef _WMI_SOURCE_
-#define WMIAPI __stdcall
-#else
-#define WMIAPI DECLSPEC_IMPORT __stdcall
-#endif // _WMI_SOURCE
-#endif // MIDL_PASS
-#endif // WMIAPI
-#define INITGUID
-#include <guiddef.h>
-#if defined(_NTDDK_) || defined(_NTIFS_) || defined(_WMIKM_)
-#define _EVNTRACE_KERNEL_MODE
-#endif
-#if !defined(_EVNTRACE_KERNEL_MODE)
-#include <wmistr.h>
-#endif
-
-#if _MSC_VER <= 1600
-#define EVENT_DESCRIPTOR_DEF
-#define EVENT_HEADER_DEF
-#define EVENT_HEADER_EXTENDED_DATA_ITEM_DEF
-#define EVENT_RECORD_DEF
-#endif
-
-#ifndef _TRACEHANDLE_DEFINED
-#define _TRACEHANDLE_DEFINED
-typedef ULONG64 TRACEHANDLE, *PTRACEHANDLE;
-#endif
-
-//
-// EventTraceGuid is used to identify a event tracing session
-//
-DEFINE_GUID( /* 68fdd900-4a3e-11d1-84f4-0000f80464e3 */
- EventTraceGuid,
- 0x68fdd900,
- 0x4a3e,
- 0x11d1,
- 0x84, 0xf4, 0x00, 0x00, 0xf8, 0x04, 0x64, 0xe3
-);
-
-//
-// SystemTraceControlGuid. Used to specify event tracing for kernel
-//
-DEFINE_GUID( /* 9e814aad-3204-11d2-9a82-006008a86939 */
- SystemTraceControlGuid,
- 0x9e814aad,
- 0x3204,
- 0x11d2,
- 0x9a, 0x82, 0x00, 0x60, 0x08, 0xa8, 0x69, 0x39
-);
-
-//
-// EventTraceConfigGuid. Used to report system configuration records
-//
-DEFINE_GUID( /* 01853a65-418f-4f36-aefc-dc0f1d2fd235 */
- EventTraceConfigGuid,
- 0x01853a65,
- 0x418f,
- 0x4f36,
- 0xae, 0xfc, 0xdc, 0x0f, 0x1d, 0x2f, 0xd2, 0x35
-);
-
-//
-// DefaultTraceSecurityGuid. Specifies the default event tracing security
-//
-DEFINE_GUID( /* 0811c1af-7a07-4a06-82ed-869455cdf713 */
- DefaultTraceSecurityGuid,
- 0x0811c1af,
- 0x7a07,
- 0x4a06,
- 0x82, 0xed, 0x86, 0x94, 0x55, 0xcd, 0xf7, 0x13
-);
-
-
-///////////////////////////////////////////////////////////////////////////////
-#define PROCESS_TRACE_MODE_REAL_TIME 0x00000100
-#define PROCESS_TRACE_MODE_RAW_TIMESTAMP 0x00001000
-#define PROCESS_TRACE_MODE_EVENT_RECORD 0x10000000
-///////////////////////////////////////////////////////////////////////////////
-#define EVENT_HEADER_FLAG_EXTENDED_INFO 0x0001
-#define EVENT_HEADER_FLAG_PRIVATE_SESSION 0x0002
-#define EVENT_HEADER_FLAG_STRING_ONLY 0x0004
-#define EVENT_HEADER_FLAG_TRACE_MESSAGE 0x0008
-#define EVENT_HEADER_FLAG_NO_CPUTIME 0x0010
-#define EVENT_HEADER_FLAG_32_BIT_HEADER 0x0020
-#define EVENT_HEADER_FLAG_64_BIT_HEADER 0x0040
-#define EVENT_HEADER_FLAG_CLASSIC_HEADER 0x0100
-#define EVENT_HEADER_FLAG_PROCESSOR_INDEX 0x0200
-///////////////////////////////////////////////////////////////////////////////
-#define KERNEL_LOGGER_NAMEW L"NT Kernel Logger"
-///////////////////////////////////////////////////////////////////////////////
-#define EVENT_TRACE_REAL_TIME_MODE 0x00000100 // Real time mode on
-///////////////////////////////////////////////////////////////////////////////
-#define EVENT_TRACE_CONTROL_STOP 1
-///////////////////////////////////////////////////////////////////////////////
-
-//
-// Enable flags for Kernel Events
-//
-#define EVENT_TRACE_FLAG_PROCESS 0x00000001 // process start & end
-#define EVENT_TRACE_FLAG_THREAD 0x00000002 // thread start & end
-#define EVENT_TRACE_FLAG_IMAGE_LOAD 0x00000004 // image load
-
-#define EVENT_TRACE_FLAG_DISK_IO 0x00000100 // physical disk IO
-#define EVENT_TRACE_FLAG_DISK_FILE_IO 0x00000200 // requires disk IO
-
-#define EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS 0x00001000 // all page faults
-#define EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS 0x00002000 // hard faults only
-
-#define EVENT_TRACE_FLAG_NETWORK_TCPIP 0x00010000 // tcpip send & receive
-
-#define EVENT_TRACE_FLAG_REGISTRY 0x00020000 // registry calls
-#define EVENT_TRACE_FLAG_DBGPRINT 0x00040000 // DbgPrint(ex) Calls
-
-//
-// Enable flags for Kernel Events on Vista and above
-//
-#define EVENT_TRACE_FLAG_PROCESS_COUNTERS 0x00000008 // process perf counters
-#define EVENT_TRACE_FLAG_CSWITCH 0x00000010 // context switches
-#define EVENT_TRACE_FLAG_DPC 0x00000020 // deffered procedure calls
-#define EVENT_TRACE_FLAG_INTERRUPT 0x00000040 // interrupts
-#define EVENT_TRACE_FLAG_SYSTEMCALL 0x00000080 // system calls
-
-#define EVENT_TRACE_FLAG_DISK_IO_INIT 0x00000400 // physical disk IO initiation
-#define EVENT_TRACE_FLAG_ALPC 0x00100000 // ALPC traces
-#define EVENT_TRACE_FLAG_SPLIT_IO 0x00200000 // split io traces (VolumeManager)
-
-#define EVENT_TRACE_FLAG_DRIVER 0x00800000 // driver delays
-#define EVENT_TRACE_FLAG_PROFILE 0x01000000 // sample based profiling
-#define EVENT_TRACE_FLAG_FILE_IO 0x02000000 // file IO
-#define EVENT_TRACE_FLAG_FILE_IO_INIT 0x04000000 // file IO initiation
-
-#define EVENT_TRACE_FLAG_PMC_PROFILE 0x80000000 // sample based profiling (PMC) - NOT CONFIRMED!
-
-//
-// Enable flags for Kernel Events on Win7 and above
-//
-#define EVENT_TRACE_FLAG_DISPATCHER 0x00000800 // scheduler (ReadyThread)
-#define EVENT_TRACE_FLAG_VIRTUAL_ALLOC 0x00004000 // VM operations
-
-//
-// Enable flags for Kernel Events on Win8 and above
-//
-#define EVENT_TRACE_FLAG_VAMAP 0x00008000 // map/unmap (excluding images)
-#define EVENT_TRACE_FLAG_NO_SYSCONFIG 0x10000000 // Do not do sys config rundown
-
-///////////////////////////////////////////////////////////////////////////////
-
-#pragma warning(push)
-#pragma warning (disable:4201)
-
-#ifndef EVENT_DESCRIPTOR_DEF
-#define EVENT_DESCRIPTOR_DEF
-typedef struct _EVENT_DESCRIPTOR {
-
- USHORT Id;
- UCHAR Version;
- UCHAR Channel;
- UCHAR Level;
- UCHAR Opcode;
- USHORT Task;
- ULONGLONG Keyword;
-
-} EVENT_DESCRIPTOR, *PEVENT_DESCRIPTOR;
-typedef const EVENT_DESCRIPTOR *PCEVENT_DESCRIPTOR;
-#endif
-///////////////////////////////////////////////////////////////////////////////
-#ifndef EVENT_HEADER_DEF
-#define EVENT_HEADER_DEF
-typedef struct _EVENT_HEADER {
-
- USHORT Size;
- USHORT HeaderType;
- USHORT Flags;
- USHORT EventProperty;
- ULONG ThreadId;
- ULONG ProcessId;
- LARGE_INTEGER TimeStamp;
- GUID ProviderId;
- EVENT_DESCRIPTOR EventDescriptor;
- union {
- struct {
- ULONG KernelTime;
- ULONG UserTime;
- } DUMMYSTRUCTNAME;
- ULONG64 ProcessorTime;
-
- } DUMMYUNIONNAME;
- GUID ActivityId;
-
-} EVENT_HEADER, *PEVENT_HEADER;
-#endif
-///////////////////////////////////////////////////////////////////////////////
-#ifndef EVENT_HEADER_EXTENDED_DATA_ITEM_DEF
-#define EVENT_HEADER_EXTENDED_DATA_ITEM_DEF
-typedef struct _EVENT_HEADER_EXTENDED_DATA_ITEM {
-
- USHORT Reserved1; // Reserved for internal use
- USHORT ExtType; // Extended info type
- struct {
- USHORT Linkage : 1; // Indicates additional extended
- // data item
- USHORT Reserved2 : 15;
- };
- USHORT DataSize; // Size of extended info data
- ULONGLONG DataPtr; // Pointer to extended info data
-
-} EVENT_HEADER_EXTENDED_DATA_ITEM, *PEVENT_HEADER_EXTENDED_DATA_ITEM;
-#endif
-///////////////////////////////////////////////////////////////////////////////
-#ifndef ETW_BUFFER_CONTEXT_DEF
-#define ETW_BUFFER_CONTEXT_DEF
-typedef struct _ETW_BUFFER_CONTEXT {
- union {
- struct {
- UCHAR ProcessorNumber;
- UCHAR Alignment;
- } DUMMYSTRUCTNAME;
- USHORT ProcessorIndex;
- } DUMMYUNIONNAME;
- USHORT LoggerId;
-} ETW_BUFFER_CONTEXT, *PETW_BUFFER_CONTEXT;
-#endif
-///////////////////////////////////////////////////////////////////////////////
-#ifndef EVENT_RECORD_DEF
-#define EVENT_RECORD_DEF
-typedef struct _EVENT_RECORD {
- EVENT_HEADER EventHeader;
- ETW_BUFFER_CONTEXT BufferContext;
- USHORT ExtendedDataCount;
-
- USHORT UserDataLength;
- PEVENT_HEADER_EXTENDED_DATA_ITEM ExtendedData;
- PVOID UserData;
- PVOID UserContext;
-} EVENT_RECORD, *PEVENT_RECORD;
-#endif
-///////////////////////////////////////////////////////////////////////////////
-typedef struct _EVENT_TRACE_PROPERTIES {
- WNODE_HEADER Wnode;
- //
- // data provided by caller
- ULONG BufferSize; // buffer size for logging (kbytes)
- ULONG MinimumBuffers; // minimum to preallocate
- ULONG MaximumBuffers; // maximum buffers allowed
- ULONG MaximumFileSize; // maximum logfile size (in MBytes)
- ULONG LogFileMode; // sequential, circular
- ULONG FlushTimer; // buffer flush timer, in seconds
- ULONG EnableFlags; // trace enable flags
- union {
- LONG AgeLimit; // unused
- LONG FlushThreshold; // Number of buffers to fill before flushing
- } DUMMYUNIONNAME;
-
- // data returned to caller
- ULONG NumberOfBuffers; // no of buffers in use
- ULONG FreeBuffers; // no of buffers free
- ULONG EventsLost; // event records lost
- ULONG BuffersWritten; // no of buffers written to file
- ULONG LogBuffersLost; // no of logfile write failures
- ULONG RealTimeBuffersLost; // no of rt delivery failures
- HANDLE LoggerThreadId; // thread id of Logger
- ULONG LogFileNameOffset; // Offset to LogFileName
- ULONG LoggerNameOffset; // Offset to LoggerName
-} EVENT_TRACE_PROPERTIES, *PEVENT_TRACE_PROPERTIES;
-
-typedef struct _EVENT_TRACE_HEADER { // overlays WNODE_HEADER
- USHORT Size; // Size of entire record
- union {
- USHORT FieldTypeFlags; // Indicates valid fields
- struct {
- UCHAR HeaderType; // Header type - internal use only
- UCHAR MarkerFlags; // Marker - internal use only
- } DUMMYSTRUCTNAME;
- } DUMMYUNIONNAME;
- union {
- ULONG Version;
- struct {
- UCHAR Type; // event type
- UCHAR Level; // trace instrumentation level
- USHORT Version; // version of trace record
- } Class;
- } DUMMYUNIONNAME2;
- ULONG ThreadId; // Thread Id
- ULONG ProcessId; // Process Id
- LARGE_INTEGER TimeStamp; // time when event happens
- union {
- GUID Guid; // Guid that identifies event
- ULONGLONG GuidPtr; // use with WNODE_FLAG_USE_GUID_PTR
- } DUMMYUNIONNAME3;
- union {
- struct {
- ULONG KernelTime; // Kernel Mode CPU ticks
- ULONG UserTime; // User mode CPU ticks
- } DUMMYSTRUCTNAME;
- ULONG64 ProcessorTime; // Processor Clock
- struct {
- ULONG ClientContext; // Reserved
- ULONG Flags; // Event Flags
- } DUMMYSTRUCTNAME2;
- } DUMMYUNIONNAME4;
-} EVENT_TRACE_HEADER, *PEVENT_TRACE_HEADER;
-
-typedef struct _EVENT_TRACE {
- EVENT_TRACE_HEADER Header; // Event trace header
- ULONG InstanceId; // Instance Id of this event
- ULONG ParentInstanceId; // Parent Instance Id.
- GUID ParentGuid; // Parent Guid;
- PVOID MofData; // Pointer to Variable Data
- ULONG MofLength; // Variable Datablock Length
- union {
- ULONG ClientContext;
- ETW_BUFFER_CONTEXT BufferContext;
- } DUMMYUNIONNAME;
-} EVENT_TRACE, *PEVENT_TRACE;
-
-typedef struct _TRACE_LOGFILE_HEADER {
- ULONG BufferSize; // Logger buffer size in Kbytes
- union {
- ULONG Version; // Logger version
- struct {
- UCHAR MajorVersion;
- UCHAR MinorVersion;
- UCHAR SubVersion;
- UCHAR SubMinorVersion;
- } VersionDetail;
- } DUMMYUNIONNAME;
- ULONG ProviderVersion; // defaults to NT version
- ULONG NumberOfProcessors; // Number of Processors
- LARGE_INTEGER EndTime; // Time when logger stops
- ULONG TimerResolution; // assumes timer is constant!!!
- ULONG MaximumFileSize; // Maximum in Mbytes
- ULONG LogFileMode; // specify logfile mode
- ULONG BuffersWritten; // used to file start of Circular File
- union {
- GUID LogInstanceGuid; // For RealTime Buffer Delivery
- struct {
- ULONG StartBuffers; // Count of buffers written at start.
- ULONG PointerSize; // Size of pointer type in bits
- ULONG EventsLost; // Events losts during log session
- ULONG CpuSpeedInMHz; // Cpu Speed in MHz
- } DUMMYSTRUCTNAME;
- } DUMMYUNIONNAME2;
-#if defined(_WMIKM_)
- PWCHAR LoggerName;
- PWCHAR LogFileName;
- RTL_TIME_ZONE_INFORMATION TimeZone;
-#else
- LPWSTR LoggerName;
- LPWSTR LogFileName;
- TIME_ZONE_INFORMATION TimeZone;
-#endif
- LARGE_INTEGER BootTime;
- LARGE_INTEGER PerfFreq; // Reserved
- LARGE_INTEGER StartTime; // Reserved
- ULONG ReservedFlags; // ClockType
- ULONG BuffersLost;
-} TRACE_LOGFILE_HEADER, *PTRACE_LOGFILE_HEADER;
-
-typedef enum _TRACE_QUERY_INFO_CLASS {
- TraceGuidQueryList,
- TraceGuidQueryInfo,
- TraceGuidQueryProcess,
- TraceStackTracingInfo, // Win7
- TraceSystemTraceEnableFlagsInfo,
- TraceSampledProfileIntervalInfo,
- TraceProfileSourceConfigInfo,
- TraceProfileSourceListInfo,
- TracePmcEventListInfo,
- TracePmcCounterListInfo,
- MaxTraceSetInfoClass
-} TRACE_QUERY_INFO_CLASS, TRACE_INFO_CLASS;
-
-typedef struct _CLASSIC_EVENT_ID {
- GUID EventGuid;
- UCHAR Type;
- UCHAR Reserved[7];
-} CLASSIC_EVENT_ID, *PCLASSIC_EVENT_ID;
-
-typedef struct _TRACE_PROFILE_INTERVAL {
- ULONG Source;
- ULONG Interval;
-} TRACE_PROFILE_INTERVAL, *PTRACE_PROFILE_INTERVAL;
-
-typedef struct _EVENT_TRACE_LOGFILEW
-EVENT_TRACE_LOGFILEW, *PEVENT_TRACE_LOGFILEW;
-
-typedef ULONG(WINAPI * PEVENT_TRACE_BUFFER_CALLBACKW)
-(PEVENT_TRACE_LOGFILEW Logfile);
-
-typedef VOID(WINAPI *PEVENT_CALLBACK)(PEVENT_TRACE pEvent);
-
-typedef struct _EVENT_RECORD
-EVENT_RECORD, *PEVENT_RECORD;
-
-typedef VOID(WINAPI *PEVENT_RECORD_CALLBACK) (PEVENT_RECORD EventRecord);
-
-struct _EVENT_TRACE_LOGFILEW {
- LPWSTR LogFileName; // Logfile Name
- LPWSTR LoggerName; // LoggerName
- LONGLONG CurrentTime; // timestamp of last event
- ULONG BuffersRead; // buffers read to date
- union {
- // Mode of the logfile
- ULONG LogFileMode;
- // Processing flags used on Vista and above
- ULONG ProcessTraceMode;
- } DUMMYUNIONNAME;
- EVENT_TRACE CurrentEvent; // Current Event from this stream.
- TRACE_LOGFILE_HEADER LogfileHeader; // logfile header structure
- PEVENT_TRACE_BUFFER_CALLBACKW // callback before each buffer
- BufferCallback; // is read
- //
- // following variables are filled for BufferCallback.
- //
- ULONG BufferSize;
- ULONG Filled;
- ULONG EventsLost;
- //
- // following needs to be propaged to each buffer
- //
- union {
- // Callback with EVENT_TRACE
- PEVENT_CALLBACK EventCallback;
- // Callback with EVENT_RECORD on Vista and above
- PEVENT_RECORD_CALLBACK EventRecordCallback;
- } DUMMYUNIONNAME2;
-
- ULONG IsKernelTrace; // TRUE for kernel logfile
-
- PVOID Context; // reserved for internal use
-};
-
-#pragma warning(pop)
-
-#define PEVENT_TRACE_BUFFER_CALLBACK PEVENT_TRACE_BUFFER_CALLBACKW
-#define EVENT_TRACE_LOGFILE EVENT_TRACE_LOGFILEW
-#define PEVENT_TRACE_LOGFILE PEVENT_TRACE_LOGFILEW
-#define KERNEL_LOGGER_NAME KERNEL_LOGGER_NAMEW
-#define GLOBAL_LOGGER_NAME GLOBAL_LOGGER_NAMEW
-#define EVENT_LOGGER_NAME EVENT_LOGGER_NAMEW
-
-EXTERN_C
-ULONG
-WMIAPI
-ProcessTrace(
- _In_reads_(HandleCount) PTRACEHANDLE HandleArray,
- _In_ ULONG HandleCount,
- _In_opt_ LPFILETIME StartTime,
- _In_opt_ LPFILETIME EndTime
-);
-
-EXTERN_C
-ULONG
-WMIAPI
-StartTraceW(
- _Out_ PTRACEHANDLE TraceHandle,
- _In_ LPCWSTR InstanceName,
- _Inout_ PEVENT_TRACE_PROPERTIES Properties
-);
-
-EXTERN_C
-ULONG
-WMIAPI
-ControlTraceW(
- _In_ TRACEHANDLE TraceHandle,
- _In_opt_ LPCWSTR InstanceName,
- _Inout_ PEVENT_TRACE_PROPERTIES Properties,
- _In_ ULONG ControlCode
-);
-
-EXTERN_C
-TRACEHANDLE
-WMIAPI
-OpenTraceW(
- _Inout_ PEVENT_TRACE_LOGFILEW Logfile
-);
-
-EXTERN_C
-ULONG
-WMIAPI
-CloseTrace(
- _In_ TRACEHANDLE TraceHandle
-);
-
-EXTERN_C
-ULONG
-WMIAPI
-TraceSetInformation(
- _In_ TRACEHANDLE SessionHandle,
- _In_ TRACE_INFO_CLASS InformationClass,
- _In_reads_bytes_(InformationLength) PVOID TraceInformation,
- _In_ ULONG InformationLength
-);
-
-EXTERN_C
-ULONG
-WMIAPI
-TraceQueryInformation(
- _In_ TRACEHANDLE SessionHandle,
- _In_ TRACE_INFO_CLASS InformationClass,
- _Out_writes_bytes_(InformationLength) PVOID TraceInformation,
- _In_ ULONG InformationLength,
- _Out_opt_ PULONG ReturnLength
-);
-
-//////////////////////////////////////////////////////////////////////////
-#define RegisterTraceGuids RegisterTraceGuidsW
-#define StartTrace StartTraceW
-#define ControlTrace ControlTraceW
-#define StopTrace StopTraceW
-#define QueryTrace QueryTraceW
-#define UpdateTrace UpdateTraceW
-#define FlushTrace FlushTraceW
-#define QueryAllTraces QueryAllTracesW
-#define OpenTrace OpenTraceW
-//////////////////////////////////////////////////////////////////////////
-#else
-#define INITGUID // Causes definition of SystemTraceControlGuid in evntrace.h.
-#include <wmistr.h>
-#include <evntrace.h>
-#include <strsafe.h>
-#include <evntcons.h>
-#endif //DECLARE_ETW
-
-namespace Optick
-{
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-class ETW : public Trace
-{
- static const int ETW_BUFFER_SIZE = 1024 << 10; // 1Mb
- static const int ETW_BUFFER_COUNT = 32;
- static const int ETW_MAXIMUM_SESSION_NAME = 1024;
-
- EVENT_TRACE_PROPERTIES *traceProperties;
- EVENT_TRACE_LOGFILE logFile;
- TRACEHANDLE traceSessionHandle;
- TRACEHANDLE openedHandle;
-
- HANDLE processThreadHandle;
- DWORD currentProcessId;
-
- bool isActive;
-
- static DWORD WINAPI RunProcessTraceThreadFunction(LPVOID parameter);
- static void AdjustPrivileges();
-
- unordered_map<uint64_t, const EventDescription*> syscallDescriptions;
-
- void ResolveSysCalls();
-public:
-
- unordered_set<uint64> activeThreadsIDs;
-
- ETW();
- ~ETW();
-
- virtual CaptureStatus::Type Start(Mode::Type mode, int frequency, const ThreadList& threads) override;
- virtual bool Stop() override;
-
- DWORD GetProcessID() const { return currentProcessId; }
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct CSwitch
-{
- // New thread ID after the switch.
- uint32 NewThreadId;
-
- // Previous thread ID.
- uint32 OldThreadId;
-
- // Thread priority of the new thread.
- int8 NewThreadPriority;
-
- // Thread priority of the previous thread.
- int8 OldThreadPriority;
-
- //The index of the C-state that was last used by the processor. A value of 0 represents the lightest idle state with higher values representing deeper C-states.
- uint8 PreviousCState;
-
- // Not used.
- int8 SpareByte;
-
- // Wait reason for the previous thread. The following are the possible values:
- // 0 Executive
- // 1 FreePage
- // 2 PageIn
- // 3 PoolAllocation
- // 4 DelayExecution
- // 5 Suspended
- // 6 UserRequest
- // 7 WrExecutive
- // 8 WrFreePage
- // 9 WrPageIn
- // 10 WrPoolAllocation
- // 11 WrDelayExecution
- // 12 WrSuspended
- // 13 WrUserRequest
- // 14 WrEventPair
- // 15 WrQueue
- // 16 WrLpcReceive
- // 17 WrLpcReply
- // 18 WrVirtualMemory
- // 19 WrPageOut
- // 20 WrRendezvous
- // 21 WrKeyedEvent
- // 22 WrTerminated
- // 23 WrProcessInSwap
- // 24 WrCpuRateControl
- // 25 WrCalloutStack
- // 26 WrKernel
- // 27 WrResource
- // 28 WrPushLock
- // 29 WrMutex
- // 30 WrQuantumEnd
- // 31 WrDispatchInt
- // 32 WrPreempted
- // 33 WrYieldExecution
- // 34 WrFastMutex
- // 35 WrGuardedMutex
- // 36 WrRundown
- // 37 MaximumWaitReason
- int8 OldThreadWaitReason;
-
- // Wait mode for the previous thread. The following are the possible values:
- // 0 KernelMode
- // 1 UserMode
- int8 OldThreadWaitMode;
-
- // State of the previous thread. The following are the possible state values:
- // 0 Initialized
- // 1 Ready
- // 2 Running
- // 3 Standby
- // 4 Terminated
- // 5 Waiting
- // 6 Transition
- // 7 DeferredReady (added for Windows Server 2003)
- int8 OldThreadState;
-
- // Ideal wait time of the previous thread.
- int8 OldThreadWaitIdealProcessor;
-
- // Wait time for the new thread.
- uint32 NewThreadWaitTime;
-
- // Reserved.
- uint32 Reserved;
-
- static const byte OPCODE = 36;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct StackWalk_Event
-{
- // Original event time stamp from the event header
- uint64 EventTimeStamp;
-
- // The process identifier of the original event
- uint32 StackProcess;
-
- // The thread identifier of the original event
- uint32 StackThread;
-
- // Callstack head
- uint64 Stack0;
-
- static const byte OPCODE = 32;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct Thread_TypeGroup1
-{
- // Process identifier of the thread involved in the event.
- uint32 ProcessId;
- // Thread identifier of the thread involved in the event.
- uint32 TThreadId;
- // Base address of the thread's stack.
- uint64 StackBase;
- // Limit of the thread's stack.
- uint64 StackLimit;
- // Base address of the thread's user-mode stack.
- uint64 UserStackBase;
- // Limit of the thread's user-mode stack.
- uint64 UserStackLimit;
- // The set of processors on which the thread is allowed to run.
- uint32 Affinity;
- // Starting address of the function to be executed by this thread.
- uint64 Win32StartAddr;
- // Thread environment block base address.
- uint64 TebBase;
- // Identifies the service if the thread is owned by a service; otherwise, zero.
- uint32 SubProcessTag;
- // The scheduler priority of the thread
- uint8 BasePriority;
- // A memory page priority hint for memory pages accessed by the thread.
- uint8 PagePriority;
- // An IO priority hint for scheduling IOs generated by the thread.
- uint8 IoPriority;
- // Not used.
- uint8 ThreadFlags;
-
- enum struct Opcode : uint8
- {
- Start = 1,
- End = 2,
- DCStart = 3,
- DCEnd = 4,
- };
-};
-
-size_t GetSIDSize(uint8* ptr)
-{
- size_t result = 0;
-
- int sid = *((int*)ptr);
-
- if (sid != 0)
- {
- size_t tokenSize = 16;
- ptr += tokenSize;
- result += tokenSize;
- result += 8 + (4 * ((SID*)ptr)->SubAuthorityCount);
- }
- else
- {
- result = 4;
- }
-
- return result;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// https://github.com/Microsoft/perfview/blob/688a8564062d51321bbab53cd71d9e174a77d2ce/src/TraceEvent/TraceEvent.cs
-struct Process_TypeGroup1
-{
- // The address of the process object in the kernel.
- uint64 UniqueProcessKey;
- // Global process identifier that you can use to identify a process.
- uint32 ProcessId;
- // Unique identifier of the process that creates this process.
- uint32 ParentId;
- // Unique identifier that an operating system generates when it creates a new session.
- uint32 SessionId;
- // Exit status of the stopped process.
- int32 ExitStatus;
- // The physical address of the page table of the process.
- uint64 DirectoryTableBase;
- // (?) uint8 Flags;
- // object UserSID;
- // string ImageFileName;
- // wstring CommandLine;
-
- static size_t GetSIDOffset(PEVENT_RECORD pEvent)
- {
- if (pEvent->EventHeader.EventDescriptor.Version >= 4)
- return 36;
-
- if (pEvent->EventHeader.EventDescriptor.Version == 3)
- return 32;
-
- return 24;
- }
-
- const char* GetProcessName(PEVENT_RECORD pEvent) const
- {
- OPTICK_ASSERT((pEvent->EventHeader.Flags & EVENT_HEADER_FLAG_64_BIT_HEADER) != 0, "32-bit is not supported! Disable OPTICK_ENABLE_TRACING on 32-bit platform if needed!");
- size_t sidOffset = GetSIDOffset(pEvent);
- size_t sidSize = GetSIDSize((uint8*)this + sidOffset);
- return (char*)this + sidOffset + sidSize;
- }
-
- enum struct Opcode
- {
- Start = 1,
- End = 2,
- DCStart = 3,
- DCEnd = 4,
- Defunct = 39,
- };
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct SampledProfile
-{
- uint32 InstructionPointer;
- uint32 ThreadId;
- uint32 Count;
-
- static const byte OPCODE = 46;
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct SysCallEnter
-{
- uintptr_t SysCallAddress;
-
- static const byte OPCODE = 51;
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct SysCallExit
-{
- uint32 SysCallNtStatus;
-
- static const byte OPCODE = 52;
-};
-
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// ce1dbfb4-137e-4da6-87b0-3f59aa102cbc
-DEFINE_GUID(SampledProfileGuid, 0xce1dbfb4, 0x137e, 0x4da6, 0x87, 0xb0, 0x3f, 0x59, 0xaa, 0x10, 0x2c, 0xbc);
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// 3d6fa8d1-fe05-11d0-9dda-00c04fd7ba7c
-// https://docs.microsoft.com/en-us/windows/desktop/etw/thread
-DEFINE_GUID(ThreadGuid, 0x3d6fa8d1, 0xfe05, 0x11d0, 0x9d, 0xda, 0x00, 0xc0, 0x4f, 0xd7, 0xba, 0x7c);
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// 3d6fa8d0-fe05-11d0-9dda-00c04fd7ba7c
-// https://docs.microsoft.com/en-us/windows/desktop/etw/process
-DEFINE_GUID(ProcessGuid, 0x3d6fa8d0, 0xfe05, 0x11d0, 0x9d, 0xda, 0x00, 0xc0, 0x4f, 0xd7, 0xba, 0x7c);
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-const int MAX_CPU_CORES = 256;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct ETWRuntime
-{
- array<ThreadID, MAX_CPU_CORES> activeCores;
- vector<std::pair<uint8_t, SysCallData*>> activeSyscalls;
-
- ETWRuntime()
- {
- Reset();
- }
-
- void Reset()
- {
- activeCores.fill(INVALID_THREAD_ID);
- activeSyscalls.resize(0);;
- }
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-ETWRuntime g_ETWRuntime;
-ETW g_ETW;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void WINAPI OnRecordEvent(PEVENT_RECORD eventRecord)
-{
- //static uint8 cpuCoreIsExecutingThreadFromOurProcess[256] = { 0 };
-
- const byte opcode = eventRecord->EventHeader.EventDescriptor.Opcode;
-
- if (opcode == CSwitch::OPCODE)
- {
- if (sizeof(CSwitch) == eventRecord->UserDataLength)
- {
- CSwitch* pSwitchEvent = (CSwitch*)eventRecord->UserData;
-
- SwitchContextDesc desc;
- desc.reason = pSwitchEvent->OldThreadWaitReason;
- desc.cpuId = eventRecord->BufferContext.ProcessorNumber;
- desc.oldThreadId = (uint64)pSwitchEvent->OldThreadId;
- desc.newThreadId = (uint64)pSwitchEvent->NewThreadId;
- desc.timestamp = eventRecord->EventHeader.TimeStamp.QuadPart;
- Core::Get().ReportSwitchContext(desc);
-
- // Assign ThreadID to the cores
- if (g_ETW.activeThreadsIDs.find(desc.newThreadId) != g_ETW.activeThreadsIDs.end())
- {
- g_ETWRuntime.activeCores[desc.cpuId] = desc.newThreadId;
- }
- else if (g_ETW.activeThreadsIDs.find(desc.oldThreadId) != g_ETW.activeThreadsIDs.end())
- {
- g_ETWRuntime.activeCores[desc.cpuId] = INVALID_THREAD_ID;
- }
- }
- }
- else if (opcode == StackWalk_Event::OPCODE)
- {
- if (eventRecord->UserData && eventRecord->UserDataLength >= sizeof(StackWalk_Event))
- {
- //TODO: Support x86 windows kernels
- const size_t osKernelPtrSize = sizeof(uint64);
-
- StackWalk_Event* pStackWalkEvent = (StackWalk_Event*)eventRecord->UserData;
- uint32 count = 1 + (eventRecord->UserDataLength - sizeof(StackWalk_Event)) / osKernelPtrSize;
-
- if (count && pStackWalkEvent->StackThread != 0)
- {
- if (pStackWalkEvent->StackProcess == g_ETW.GetProcessID())
- {
- CallstackDesc desc;
- desc.threadID = pStackWalkEvent->StackThread;
- desc.timestamp = pStackWalkEvent->EventTimeStamp;
-
- static_assert(osKernelPtrSize == sizeof(uint64), "Incompatible types!");
- desc.callstack = &pStackWalkEvent->Stack0;
-
- desc.count = (uint8)count;
- Core::Get().ReportStackWalk(desc);
- }
- }
- }
- }
- else if (opcode == SampledProfile::OPCODE)
- {
- SampledProfile* pEvent = (SampledProfile*)eventRecord->UserData;
- OPTICK_UNUSED(pEvent);
- }
- else if (opcode == SysCallEnter::OPCODE)
- {
- if (eventRecord->UserDataLength >= sizeof(SysCallEnter))
- {
- uint8_t cpuId = eventRecord->BufferContext.ProcessorNumber;
- uint64_t threadId = g_ETWRuntime.activeCores[cpuId];
-
- if (threadId != INVALID_THREAD_ID)
- {
- SysCallEnter* pEventEnter = (SysCallEnter*)eventRecord->UserData;
-
- SysCallData& sysCall = Core::Get().syscallCollector.Add();
- sysCall.start = eventRecord->EventHeader.TimeStamp.QuadPart;
- sysCall.finish = EventTime::INVALID_TIMESTAMP;
- sysCall.threadID = threadId;
- sysCall.id = pEventEnter->SysCallAddress;
- sysCall.description = nullptr;
-
- g_ETWRuntime.activeSyscalls.push_back(std::make_pair(cpuId, &sysCall));
- }
- }
- }
- else if (opcode == SysCallExit::OPCODE)
- {
- if (eventRecord->UserDataLength >= sizeof(SysCallExit))
- {
- uint8_t cpuId = eventRecord->BufferContext.ProcessorNumber;
- if (g_ETWRuntime.activeCores[cpuId] != INVALID_THREAD_ID)
- {
- for (int i = (int)g_ETWRuntime.activeSyscalls.size() - 1; i >= 0; --i)
- {
- if (g_ETWRuntime.activeSyscalls[i].first == cpuId)
- {
- g_ETWRuntime.activeSyscalls[i].second->finish = eventRecord->EventHeader.TimeStamp.QuadPart;
- g_ETWRuntime.activeSyscalls.erase(g_ETWRuntime.activeSyscalls.begin() + i);
- break;
- }
- }
- }
- }
- }
- else
- {
- // VS TODO: We might have a situation where a thread was deleted and the new thread was created with the same threadID
- // Ignoring for now - profiling sessions are quite short - not critical
- if (IsEqualGUID(eventRecord->EventHeader.ProviderId, ThreadGuid))
- {
- if (eventRecord->UserDataLength >= sizeof(Thread_TypeGroup1))
- {
- const Thread_TypeGroup1* pThreadEvent = (const Thread_TypeGroup1*)eventRecord->UserData;
- Core::Get().RegisterThreadDescription(ThreadDescription("", pThreadEvent->TThreadId, pThreadEvent->ProcessId, 1, pThreadEvent->BasePriority));
- }
-
- }
- else if (IsEqualGUID(eventRecord->EventHeader.ProviderId, ProcessGuid))
- {
- if (eventRecord->UserDataLength >= sizeof(Process_TypeGroup1))
- {
- const Process_TypeGroup1* pProcessEvent = (const Process_TypeGroup1*)eventRecord->UserData;
- Core::Get().RegisterProcessDescription(ProcessDescription(pProcessEvent->GetProcessName(eventRecord), pProcessEvent->ProcessId, pProcessEvent->UniqueProcessKey));
- }
- }
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-static ULONG WINAPI OnBufferRecord(_In_ PEVENT_TRACE_LOGFILE Buffer)
-{
- OPTICK_UNUSED(Buffer);
- return true;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-const TRACEHANDLE INVALID_TRACEHANDLE = (TRACEHANDLE)-1;
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-DWORD WINAPI ETW::RunProcessTraceThreadFunction(LPVOID parameter)
-{
- Core::Get().RegisterThreadDescription(ThreadDescription("[Optick] ETW", GetCurrentThreadId(), GetCurrentProcessId()));
- ETW* etw = (ETW*)parameter;
- ULONG status = ProcessTrace(&etw->openedHandle, 1, 0, 0);
- OPTICK_UNUSED(status);
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void ETW::AdjustPrivileges()
-{
-#if OPTICK_PC
- HANDLE token = 0;
- if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))
- {
- TOKEN_PRIVILEGES tokenPrivileges;
- memset(&tokenPrivileges, 0, sizeof(tokenPrivileges));
- tokenPrivileges.PrivilegeCount = 1;
- tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- LookupPrivilegeValue(NULL, SE_SYSTEM_PROFILE_NAME, &tokenPrivileges.Privileges[0].Luid);
-
- AdjustTokenPrivileges(token, FALSE, &tokenPrivileges, 0, (PTOKEN_PRIVILEGES)NULL, 0);
- CloseHandle(token);
- }
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void ETW::ResolveSysCalls()
-{
- if (SymbolEngine* symEngine = Platform::GetSymbolEngine())
- {
- Core::Get().syscallCollector.syscallPool.ForEach([this, symEngine](SysCallData& data)
- {
- auto it = syscallDescriptions.find(data.id);
- if (it == syscallDescriptions.end())
- {
- const Symbol* symbol = symEngine->GetSymbol(data.id);
- if (symbol != nullptr)
- {
- string name(symbol->function.begin(), symbol->function.end());
-
- data.description = EventDescription::CreateShared(name.c_str(), "SysCall", (long)data.id);
- syscallDescriptions.insert(std::pair<const uint64_t, const EventDescription *>(data.id, data.description));
- }
- }
- else
- {
- data.description = it->second;
- }
- });
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-ETW::ETW()
- : isActive(false)
- , traceSessionHandle(INVALID_TRACEHANDLE)
- , openedHandle(INVALID_TRACEHANDLE)
- , processThreadHandle(INVALID_HANDLE_VALUE)
- , traceProperties(nullptr)
-{
- currentProcessId = GetCurrentProcessId();
-}
-
-CaptureStatus::Type ETW::Start(Mode::Type mode, int frequency, const ThreadList& threads)
-{
- if (!isActive)
- {
- AdjustPrivileges();
-
- g_ETWRuntime.Reset();
-
- activeThreadsIDs.clear();
- for (auto it = threads.begin(); it != threads.end(); ++it)
- {
- ThreadEntry* entry = *it;
- if (entry->isAlive)
- {
- activeThreadsIDs.insert(entry->description.threadID);
- }
- }
-
-
- ULONG bufferSize = sizeof(EVENT_TRACE_PROPERTIES) + (ETW_MAXIMUM_SESSION_NAME + MAX_PATH) * sizeof(WCHAR);
- if (traceProperties == nullptr)
- traceProperties = (EVENT_TRACE_PROPERTIES*)Memory::Alloc(bufferSize);
- ZeroMemory(traceProperties, bufferSize);
- traceProperties->Wnode.BufferSize = bufferSize;
- traceProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
- StringCchCopyW((LPWSTR)((PCHAR)traceProperties + traceProperties->LoggerNameOffset), ETW_MAXIMUM_SESSION_NAME, KERNEL_LOGGER_NAMEW);
- traceProperties->EnableFlags = 0;
-
- traceProperties->BufferSize = ETW_BUFFER_SIZE;
- traceProperties->MinimumBuffers = ETW_BUFFER_COUNT;
-
- if (mode & Mode::SWITCH_CONTEXT)
- {
- traceProperties->EnableFlags |= EVENT_TRACE_FLAG_CSWITCH;
- }
-
- if (mode & Mode::AUTOSAMPLING)
- {
- traceProperties->EnableFlags |= EVENT_TRACE_FLAG_PROFILE;
- }
-
- if (mode & Mode::SYS_CALLS)
- {
- traceProperties->EnableFlags |= EVENT_TRACE_FLAG_SYSTEMCALL;
- }
-
- if (mode & Mode::OTHER_PROCESSES)
- {
- traceProperties->EnableFlags |= EVENT_TRACE_FLAG_PROCESS;
- traceProperties->EnableFlags |= EVENT_TRACE_FLAG_THREAD;
- }
-
- traceProperties->LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
- traceProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
- //
- // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364160(v=vs.85).aspx
- // Clock resolution = QPC
- traceProperties->Wnode.ClientContext = 1;
- traceProperties->Wnode.Guid = SystemTraceControlGuid;
-
- // ERROR_BAD_LENGTH(24): The Wnode.BufferSize member of Properties specifies an incorrect size. Properties does not have sufficient space allocated to hold a copy of SessionName.
- // ERROR_ALREADY_EXISTS(183): A session with the same name or GUID is already running.
- // ERROR_ACCESS_DENIED(5): Only users with administrative privileges, users in the Performance Log Users group, and services running as LocalSystem, LocalService, NetworkService can control event tracing sessions.
- // ERROR_INVALID_PARAMETER(87)
- // ERROR_BAD_PATHNAME(161)
- // ERROR_DISK_FULL(112)
- // ERROR_NO_SUCH_PRIVILEGE(1313)
- int retryCount = 4;
- ULONG status = CaptureStatus::OK;
-
- while (--retryCount >= 0)
- {
- status = StartTrace(&traceSessionHandle, KERNEL_LOGGER_NAME, traceProperties);
-
- switch (status)
- {
- case ERROR_NO_SUCH_PRIVILEGE:
- AdjustPrivileges();
- break;
-
- case ERROR_ALREADY_EXISTS:
- ControlTrace(0, KERNEL_LOGGER_NAME, traceProperties, EVENT_TRACE_CONTROL_STOP);
- break;
-
- case ERROR_ACCESS_DENIED:
- return CaptureStatus::ERR_TRACER_ACCESS_DENIED;
-
- case ERROR_SUCCESS:
- retryCount = 0;
- break;
-
- default:
- return CaptureStatus::ERR_TRACER_FAILED;
- }
- }
-
- if (status != ERROR_SUCCESS)
- {
- return CaptureStatus::ERR_TRACER_FAILED;
- }
-
- CLASSIC_EVENT_ID callstackSamples[4];
- int callstackCountSamplesCount = 0;
-
- if (mode & Mode::AUTOSAMPLING)
- {
- callstackSamples[callstackCountSamplesCount].EventGuid = SampledProfileGuid;
- callstackSamples[callstackCountSamplesCount].Type = SampledProfile::OPCODE;
- ++callstackCountSamplesCount;
- }
-
- if (mode & Mode::SYS_CALLS)
- {
- callstackSamples[callstackCountSamplesCount].EventGuid = SampledProfileGuid;
- callstackSamples[callstackCountSamplesCount].Type = SysCallEnter::OPCODE;
- ++callstackCountSamplesCount;
- }
-
- /*
- callstackSamples[callstackCountSamplesCount].EventGuid = CSwitchProfileGuid;
- callstackSamples[callstackCountSamplesCount].Type = CSwitch::OPCODE;
- ++callstackCountSamplesCount;
- */
-
-
- /*
- https://msdn.microsoft.com/en-us/library/windows/desktop/dd392328%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
- Typically, on 64-bit computers, you cannot capture the kernel stack in certain contexts when page faults are not allowed. To enable walking the kernel stack on x64, set
- the DisablePagingExecutive Memory Management registry value to 1. The DisablePagingExecutive registry value is located under the following registry key:
- HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management
- */
- if (callstackCountSamplesCount > 0)
- {
- status = TraceSetInformation(traceSessionHandle, TraceStackTracingInfo, &callstackSamples[0], sizeof(CLASSIC_EVENT_ID) * callstackCountSamplesCount);
- if (status != ERROR_SUCCESS)
- {
- OPTICK_FAILED("TraceSetInformation - failed");
- return CaptureStatus::ERR_TRACER_FAILED;
- }
- }
-
- if (mode & Mode::AUTOSAMPLING)
- {
- TRACE_PROFILE_INTERVAL itnerval = { 0 };
- memset(&itnerval, 0, sizeof(TRACE_PROFILE_INTERVAL));
- int step = 10000 * 1000 / frequency; // 1ms = 10000 steps
- itnerval.Interval = step; // std::max(1221, std::min(step, 10000));
- // The SessionHandle is irrelevant for this information class and must be zero, else the function returns ERROR_INVALID_PARAMETER.
- status = TraceSetInformation(0, TraceSampledProfileIntervalInfo, &itnerval, sizeof(TRACE_PROFILE_INTERVAL));
- OPTICK_ASSERT(status == ERROR_SUCCESS, "TraceSetInformation - failed");
- }
-
- ZeroMemory(&logFile, sizeof(EVENT_TRACE_LOGFILE));
- logFile.LoggerName = KERNEL_LOGGER_NAME;
- logFile.ProcessTraceMode = (PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD | PROCESS_TRACE_MODE_RAW_TIMESTAMP);
- logFile.EventRecordCallback = OnRecordEvent;
- logFile.BufferCallback = OnBufferRecord;
- openedHandle = OpenTrace(&logFile);
- if (openedHandle == INVALID_TRACEHANDLE)
- {
- OPTICK_FAILED("OpenTrace - failed");
- return CaptureStatus::ERR_TRACER_FAILED;
- }
-
- DWORD threadID;
- processThreadHandle = CreateThread(0, 0, RunProcessTraceThreadFunction, this, 0, &threadID);
-
- isActive = true;
- }
-
- return CaptureStatus::OK;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool ETW::Stop()
-{
- if (!isActive)
- {
- return false;
- }
-
- ULONG controlTraceResult = ControlTrace(openedHandle, KERNEL_LOGGER_NAME, traceProperties, EVENT_TRACE_CONTROL_STOP);
-
- // ERROR_CTX_CLOSE_PENDING(7007L): The call was successful. The ProcessTrace function will stop after it has processed all real-time events in its buffers (it will not receive any new events).
- // ERROR_BUSY(170L): Prior to Windows Vista, you cannot close the trace until the ProcessTrace function completes.
- // ERROR_INVALID_HANDLE(6L): One of the following is true: TraceHandle is NULL. TraceHandle is INVALID_HANDLE_VALUE.
- ULONG closeTraceStatus = CloseTrace(openedHandle);
-
- // Wait for ProcessThread to finish
- WaitForSingleObject(processThreadHandle, INFINITE);
- BOOL wasThreadClosed = CloseHandle(processThreadHandle);
-
- isActive = false;
-
- //VS TODO: Disabling resolving of the syscalls - we can't use then as EventDescriptions at the moment
- //ResolveSysCalls();
-
- activeThreadsIDs.clear();
-
- return wasThreadClosed && (closeTraceStatus == ERROR_SUCCESS) && (controlTraceResult == ERROR_SUCCESS);
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-ETW::~ETW()
-{
- Stop();
- Memory::Free(traceProperties);
- traceProperties = nullptr;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-Trace* Platform::GetTrace()
-{
- return &g_ETW;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Symbol Resolving
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-#define USE_DBG_HELP (OPTICK_PC)
-
-#if USE_DBG_HELP
-#include <DbgHelp.h>
-#pragma comment( lib, "DbgHelp.Lib" )
-#endif
-
-#include "optick_serialization.h"
-
-#if OPTICK_PC
-#include <psapi.h>
-#else
-// Forward declare kernel functions
-#pragma pack(push,8)
-typedef struct _MODULEINFO {
- LPVOID lpBaseOfDll;
- DWORD SizeOfImage;
- LPVOID EntryPoint;
-} MODULEINFO, *LPMODULEINFO;
-#pragma pack(pop)
-#ifndef EnumProcessModulesEx
-#define EnumProcessModulesEx K32EnumProcessModulesEx
-EXTERN_C DWORD WINAPI K32EnumProcessModulesEx(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded, DWORD dwFilterFlag);
-#endif
-#ifndef GetModuleInformation
-#define GetModuleInformation K32GetModuleInformation
-EXTERN_C DWORD WINAPI K32GetModuleInformation(HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb);
-#endif
-
-#ifndef GetModuleFileNameExA
-#define GetModuleFileNameExA K32GetModuleFileNameExA
-EXTERN_C DWORD WINAPI K32GetModuleFileNameExA(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize);
-#endif
-#endif
-
-namespace Optick
-{
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//void ReportLastError()
-//{
-// LPVOID lpMsgBuf;
-// DWORD dw = GetLastError();
-//
-// FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
-// NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-// (LPTSTR)&lpMsgBuf, 0, NULL);
-//
-// MessageBox(NULL, (LPCTSTR)lpMsgBuf, TEXT("Error"), MB_OK);
-// LocalFree(lpMsgBuf);
-//}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-typedef array<uintptr_t, 512> CallStackBuffer;
-typedef unordered_map<uint64, Symbol> SymbolCache;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-class WinSymbolEngine : public SymbolEngine
-{
- HANDLE hProcess;
-
- bool isInitialized;
-
- bool needRestorePreviousSettings;
- uint32 previousOptions;
- static const size_t MAX_SEARCH_PATH_LENGTH = 2048;
- char previousSearchPath[MAX_SEARCH_PATH_LENGTH];
-
- SymbolCache cache;
- vector<Module> modules;
-
- void InitSystemModules();
- void InitApplicationModules();
-public:
- WinSymbolEngine();
- ~WinSymbolEngine();
-
- void Init();
- void Close();
-
- // Get Symbol from PDB file
- virtual const Symbol * GetSymbol(uint64 dwAddress) override;
- virtual const vector<Module>& GetModules() override;
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-WinSymbolEngine::WinSymbolEngine() : isInitialized(false), hProcess(GetCurrentProcess()), needRestorePreviousSettings(false), previousOptions(0)
-{
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-WinSymbolEngine::~WinSymbolEngine()
-{
- Close();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-const Symbol* WinSymbolEngine::GetSymbol(uint64 address)
-{
- if (address == 0)
- return nullptr;
-
- Init();
-
- Symbol& symbol = cache[address];
-
- if (symbol.address != 0)
- return &symbol;
-
- if (!isInitialized)
- return nullptr;
-
- symbol.address = address;
-
-#if USE_DBG_HELP
- DWORD64 dwAddress = static_cast<DWORD64>(address);
-
- // FileName and Line
- IMAGEHLP_LINEW64 lineInfo;
- memset(&lineInfo, 0, sizeof(IMAGEHLP_LINEW64));
- lineInfo.SizeOfStruct = sizeof(lineInfo);
- DWORD dwDisp;
- if (SymGetLineFromAddrW64(hProcess, dwAddress, &dwDisp, &lineInfo))
- {
- symbol.file = lineInfo.FileName;
- symbol.line = lineInfo.LineNumber;
- }
-
- const size_t length = (sizeof(SYMBOL_INFOW) + MAX_SYM_NAME * sizeof(WCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64) + 1;
-
- // Function Name
- ULONG64 buffer[length];
- PSYMBOL_INFOW dbgSymbol = (PSYMBOL_INFOW)buffer;
- memset(dbgSymbol, 0, sizeof(buffer));
- dbgSymbol->SizeOfStruct = sizeof(SYMBOL_INFOW);
- dbgSymbol->MaxNameLen = MAX_SYM_NAME;
-
- DWORD64 offset = 0;
- if (SymFromAddrW(hProcess, dwAddress, &offset, dbgSymbol))
- {
- symbol.function.resize(dbgSymbol->NameLen);
- memcpy(&symbol.function[0], &dbgSymbol->Name[0], sizeof(WCHAR) * dbgSymbol->NameLen);
- }
-
- symbol.offset = static_cast<uintptr_t>(offset);
-#endif
-
- return &symbol;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-const vector<Module>& WinSymbolEngine::GetModules()
-{
- if (modules.empty())
- {
- InitSystemModules();
- InitApplicationModules();
- }
- return modules;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// const char* USER_SYMBOL_SEARCH_PATH = "http://msdl.microsoft.com/download/symbols";
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void WinSymbolEngine::Init()
-{
- if (!isInitialized)
- {
-#if USE_DBG_HELP
- previousOptions = SymGetOptions();
-
- memset(previousSearchPath, 0, MAX_SEARCH_PATH_LENGTH);
- SymGetSearchPath(hProcess, previousSearchPath, MAX_SEARCH_PATH_LENGTH);
-
- SymSetOptions(SymGetOptions() | SYMOPT_LOAD_LINES | SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME | SYMOPT_INCLUDE_32BIT_MODULES | SYMOPT_LOAD_ANYTHING);
- if (!SymInitialize(hProcess, NULL, TRUE))
- {
- needRestorePreviousSettings = true;
- SymCleanup(hProcess);
-
- if (SymInitialize(hProcess, NULL, TRUE))
- isInitialized = true;
- }
- else
- {
- isInitialized = true;
- }
-
- const vector<Module>& loadedModules = GetModules();
- for (size_t i = 0; i < loadedModules.size(); ++i)
- {
- const Module& module = loadedModules[i];
- SymLoadModule64(hProcess, NULL, module.path.c_str(), NULL, (DWORD64)module.address, (DWORD)module.size);
- }
-
-#else
- isInitialized = true;
-#endif
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-typedef DWORD(__stdcall *pZwQuerySystemInformation)(DWORD, LPVOID, DWORD, DWORD*);
-#define SystemModuleInformation 11 // SYSTEMINFOCLASS
-#define MAXIMUM_FILENAME_LENGTH 256
-
-struct SYSTEM_MODULE_INFORMATION
-{
- DWORD reserved1;
- DWORD reserved2;
- PVOID mappedBase;
- PVOID imageBase;
- DWORD imageSize;
- DWORD flags;
- WORD loadOrderIndex;
- WORD initOrderIndex;
- WORD loadCount;
- WORD moduleNameOffset;
- CHAR imageName[MAXIMUM_FILENAME_LENGTH];
-};
-
-#pragma warning (push)
-#pragma warning(disable : 4200)
-struct MODULE_LIST
-{
- DWORD dwModules;
- SYSTEM_MODULE_INFORMATION pModulesInfo[];
-};
-#pragma warning (pop)
-
-void WinSymbolEngine::InitSystemModules()
-{
- ULONG returnLength = 0;
- ULONG systemInformationLength = 0;
- MODULE_LIST* pModuleList = nullptr;
-
-#pragma warning (push)
-#pragma warning(disable : 4191)
- pZwQuerySystemInformation ZwQuerySystemInformation = (pZwQuerySystemInformation)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "ZwQuerySystemInformation");
-#pragma warning (pop)
-
- ZwQuerySystemInformation(SystemModuleInformation, pModuleList, systemInformationLength, &returnLength);
- systemInformationLength = returnLength;
- pModuleList = (MODULE_LIST*)Memory::Alloc(systemInformationLength);
- DWORD status = ZwQuerySystemInformation(SystemModuleInformation, pModuleList, systemInformationLength, &returnLength);
- if (status == ERROR_SUCCESS)
- {
- char systemRootPath[MAXIMUM_FILENAME_LENGTH] = { 0 };
-#if OPTICK_PC
- ExpandEnvironmentStringsA("%SystemRoot%", systemRootPath, MAXIMUM_FILENAME_LENGTH);
-#else
- strcpy_s(systemRootPath, "C:\\Windows");
-#endif
-
- const char* systemRootPattern = "\\SystemRoot";
-
- modules.reserve(modules.size() + pModuleList->dwModules);
-
- for (uint32_t i = 0; i < pModuleList->dwModules; ++i)
- {
- SYSTEM_MODULE_INFORMATION& module = pModuleList->pModulesInfo[i];
-
- char path[MAXIMUM_FILENAME_LENGTH] = { 0 };
-
- if (strstr(module.imageName, systemRootPattern) == module.imageName)
- {
- strcpy_s(path, systemRootPath);
- strcat_s(path, module.imageName + strlen(systemRootPattern));
- }
- else
- {
- strcpy_s(path, module.imageName);
- }
-
- modules.push_back(Module(path, (void*)module.imageBase, module.imageSize));
- }
- }
- else
- {
- OPTICK_FAILED("Can't query System Module Information!");
- }
-
- if (pModuleList)
- {
- Memory::Free(pModuleList);
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void WinSymbolEngine::InitApplicationModules()
-{
- HANDLE processHandle = GetCurrentProcess();
- HMODULE hModules[256];
- DWORD modulesSize = 0;
- EnumProcessModulesEx(processHandle, hModules, sizeof(hModules), &modulesSize, 0);
-
- int moduleCount = modulesSize / sizeof(HMODULE);
-
- modules.reserve(modules.size() + moduleCount);
-
- for (int i = 0; i < moduleCount; ++i)
- {
- MODULEINFO info = { 0 };
- if (GetModuleInformation(processHandle, hModules[i], &info, sizeof(MODULEINFO)))
- {
- char name[MAX_PATH] = "UnknownModule";
- GetModuleFileNameExA(processHandle, hModules[i], name, MAX_PATH);
-
- modules.push_back(Module(name, info.lpBaseOfDll, info.SizeOfImage));
- }
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void WinSymbolEngine::Close()
-{
- if (isInitialized)
- {
-#if USE_DBG_HELP
- SymCleanup(hProcess);
- if (needRestorePreviousSettings)
- {
- HANDLE currentProcess = GetCurrentProcess();
-
- SymSetOptions(previousOptions);
- SymSetSearchPath(currentProcess, previousSearchPath);
- SymInitialize(currentProcess, NULL, TRUE);
-
- needRestorePreviousSettings = false;
- }
-#endif
- modules.clear();
- isInitialized = false;
- }
-}
-//////////////////////////////////////////////////////////////////////////
-SymbolEngine* Platform::GetSymbolEngine()
-{
- static WinSymbolEngine pdbSymbolEngine;
- return &pdbSymbolEngine;
-}
-//////////////////////////////////////////////////////////////////////////
-}
-#endif //OPTICK_ENABLE_TRACING
-#endif //USE_OPTICK
-#endif //_MSC_VER \ No newline at end of file
diff --git a/external/optick/optick_gpu.cpp b/external/optick/optick_gpu.cpp
deleted file mode 100644
index d3610c3..0000000
--- a/external/optick/optick_gpu.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-#include "optick.config.h"
-
-#if USE_OPTICK
-#include "optick_gpu.h"
-#include "optick_core.h"
-#include "optick_memory.h"
-
-#include <thread>
-
-namespace Optick
-{
- static_assert((1ULL << 32) % GPUProfiler::MAX_QUERIES_COUNT == 0, "(1 << 32) should be a multiple of MAX_QUERIES_COUNT to handle query index overflow!");
-
-
- GPUProfiler::GPUProfiler() : currentState(STATE_OFF), currentNode(0), frameNumber(0)
- {
-
- }
-
- void GPUProfiler::InitNode(const char *nodeName, uint32_t nodeIndex)
- {
- Node* node = Memory::New<Node>();
- for (int i = 0; i < GPU_QUEUE_COUNT; ++i)
- {
- char name[128] = { 0 };
- sprintf_s(name, "%s [%s]", nodeName, GetGPUQueueName((GPUQueueType)i));
- node->gpuEventStorage[i] = RegisterStorage(name, uint64_t(-1), ThreadMask::GPU);
- node->name = nodeName;
- }
- nodes[nodeIndex] = node;
- }
-
- void GPUProfiler::Start(uint32 /*mode*/)
- {
- std::lock_guard<std::recursive_mutex> lock(updateLock);
- Reset();
- currentState = STATE_STARTING;
- }
-
- void GPUProfiler::Stop(uint32 /*mode*/)
- {
- std::lock_guard<std::recursive_mutex> lock(updateLock);
- currentState = STATE_OFF;
- }
-
- void GPUProfiler::Dump(uint32 /*mode*/)
- {
- for (size_t nodeIndex = 0; nodeIndex < nodes.size(); ++nodeIndex)
- {
- Node* node = nodes[nodeIndex];
-
- for (int queueIndex = 0; queueIndex < GPU_QUEUE_COUNT; ++queueIndex)
- {
- EventBuffer& gpuBuffer = node->gpuEventStorage[queueIndex]->eventBuffer;
-
- const vector<ThreadEntry*>& threads = Core::Get().GetThreads();
- for (size_t threadIndex = 0; threadIndex < threads.size(); ++threadIndex)
- {
- ThreadEntry* thread = threads[threadIndex];
- thread->storage.gpuStorage.gpuBuffer[nodeIndex][queueIndex].ForEachChunk([&gpuBuffer](const EventData* events, int count)
- {
- gpuBuffer.AddRange(events, count);
- });
- }
- }
- }
- }
-
- string GPUProfiler::GetName() const
- {
- return !nodes.empty() ? nodes[0]->name : string();
- }
-
- GPUProfiler::~GPUProfiler()
- {
- for (Node* node : nodes)
- Memory::Delete(node);
- nodes.clear();
- }
-
- void GPUProfiler::Reset()
- {
- for (uint32_t nodeIndex = 0; nodeIndex < nodes.size(); ++nodeIndex)
- {
- Node& node = *nodes[nodeIndex];
- node.Reset();
- node.clock = GetClockSynchronization(nodeIndex);
- }
- }
-
- EventData& GPUProfiler::AddFrameEvent()
- {
- static const EventDescription* GPUFrameDescription = EventDescription::Create("GPU Frame", __FILE__, __LINE__);
- EventData& event = nodes[currentNode]->gpuEventStorage[GPU_QUEUE_GRAPHICS]->eventBuffer.Add();
- event.description = GPUFrameDescription;
- event.start = EventTime::INVALID_TIMESTAMP;
- event.finish = EventTime::INVALID_TIMESTAMP;
- return event;
- }
-
- EventData& GPUProfiler::AddVSyncEvent()
- {
- static const EventDescription* VSyncDescription = EventDescription::Create("VSync", __FILE__, __LINE__);
- EventData& event = nodes[currentNode]->gpuEventStorage[GPU_QUEUE_VSYNC]->eventBuffer.Add();
- event.description = VSyncDescription;
- event.start = EventTime::INVALID_TIMESTAMP;
- event.finish = EventTime::INVALID_TIMESTAMP;
- return event;
- }
-
- TagData<uint32>& GPUProfiler::AddFrameTag()
- {
- static const EventDescription* FrameTagDescription = EventDescription::CreateShared("Frame");
- TagData<uint32>& tag = nodes[currentNode]->gpuEventStorage[GPU_QUEUE_GRAPHICS]->tagU32Buffer.Add();
- tag.description = FrameTagDescription;
- tag.timestamp = EventTime::INVALID_TIMESTAMP;
- tag.data = Core::Get().GetCurrentFrame();
- return tag;
- }
-
- const char * GetGPUQueueName(GPUQueueType queue)
- {
- const char* GPUQueueToName[GPU_QUEUE_COUNT] = { "Graphics", "Compute", "Transfer", "VSync" };
- return GPUQueueToName[queue];
- }
-
- void GPUProfiler::Node::Reset()
- {
- queryIndex = 0;
-
- for (size_t frameIndex = 0; frameIndex < queryGpuframes.size(); ++frameIndex)
- queryGpuframes[frameIndex].Reset();
- }
-}
-#endif //USE_OPTICK
-
diff --git a/external/optick/optick_gpu.d3d12.cpp b/external/optick/optick_gpu.d3d12.cpp
deleted file mode 100644
index 1ee4dd9..0000000
--- a/external/optick/optick_gpu.d3d12.cpp
+++ /dev/null
@@ -1,382 +0,0 @@
-#include "optick.config.h"
-#if USE_OPTICK
-#if OPTICK_ENABLE_GPU_D3D12
-
-#include "optick_common.h"
-#include "optick_memory.h"
-#include "optick_core.h"
-#include "optick_gpu.h"
-
-#include <atomic>
-#include <thread>
-
-#include <d3d12.h>
-#include <dxgi.h>
-#include <dxgi1_4.h>
-
-
-#define OPTICK_CHECK(args) do { HRESULT __hr = args; (void)__hr; OPTICK_ASSERT(__hr == S_OK, "Failed check"); } while(false);
-
-namespace Optick
-{
- class GPUProfilerD3D12 : public GPUProfiler
- {
- struct Frame
- {
- ID3D12CommandAllocator* commandAllocator;
- ID3D12GraphicsCommandList* commandList;
-
- Frame() : commandAllocator(nullptr), commandList(nullptr)
- {
- Reset();
- }
-
- void Reset()
- {
- }
-
- void Shutdown();
-
- ~Frame()
- {
- Shutdown();
- }
- };
-
- struct NodePayload
- {
- ID3D12CommandQueue* commandQueue;
- ID3D12QueryHeap* queryHeap;
- ID3D12Fence* syncFence;
- array<Frame, NUM_FRAMES_DELAY> frames;
-
- NodePayload() : commandQueue(nullptr), queryHeap(nullptr), syncFence(nullptr) {}
- ~NodePayload();
- };
- vector<NodePayload*> nodePayloads;
-
- ID3D12Resource* queryBuffer;
- ID3D12Device* device;
-
- // VSync Stats
- DXGI_FRAME_STATISTICS prevFrameStatistics;
-
- //void UpdateRange(uint32_t start, uint32_t finish)
- void InitNodeInternal(const char* nodeName, uint32_t nodeIndex, ID3D12CommandQueue* pCmdQueue);
-
- void ResolveTimestamps(uint32_t startIndex, uint32_t count);
-
- void WaitForFrame(uint64_t frameNumber);
-
- public:
- GPUProfilerD3D12();
- ~GPUProfilerD3D12();
-
- void InitDevice(ID3D12Device* pDevice, ID3D12CommandQueue** pCommandQueues, uint32_t numCommandQueues);
-
- void QueryTimestamp(ID3D12GraphicsCommandList* context, int64_t* outCpuTimestamp);
-
- void Flip(IDXGISwapChain* swapChain);
-
-
- // Interface implementation
- ClockSynchronization GetClockSynchronization(uint32_t nodeIndex) override;
-
- void QueryTimestamp(void* context, int64_t* outCpuTimestamp) override
- {
- QueryTimestamp((ID3D12GraphicsCommandList*)context, outCpuTimestamp);
- }
-
- void Flip(void* swapChain) override
- {
- Flip(static_cast<IDXGISwapChain*>(swapChain));
- }
- };
-
- template <class T> void SafeRelease(T **ppT)
- {
- if (*ppT)
- {
- (*ppT)->Release();
- *ppT = NULL;
- }
- }
-
- void InitGpuD3D12(void* device, void** cmdQueues, uint32_t numQueues)
- {
- GPUProfilerD3D12* gpuProfiler = Memory::New<GPUProfilerD3D12>();
- gpuProfiler->InitDevice((ID3D12Device*)device, (ID3D12CommandQueue**)cmdQueues, numQueues);
- Core::Get().InitGPUProfiler(gpuProfiler);
- }
-
- GPUProfilerD3D12::GPUProfilerD3D12() : queryBuffer(nullptr), device(nullptr)
- {
- prevFrameStatistics = { 0 };
- }
-
- GPUProfilerD3D12::~GPUProfilerD3D12()
- {
- WaitForFrame(frameNumber - 1);
-
- for (NodePayload* payload : nodePayloads)
- Memory::Delete(payload);
- nodePayloads.clear();
-
- for (Node* node : nodes)
- Memory::Delete(node);
- nodes.clear();
-
- SafeRelease(&queryBuffer);
- }
-
- void GPUProfilerD3D12::InitDevice(ID3D12Device* pDevice, ID3D12CommandQueue** pCommandQueues, uint32_t numCommandQueues)
- {
- device = pDevice;
-
- uint32_t nodeCount = numCommandQueues; // device->GetNodeCount();
-
- nodes.resize(nodeCount);
- nodePayloads.resize(nodeCount);
-
- D3D12_HEAP_PROPERTIES heapDesc;
- heapDesc.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
- heapDesc.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
- heapDesc.CreationNodeMask = 0;
- heapDesc.VisibleNodeMask = (1u << nodeCount) - 1u;
- heapDesc.Type = D3D12_HEAP_TYPE_READBACK;
-
- D3D12_RESOURCE_DESC resourceDesc;
- resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
- resourceDesc.Alignment = 0;
- resourceDesc.Width = MAX_QUERIES_COUNT * sizeof(int64_t);
- resourceDesc.Height = 1;
- resourceDesc.DepthOrArraySize = 1;
- resourceDesc.MipLevels = 1;
- resourceDesc.Format = DXGI_FORMAT_UNKNOWN;
- resourceDesc.SampleDesc.Count = 1;
- resourceDesc.SampleDesc.Quality = 0;
- resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
- resourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
-
- OPTICK_CHECK(device->CreateCommittedResource(
- &heapDesc,
- D3D12_HEAP_FLAG_NONE,
- &resourceDesc,
- D3D12_RESOURCE_STATE_COPY_DEST,
- nullptr,
- IID_PPV_ARGS(&queryBuffer)));
-
- // Get Device Name
- LUID adapterLUID = pDevice->GetAdapterLuid();
-
- IDXGIFactory4* factory;
- OPTICK_CHECK(CreateDXGIFactory2(0, IID_PPV_ARGS(&factory)));
-
- IDXGIAdapter1* adapter;
- factory->EnumAdapterByLuid(adapterLUID, IID_PPV_ARGS(&adapter));
-
- DXGI_ADAPTER_DESC1 desc;
- adapter->GetDesc1(&desc);
-
- adapter->Release();
- factory->Release();
-
- char deviceName[128] = { 0 };
- wcstombs_s(deviceName, desc.Description, OPTICK_ARRAY_SIZE(deviceName) - 1);
-
- for (uint32_t nodeIndex = 0; nodeIndex < nodeCount; ++nodeIndex)
- InitNodeInternal(deviceName, nodeIndex, pCommandQueues[nodeIndex]);
- }
-
- void GPUProfilerD3D12::InitNodeInternal(const char* nodeName, uint32_t nodeIndex, ID3D12CommandQueue* pCmdQueue)
- {
- GPUProfiler::InitNode(nodeName, nodeIndex);
-
- NodePayload* node = Memory::New<NodePayload>();
- nodePayloads[nodeIndex] = node;
- node->commandQueue = pCmdQueue;
-
- D3D12_QUERY_HEAP_DESC queryHeapDesc;
- queryHeapDesc.Count = MAX_QUERIES_COUNT;
- queryHeapDesc.Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP;
- queryHeapDesc.NodeMask = 1u << nodeIndex;
- OPTICK_CHECK(device->CreateQueryHeap(&queryHeapDesc, IID_PPV_ARGS(&node->queryHeap)));
-
- OPTICK_CHECK(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&node->syncFence)));
-
- for (Frame& frame : node->frames)
- {
- OPTICK_CHECK(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&frame.commandAllocator)));
- OPTICK_CHECK(device->CreateCommandList(1u << nodeIndex, D3D12_COMMAND_LIST_TYPE_DIRECT, frame.commandAllocator, nullptr, IID_PPV_ARGS(&frame.commandList)));
- OPTICK_CHECK(frame.commandList->Close());
- }
- }
-
- void GPUProfilerD3D12::QueryTimestamp(ID3D12GraphicsCommandList* context, int64_t* outCpuTimestamp)
- {
- if (currentState == STATE_RUNNING)
- {
- uint32_t index = nodes[currentNode]->QueryTimestamp(outCpuTimestamp);
- context->EndQuery(nodePayloads[currentNode]->queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, index);
- }
- }
-
- void GPUProfilerD3D12::ResolveTimestamps(uint32_t startIndex, uint32_t count)
- {
- if (count)
- {
- Node* node = nodes[currentNode];
-
- D3D12_RANGE range = { sizeof(uint64_t)*startIndex, sizeof(uint64_t)*(startIndex + count) };
- void* pData = nullptr;
- queryBuffer->Map(0, &range, &pData);
- memcpy(&node->queryGpuTimestamps[startIndex], (uint64_t*)pData + startIndex, sizeof(uint64_t) * count);
- queryBuffer->Unmap(0, 0);
-
- // Convert GPU timestamps => CPU Timestamps
- for (uint32_t index = startIndex; index < startIndex + count; ++index)
- *node->queryCpuTimestamps[index] = node->clock.GetCPUTimestamp(node->queryGpuTimestamps[index]);
- }
- }
-
- void GPUProfilerD3D12::WaitForFrame(uint64_t frameNumberToWait)
- {
- OPTICK_EVENT();
-
- NodePayload* payload = nodePayloads[currentNode];
- while (frameNumberToWait > payload->syncFence->GetCompletedValue())
- {
- std::this_thread::sleep_for(std::chrono::milliseconds(1));
- }
- }
-
- void GPUProfilerD3D12::Flip(IDXGISwapChain* swapChain)
- {
- OPTICK_CATEGORY("GPUProfilerD3D12::Flip", Category::Debug);
-
- std::lock_guard<std::recursive_mutex> lock(updateLock);
-
- if (currentState == STATE_STARTING)
- currentState = STATE_RUNNING;
-
- if (currentState == STATE_RUNNING)
- {
- Node& node = *nodes[currentNode];
- NodePayload& payload = *nodePayloads[currentNode];
-
- uint32_t currentFrameIndex = frameNumber % NUM_FRAMES_DELAY;
- uint32_t nextFrameIndex = (frameNumber + 1) % NUM_FRAMES_DELAY;
-
- //Frame& currentFrame = frames[frameNumber % NUM_FRAMES_DELAY];
- //Frame& nextFrame = frames[(frameNumber + 1) % NUM_FRAMES_DELAY];
-
- QueryFrame& currentFrame = node.queryGpuframes[currentFrameIndex];
- QueryFrame& nextFrame = node.queryGpuframes[nextFrameIndex];
-
- ID3D12GraphicsCommandList* commandList = payload.frames[currentFrameIndex].commandList;
- ID3D12CommandAllocator* commandAllocator = payload.frames[currentFrameIndex].commandAllocator;
- commandAllocator->Reset();
- commandList->Reset(commandAllocator, nullptr);
-
- if (EventData* frameEvent = currentFrame.frameEvent)
- QueryTimestamp(commandList, &frameEvent->finish);
-
- // Generate GPU Frame event for the next frame
- EventData& event = AddFrameEvent();
- QueryTimestamp(commandList, &event.start);
- QueryTimestamp(commandList, &AddFrameTag().timestamp);
- nextFrame.frameEvent = &event;
-
- uint32_t queryBegin = currentFrame.queryIndexStart;
- uint32_t queryEnd = node.queryIndex;
-
- if (queryBegin != (uint32_t)-1)
- {
- OPTICK_ASSERT(queryEnd - queryBegin <= MAX_QUERIES_COUNT, "Too many queries in one frame? Increase GPUProfiler::MAX_QUERIES_COUNT to fix the problem!");
- currentFrame.queryIndexCount = queryEnd - queryBegin;
-
- uint32_t startIndex = queryBegin % MAX_QUERIES_COUNT;
- uint32_t finishIndex = queryEnd % MAX_QUERIES_COUNT;
-
- if (startIndex < finishIndex)
- {
- commandList->ResolveQueryData(payload.queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, startIndex, queryEnd - queryBegin, queryBuffer, startIndex * sizeof(int64_t));
- }
- else
- {
- commandList->ResolveQueryData(payload.queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, startIndex, MAX_QUERIES_COUNT - startIndex, queryBuffer, startIndex * sizeof(int64_t));
- commandList->ResolveQueryData(payload.queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, 0, finishIndex, queryBuffer, 0);
- }
- }
-
- commandList->Close();
-
- payload.commandQueue->ExecuteCommandLists(1, (ID3D12CommandList*const*)&commandList);
- payload.commandQueue->Signal(payload.syncFence, frameNumber);
-
- // Preparing Next Frame
- // Try resolve timestamps for the current frame
- if (frameNumber >= NUM_FRAMES_DELAY && nextFrame.queryIndexCount)
- {
- WaitForFrame(frameNumber + 1 - NUM_FRAMES_DELAY);
-
- uint32_t resolveStart = nextFrame.queryIndexStart % MAX_QUERIES_COUNT;
- uint32_t resolveFinish = resolveStart + nextFrame.queryIndexCount;
- ResolveTimestamps(resolveStart, std::min<uint32_t>(resolveFinish, MAX_QUERIES_COUNT) - resolveStart);
- if (resolveFinish > MAX_QUERIES_COUNT)
- ResolveTimestamps(0, resolveFinish - MAX_QUERIES_COUNT);
- }
-
- nextFrame.queryIndexStart = queryEnd;
- nextFrame.queryIndexCount = 0;
-
- // Process VSync
- DXGI_FRAME_STATISTICS currentFrameStatistics = { 0 };
- HRESULT result = swapChain->GetFrameStatistics(&currentFrameStatistics);
- if ((result == S_OK) && (prevFrameStatistics.PresentCount + 1 == currentFrameStatistics.PresentCount))
- {
- EventData& data = AddVSyncEvent();
- data.start = prevFrameStatistics.SyncQPCTime.QuadPart;
- data.finish = currentFrameStatistics.SyncQPCTime.QuadPart;
- }
- prevFrameStatistics = currentFrameStatistics;
- }
-
- ++frameNumber;
- }
-
- GPUProfiler::ClockSynchronization GPUProfilerD3D12::GetClockSynchronization(uint32_t nodeIndex)
- {
- ClockSynchronization clock;
- clock.frequencyCPU = GetHighPrecisionFrequency();
- nodePayloads[nodeIndex]->commandQueue->GetTimestampFrequency((uint64_t*)&clock.frequencyGPU);
- nodePayloads[nodeIndex]->commandQueue->GetClockCalibration((uint64_t*)&clock.timestampGPU, (uint64_t*)&clock.timestampCPU);
- return clock;
- }
-
- GPUProfilerD3D12::NodePayload::~NodePayload()
- {
- SafeRelease(&queryHeap);
- SafeRelease(&syncFence);
- }
-
- void GPUProfilerD3D12::Frame::Shutdown()
- {
- SafeRelease(&commandAllocator);
- SafeRelease(&commandList);
- }
-}
-
-#else
-#include "optick_common.h"
-
-namespace Optick
-{
- void InitGpuD3D12(void* /*device*/, void** /*cmdQueues*/, uint32_t /*numQueues*/)
- {
- OPTICK_FAILED("OPTICK_ENABLE_GPU_D3D12 is disabled! Can't initialize GPU Profiler!");
- }
-}
-
-#endif //OPTICK_ENABLE_GPU_D3D12
-#endif //USE_OPTICK \ No newline at end of file
diff --git a/external/optick/optick_gpu.h b/external/optick/optick_gpu.h
deleted file mode 100644
index f028f8a..0000000
--- a/external/optick/optick_gpu.h
+++ /dev/null
@@ -1,129 +0,0 @@
-#pragma once
-#include "optick.config.h"
-
-#if USE_OPTICK
-
-#include <atomic>
-#include <mutex>
-
-#include "optick_common.h"
-#include "optick_memory.h"
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-namespace Optick
-{
- const char* GetGPUQueueName(GPUQueueType queue);
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- class GPUProfiler
- {
- public:
- static const int MAX_FRAME_EVENTS = 1024;
- static const int NUM_FRAMES_DELAY = 4;
- static const int MAX_QUERIES_COUNT = (2 * MAX_FRAME_EVENTS) * NUM_FRAMES_DELAY;
- protected:
-
- enum State
- {
- STATE_OFF,
- STATE_STARTING,
- STATE_RUNNING,
- STATE_FINISHING,
- };
-
- struct ClockSynchronization
- {
- int64_t frequencyCPU;
- int64_t frequencyGPU;
- int64_t timestampCPU;
- int64_t timestampGPU;
-
- int64_t GetCPUTimestamp(int64_t gpuTimestamp)
- {
- return timestampCPU + (gpuTimestamp - timestampGPU) * frequencyCPU / frequencyGPU;
- }
-
- ClockSynchronization() : frequencyCPU(0), frequencyGPU(0), timestampCPU(0), timestampGPU(0) {}
- };
-
- struct QueryFrame
- {
- EventData* frameEvent;
- uint32_t queryIndexStart;
- uint32_t queryIndexCount;
-
- QueryFrame()
- {
- Reset();
- }
-
- void Reset()
- {
- frameEvent = nullptr;
- queryIndexStart = (uint32_t)-1;
- queryIndexCount = 0;
- }
- };
-
- struct Node
- {
- array<QueryFrame, NUM_FRAMES_DELAY> queryGpuframes;
- array<int64_t, MAX_QUERIES_COUNT> queryGpuTimestamps;
- array<int64_t*, MAX_QUERIES_COUNT> queryCpuTimestamps;
- std::atomic<uint32_t> queryIndex;
-
- ClockSynchronization clock;
-
- array<EventStorage*, GPU_QUEUE_COUNT> gpuEventStorage;
-
- uint32_t QueryTimestamp(int64_t* outCpuTimestamp)
- {
- uint32_t index = queryIndex.fetch_add(1) % MAX_QUERIES_COUNT;
- queryCpuTimestamps[index] = outCpuTimestamp;
- return index;
- }
-
- string name;
-
- void Reset();
-
- Node() : queryIndex(0) { gpuEventStorage.fill(nullptr); }
- };
-
- std::recursive_mutex updateLock;
- volatile State currentState;
-
- vector<Node*> nodes;
- uint32_t currentNode;
-
- uint32_t frameNumber;
-
- void Reset();
-
- EventData& AddFrameEvent();
- EventData& AddVSyncEvent();
- TagData<uint32>& AddFrameTag();
-
- public:
- GPUProfiler();
-
- // Init
- virtual void InitNode(const char* nodeName, uint32_t nodeIndex);
-
- // Capture Controls
- virtual void Start(uint32 mode);
- virtual void Stop(uint32 mode);
- virtual void Dump(uint32 mode);
-
- virtual string GetName() const;
-
- // Interface to implement
- virtual ClockSynchronization GetClockSynchronization(uint32_t nodeIndex) = 0;
- virtual void QueryTimestamp(void* context, int64_t* cpuTimestampOut) = 0;
- virtual void Flip(void* swapChain) = 0;
-
- virtual ~GPUProfiler();
- };
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-}
-
-#endif //USE_OPTICK
diff --git a/external/optick/optick_gpu.vulkan.cpp b/external/optick/optick_gpu.vulkan.cpp
deleted file mode 100644
index 6d6f29d..0000000
--- a/external/optick/optick_gpu.vulkan.cpp
+++ /dev/null
@@ -1,365 +0,0 @@
-#include "optick.config.h"
-
-#if USE_OPTICK
-#if OPTICK_ENABLE_GPU_VULKAN
-#include <vulkan/vulkan.h>
-
-#include "optick_core.h"
-#include "optick_gpu.h"
-
-#define OPTICK_VK_CHECK(args) do { VkResult __hr = args; OPTICK_ASSERT(__hr == VK_SUCCESS, "Failed check"); (void)__hr; } while(false);
-
-namespace Optick
-{
- class GPUProfilerVulkan : public GPUProfiler
- {
- protected:
- struct Frame
- {
- VkCommandBuffer commandBuffer;
- VkFence fence;
- Frame() : commandBuffer(VK_NULL_HANDLE), fence(VK_NULL_HANDLE) {}
- };
-
- struct NodePayload
- {
- VkDevice device;
- VkPhysicalDevice physicalDevice;
- VkQueue queue;
- VkQueryPool queryPool;
- VkCommandPool commandPool;
-
- array<Frame, NUM_FRAMES_DELAY> frames;
-
- NodePayload() : device(VK_NULL_HANDLE), physicalDevice(VK_NULL_HANDLE), queue(VK_NULL_HANDLE), queryPool(VK_NULL_HANDLE), commandPool(VK_NULL_HANDLE) {}
- ~NodePayload();
- };
- vector<NodePayload*> nodePayloads;
-
- void ResolveTimestamps(VkCommandBuffer commandBuffer, uint32_t startIndex, uint32_t count);
- void WaitForFrame(uint64_t frameNumber);
-
- public:
- GPUProfilerVulkan();
- ~GPUProfilerVulkan();
-
- void InitDevice(VkDevice* devices, VkPhysicalDevice* physicalDevices, VkQueue* cmdQueues, uint32_t* cmdQueuesFamily, uint32_t nodeCount);
- void QueryTimestamp(VkCommandBuffer commandBuffer, int64_t* outCpuTimestamp);
-
-
- // Interface implementation
- ClockSynchronization GetClockSynchronization(uint32_t nodeIndex) override;
-
- void QueryTimestamp(void* context, int64_t* outCpuTimestamp) override
- {
- QueryTimestamp((VkCommandBuffer)context, outCpuTimestamp);
- }
-
- void Flip(void* swapChain) override;
- };
-
- void InitGpuVulkan(void* vkDevices, void* vkPhysicalDevices, void* vkQueues, uint32_t* cmdQueuesFamily, uint32_t numQueues)
- {
- GPUProfilerVulkan* gpuProfiler = Memory::New<GPUProfilerVulkan>();
- gpuProfiler->InitDevice((VkDevice*)vkDevices, (VkPhysicalDevice*)vkPhysicalDevices, (VkQueue*)vkQueues, cmdQueuesFamily, numQueues);
- Core::Get().InitGPUProfiler(gpuProfiler);
- }
-
- GPUProfilerVulkan::GPUProfilerVulkan()
- {
- }
-
- void GPUProfilerVulkan::InitDevice(VkDevice* devices, VkPhysicalDevice* physicalDevices, VkQueue* cmdQueues, uint32_t* cmdQueuesFamily, uint32_t nodeCount)
- {
- VkQueryPoolCreateInfo queryPoolCreateInfo;
- queryPoolCreateInfo.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
- queryPoolCreateInfo.pNext = 0;
- queryPoolCreateInfo.flags = 0;
- queryPoolCreateInfo.queryType = VK_QUERY_TYPE_TIMESTAMP;
- queryPoolCreateInfo.queryCount = MAX_QUERIES_COUNT + 1;
-
- VkCommandPoolCreateInfo commandPoolCreateInfo;
- commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
- commandPoolCreateInfo.pNext = 0;
- commandPoolCreateInfo.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
-
- nodes.resize(nodeCount);
- nodePayloads.resize(nodeCount);
-
- VkResult r;
- for (uint32_t i = 0; i < nodeCount; ++i)
- {
- VkPhysicalDeviceProperties properties = { 0 };
- vkGetPhysicalDeviceProperties(physicalDevices[i], &properties);
- GPUProfiler::InitNode(properties.deviceName, i);
-
- NodePayload* nodePayload = Memory::New<NodePayload>();
- nodePayloads[i] = nodePayload;
- nodePayload->device = devices[i];
- nodePayload->physicalDevice = physicalDevices[i];
- nodePayload->queue = cmdQueues[i];
-
- r = vkCreateQueryPool(devices[i], &queryPoolCreateInfo, 0, &nodePayload->queryPool);
- OPTICK_ASSERT(r == VK_SUCCESS, "Failed");
-
- commandPoolCreateInfo.queueFamilyIndex = cmdQueuesFamily[i];
- r = vkCreateCommandPool(nodePayload->device, &commandPoolCreateInfo, 0, &nodePayload->commandPool);
- OPTICK_ASSERT(r == VK_SUCCESS, "Failed");
-
- for (uint32_t j = 0; j < nodePayload->frames.size(); ++j)
- {
- Frame& frame = nodePayload->frames[j];
-
- VkCommandBufferAllocateInfo allocInfo;
- allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
- allocInfo.pNext = 0;
- allocInfo.commandBufferCount = 1;
- allocInfo.commandPool = nodePayload->commandPool;
- allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
- r = vkAllocateCommandBuffers(nodePayload->device, &allocInfo, &frame.commandBuffer);
- OPTICK_ASSERT(r == VK_SUCCESS, "Failed");
-
- VkFenceCreateInfo fenceCreateInfo;
- fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
- fenceCreateInfo.pNext = 0;
- fenceCreateInfo.flags = j == 0 ? 0 : VK_FENCE_CREATE_SIGNALED_BIT;
- r = vkCreateFence(nodePayload->device, &fenceCreateInfo, 0, &frame.fence);
- OPTICK_ASSERT(r == VK_SUCCESS, "Failed");
- if (j == 0)
- {
- VkCommandBufferBeginInfo commandBufferBeginInfo;
- commandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
- commandBufferBeginInfo.pNext = 0;
- commandBufferBeginInfo.pInheritanceInfo = 0;
- commandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
- vkBeginCommandBuffer(frame.commandBuffer, &commandBufferBeginInfo);
- vkCmdResetQueryPool(frame.commandBuffer, nodePayload->queryPool, 0, MAX_QUERIES_COUNT);
- vkEndCommandBuffer(frame.commandBuffer);
-
- VkSubmitInfo submitInfo = {};
- submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
- submitInfo.pNext = nullptr;
- submitInfo.waitSemaphoreCount = 0;
- submitInfo.pWaitSemaphores = nullptr;
- submitInfo.commandBufferCount = 1;
- submitInfo.pCommandBuffers = &frame.commandBuffer;
- submitInfo.signalSemaphoreCount = 0;
- submitInfo.pSignalSemaphores = nullptr;
- vkQueueSubmit(nodePayload->queue, 1, &submitInfo, frame.fence);
- vkWaitForFences(nodePayload->device, 1, &frame.fence, 1, (uint64_t)-1);
- vkResetCommandBuffer(frame.commandBuffer, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
- }
- }
- }
- }
-
- void GPUProfilerVulkan::QueryTimestamp(VkCommandBuffer commandBuffer, int64_t* outCpuTimestamp)
- {
- if (currentState == STATE_RUNNING)
- {
- uint32_t index = nodes[currentNode]->QueryTimestamp(outCpuTimestamp);
- vkCmdWriteTimestamp(commandBuffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, nodePayloads[currentNode]->queryPool, index);
- }
- }
-
- void GPUProfilerVulkan::ResolveTimestamps(VkCommandBuffer commandBuffer, uint32_t startIndex, uint32_t count)
- {
- if (count)
- {
- Node* node = nodes[currentNode];
-
- NodePayload* payload = nodePayloads[currentNode];
-
- OPTICK_VK_CHECK(vkGetQueryPoolResults(payload->device, payload->queryPool, startIndex, count, 8 * count, &nodes[currentNode]->queryGpuTimestamps[startIndex], 8, VK_QUERY_RESULT_64_BIT));
- vkCmdResetQueryPool(commandBuffer, payload->queryPool, startIndex, count);
-
- // Convert GPU timestamps => CPU Timestamps
- for (uint32_t index = startIndex; index < startIndex + count; ++index)
- *node->queryCpuTimestamps[index] = node->clock.GetCPUTimestamp(node->queryGpuTimestamps[index]);
- }
- }
-
- void GPUProfilerVulkan::WaitForFrame(uint64_t frameNumberToWait)
- {
- OPTICK_EVENT();
-
- int r = VK_SUCCESS;
- do
- {
- NodePayload& payload = *nodePayloads[currentNode];
- r = vkWaitForFences(nodePayloads[currentNode]->device, 1, &payload.frames[frameNumberToWait % payload.frames.size()].fence, 1, 1000 * 30);
- } while (r != VK_SUCCESS);
- }
-
- void GPUProfilerVulkan::Flip(void* /*swapChain*/)
- {
- OPTICK_CATEGORY("GPUProfilerVulkan::Flip", Category::Debug);
-
- std::lock_guard<std::recursive_mutex> lock(updateLock);
-
- if (currentState == STATE_STARTING)
- currentState = STATE_RUNNING;
-
- if (currentState == STATE_RUNNING)
- {
- Node& node = *nodes[currentNode];
- NodePayload& payload = *nodePayloads[currentNode];
-
- uint32_t currentFrameIndex = frameNumber % NUM_FRAMES_DELAY;
- uint32_t nextFrameIndex = (frameNumber + 1) % NUM_FRAMES_DELAY;
-
- QueryFrame& currentFrame = node.queryGpuframes[currentFrameIndex];
- QueryFrame& nextFrame = node.queryGpuframes[nextFrameIndex];
-
- VkCommandBuffer commandBuffer = payload.frames[currentFrameIndex].commandBuffer;
- VkFence fence = payload.frames[currentFrameIndex].fence;
- VkDevice device = payload.device;
- VkQueue queue = payload.queue;
-
- vkWaitForFences(device, 1, &fence, 1, (uint64_t)-1);
-
- VkCommandBufferBeginInfo commandBufferBeginInfo;
- commandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
- commandBufferBeginInfo.pNext = 0;
- commandBufferBeginInfo.pInheritanceInfo = 0;
- commandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
- OPTICK_VK_CHECK(vkBeginCommandBuffer(commandBuffer, &commandBufferBeginInfo));
- vkResetFences(device, 1, &fence);
-
- if (EventData* frameEvent = currentFrame.frameEvent)
- QueryTimestamp(commandBuffer, &frameEvent->finish);
-
- // Generate GPU Frame event for the next frame
- EventData& event = AddFrameEvent();
- QueryTimestamp(commandBuffer, &event.start);
- QueryTimestamp(commandBuffer, &AddFrameTag().timestamp);
- nextFrame.frameEvent = &event;
-
- OPTICK_VK_CHECK(vkEndCommandBuffer(commandBuffer));
- VkSubmitInfo submitInfo = {};
- submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
- submitInfo.pNext = nullptr;
- submitInfo.waitSemaphoreCount = 0;
- submitInfo.pWaitSemaphores = nullptr;
- submitInfo.commandBufferCount = 1;
- submitInfo.pCommandBuffers = &commandBuffer;
- submitInfo.signalSemaphoreCount = 0;
- submitInfo.pSignalSemaphores = nullptr;
- OPTICK_VK_CHECK(vkQueueSubmit(queue, 1, &submitInfo, fence));
-
- uint32_t queryBegin = currentFrame.queryIndexStart;
- uint32_t queryEnd = node.queryIndex;
-
- if (queryBegin != (uint32_t)-1)
- {
- currentFrame.queryIndexCount = queryEnd - queryBegin;
- }
-
- // Preparing Next Frame
- // Try resolve timestamps for the current frame
- if (nextFrame.queryIndexStart != (uint32_t)-1)
- {
- uint32_t startIndex = nextFrame.queryIndexStart % MAX_QUERIES_COUNT;
- uint32_t finishIndex = (startIndex + nextFrame.queryIndexCount) % MAX_QUERIES_COUNT;
-
- if (startIndex < finishIndex)
- {
- ResolveTimestamps(commandBuffer, startIndex, finishIndex - startIndex);
- }
- else if (startIndex > finishIndex)
- {
- ResolveTimestamps(commandBuffer, startIndex, MAX_QUERIES_COUNT - startIndex);
- ResolveTimestamps(commandBuffer, 0, finishIndex);
- }
- }
-
- nextFrame.queryIndexStart = queryEnd;
- nextFrame.queryIndexCount = 0;
- }
-
- ++frameNumber;
- }
-
- GPUProfiler::ClockSynchronization GPUProfilerVulkan::GetClockSynchronization(uint32_t nodeIndex)
- {
- GPUProfiler::ClockSynchronization clock;
-
- NodePayload& node = *nodePayloads[nodeIndex];
- Frame& currentFrame = node.frames[frameNumber % NUM_FRAMES_DELAY];
-
- VkCommandBufferBeginInfo commandBufferBeginInfo;
- commandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
- commandBufferBeginInfo.pNext = 0;
- commandBufferBeginInfo.pInheritanceInfo = 0;
- commandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
- VkCommandBuffer CB = currentFrame.commandBuffer;
- VkDevice Device = node.device;
- VkFence Fence = currentFrame.fence;
-
- vkWaitForFences(Device, 1, &Fence, 1, (uint64_t)-1);
- vkResetFences(Device, 1, &Fence);
- vkResetCommandBuffer(CB, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
- vkBeginCommandBuffer(CB, &commandBufferBeginInfo);
- vkCmdResetQueryPool(CB, nodePayloads[nodeIndex]->queryPool, 0, 1);
- vkCmdWriteTimestamp(CB, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, nodePayloads[nodeIndex]->queryPool, 0);
- vkEndCommandBuffer(CB);
-
- VkSubmitInfo submitInfo = {};
- submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
- submitInfo.pNext = nullptr;
- submitInfo.waitSemaphoreCount = 0;
- submitInfo.pWaitSemaphores = nullptr;
- submitInfo.commandBufferCount = 1;
- submitInfo.pCommandBuffers = &CB;
- submitInfo.signalSemaphoreCount = 0;
- submitInfo.pSignalSemaphores = nullptr;
- vkQueueSubmit(nodePayloads[nodeIndex]->queue, 1, &submitInfo, Fence);
- vkWaitForFences(Device, 1, &Fence, 1, (uint64_t)-1);
-
- clock.timestampGPU = 0;
- vkGetQueryPoolResults(Device, nodePayloads[nodeIndex]->queryPool, 0, 1, 8, &clock.timestampGPU, 8, VK_QUERY_RESULT_64_BIT);
- clock.timestampCPU = GetHighPrecisionTime();
- clock.frequencyCPU = GetHighPrecisionFrequency();
-
- VkPhysicalDeviceProperties Properties;
- vkGetPhysicalDeviceProperties(nodePayloads[nodeIndex]->physicalDevice, &Properties);
- clock.frequencyGPU = (uint64_t)(1000000000ll / Properties.limits.timestampPeriod);
-
- return clock;
- }
-
- GPUProfilerVulkan::NodePayload::~NodePayload()
- {
- vkDestroyCommandPool(device, commandPool, nullptr);
- vkDestroyQueryPool(device, queryPool, nullptr);
- }
-
- GPUProfilerVulkan::~GPUProfilerVulkan()
- {
- WaitForFrame(frameNumber - 1);
-
- for (NodePayload* payload : nodePayloads)
- {
- for (Frame& frame : payload->frames)
- {
- vkDestroyFence(payload->device, frame.fence, nullptr);
- vkFreeCommandBuffers(payload->device, payload->commandPool, 1, &frame.commandBuffer);
- }
-
- Memory::Delete(payload);
- }
-
- nodePayloads.clear();
- }
-}
-#else
-#include "optick_common.h"
-namespace Optick
-{
- void InitGpuVulkan(void* /*devices*/, void* /*physicalDevices*/, void* /*cmdQueues*/, uint32_t* /*cmdQueuesFamily*/, uint32_t /*numQueues*/)
- {
- OPTICK_FAILED("OPTICK_ENABLE_GPU_VULKAN is disabled! Can't initialize GPU Profiler!");
- }
-}
-#endif //OPTICK_ENABLE_GPU_D3D12
-#endif //USE_OPTICK \ No newline at end of file
diff --git a/external/optick/optick_memory.h b/external/optick/optick_memory.h
deleted file mode 100644
index 45249c6..0000000
--- a/external/optick/optick_memory.h
+++ /dev/null
@@ -1,419 +0,0 @@
-#pragma once
-
-#include "optick_common.h"
-
-#if USE_OPTICK
-
-#include <cstring>
-#include <new>
-#include <stdlib.h>
-#include <atomic>
-
-#include <array>
-#include <list>
-#include <string>
-#include <sstream>
-#include <unordered_set>
-#include <unordered_map>
-#include <vector>
-
-namespace Optick
-{
- class Memory
- {
- struct Header
- {
- uint64_t size;
- };
-
- static std::atomic<uint64_t> memAllocated;
-
- static void* (*allocate)(size_t);
- static void (*deallocate)(void* p);
- public:
- static OPTICK_INLINE void* Alloc(size_t size)
- {
- size_t totalSize = size + sizeof(Header);
- void *ptr = allocate(totalSize);
- OPTICK_VERIFY(ptr, "Can't allocate memory", return nullptr);
-
- Header* header = (Header*)ptr;
- header->size = totalSize;
- memAllocated += totalSize;
-
- return (uint8_t*)ptr + sizeof(Header);
- }
-
- static OPTICK_INLINE void Free(void* p)
- {
- if (p != nullptr)
- {
- uint8_t* basePtr = (uint8_t*)p - sizeof(Header);
- Header* header = (Header*)basePtr;
- memAllocated -= header->size;
- deallocate(basePtr);
- }
- }
-
- static OPTICK_INLINE size_t GetAllocatedSize()
- {
- return (size_t)memAllocated;
- }
-
- template<class T>
- static T* New()
- {
- return new (Memory::Alloc(sizeof(T))) T();
- }
-
- template<class T, class P1>
- static T* New(P1 p1)
- {
- return new (Memory::Alloc(sizeof(T))) T(p1);
- }
-
- template<class T, class P1, class P2>
- static T* New(P1 p1, P2 p2)
- {
- return new (Memory::Alloc(sizeof(T))) T(p1, p2);
- }
-
- template<class T>
- static void Delete(T* p)
- {
- if (p)
- {
- p->~T();
- Free(p);
- }
- }
-
- static void SetAllocator(void* (*allocateFn)(size_t), void(*deallocateFn)(void*))
- {
- allocate = allocateFn;
- deallocate = deallocateFn;
- }
-
- template<typename T>
- struct Allocator : public std::allocator<T>
- {
- Allocator() {}
- template<class U>
- Allocator(const Allocator<U>&) {}
- template<typename U> struct rebind { typedef Allocator<U> other; };
-
- typename std::allocator<T>::pointer allocate(typename std::allocator<T>::size_type n, typename std::allocator<void>::const_pointer = 0)
- {
- return reinterpret_cast<typename std::allocator<T>::pointer>(Memory::Alloc(n * sizeof(T)));
- }
-
- void deallocate(typename std::allocator<T>::pointer p, typename std::allocator<T>::size_type)
- {
- Memory::Free(p);
- }
- };
- };
-
- // std::* section
- template <typename T, size_t _Size> class array : public std::array<T, _Size>{};
- template <typename T> class vector : public std::vector<T, Memory::Allocator<T>>{};
- template <typename T> class list : public std::list<T, Memory::Allocator<T>>{};
- template <typename T> class unordered_set : public std::unordered_set<T, std::hash<T>, std::equal_to<T>, Memory::Allocator<T>>{};
- template <typename T, typename V> class unordered_map : public std::unordered_map<T, V, std::hash<T>, std::equal_to<T>, Memory::Allocator<std::pair<const T, V>>>{};
-
- using string = std::basic_string<char, std::char_traits<char>, Memory::Allocator<char>>;
- using wstring = std::basic_string<wchar_t, std::char_traits<wchar_t>, Memory::Allocator<wchar_t>>;
-
- using istringstream = std::basic_istringstream<char, std::char_traits<char>, Memory::Allocator<char>>;
- using ostringstream = std::basic_ostringstream<char, std::char_traits<char>, Memory::Allocator<char>>;
- using stringstream = std::basic_stringstream<char, std::char_traits<char>, Memory::Allocator<char>>;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- template<class T, uint32 SIZE>
- struct MemoryChunk
- {
- OPTICK_ALIGN_CACHE T data[SIZE];
- MemoryChunk* next;
- MemoryChunk* prev;
-
- MemoryChunk() : next(0), prev(0) {}
-
- ~MemoryChunk()
- {
- MemoryChunk* chunk = this;
- while (chunk->next)
- chunk = chunk->next;
-
- while (chunk != this)
- {
- MemoryChunk* toDelete = chunk;
- chunk = toDelete->prev;
- Memory::Delete(toDelete);
- }
-
- if (prev != nullptr)
- {
- prev->next = nullptr;
- prev = nullptr;
- }
- }
- };
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- template<class T, uint32 SIZE = 16>
- class MemoryPool
- {
- typedef MemoryChunk<T, SIZE> Chunk;
- Chunk* root;
- Chunk* chunk;
- uint32 index;
-
- OPTICK_INLINE void AddChunk()
- {
- index = 0;
- if (!chunk || !chunk->next)
- {
- Chunk* newChunk = Memory::New<Chunk>();
- if (chunk)
- {
- chunk->next = newChunk;
- newChunk->prev = chunk;
- chunk = newChunk;
- }
- else
- {
- root = chunk = newChunk;
- }
- }
- else
- {
- chunk = chunk->next;
- }
- }
- public:
- MemoryPool() : root(nullptr), chunk(nullptr), index(SIZE) {}
-
- OPTICK_INLINE T& Add()
- {
- if (index >= SIZE)
- AddChunk();
-
- return chunk->data[index++];
- }
-
- OPTICK_INLINE T& Add(const T& item)
- {
- return Add() = item;
- }
-
- OPTICK_INLINE T* AddRange(const T* items, size_t count, bool allowOverlap = true)
- {
- if (count == 0 || (count > SIZE && !allowOverlap))
- return nullptr;
-
- if (count >= (SIZE - index) && !allowOverlap)
- {
- AddChunk();
- }
-
- T* result = &chunk->data[index];
-
- while (count)
- {
- size_t numLeft = SIZE - index;
- size_t numCopy = numLeft < count ? numLeft : count;
- std::memcpy(&chunk->data[index], items, sizeof(T) * numCopy);
-
- count -= numCopy;
- items += numCopy;
- index += (uint32_t)numCopy;
-
- if (count)
- AddChunk();
- }
-
- return result;
- }
-
-
- OPTICK_INLINE T* TryAdd(int count)
- {
- if (index + count <= SIZE)
- {
- T* res = &chunk->data[index];
- index += count;
- return res;
- }
-
- return nullptr;
- }
-
- OPTICK_INLINE T* Back()
- {
- if (chunk && index > 0)
- return &chunk->data[index - 1];
-
- if (chunk && chunk->prev != nullptr)
- return &chunk->prev->data[SIZE - 1];
-
- return nullptr;
- }
-
- OPTICK_INLINE size_t Size() const
- {
- if (root == nullptr)
- return 0;
-
- size_t count = 0;
-
- for (const Chunk* it = root; it != chunk; it = it->next)
- count += SIZE;
-
- return count + index;
- }
-
- OPTICK_INLINE bool IsEmpty() const
- {
- return (chunk == nullptr) || (chunk == root && index == 0);
- }
-
- OPTICK_INLINE void Clear(bool preserveMemory = true)
- {
- if (!preserveMemory)
- {
- if (root)
- {
- Memory::Delete(root);
- root = nullptr;
- chunk = nullptr;
- index = SIZE;
- }
- }
- else if (root)
- {
- index = 0;
- chunk = root;
- }
- }
-
- class const_iterator
- {
- void advance()
- {
- if (chunkIndex < SIZE - 1)
- {
- ++chunkIndex;
- }
- else
- {
- chunkPtr = chunkPtr->next;
- chunkIndex = 0;
- }
- }
- public:
- typedef const_iterator self_type;
- typedef T value_type;
- typedef T& reference;
- typedef T* pointer;
- typedef int difference_type;
- const_iterator(const Chunk* ptr, size_t index) : chunkPtr(ptr), chunkIndex(index) { }
- self_type operator++()
- {
- self_type i = *this;
- advance();
- return i;
- }
- self_type operator++(int /*junk*/)
- {
- advance();
- return *this;
- }
- reference operator*() { return (reference)chunkPtr->data[chunkIndex]; }
- const pointer operator->() { return &chunkPtr->data[chunkIndex]; }
- bool operator==(const self_type& rhs) { return (chunkPtr == rhs.chunkPtr) && (chunkIndex == rhs.chunkIndex); }
- bool operator!=(const self_type& rhs) { return (chunkPtr != rhs.chunkPtr) || (chunkIndex != rhs.chunkIndex); }
- private:
- const Chunk* chunkPtr;
- size_t chunkIndex;
- };
-
- const_iterator begin() const
- {
- return const_iterator(root, 0);
- }
-
- const_iterator end() const
- {
- return const_iterator(chunk, index);
- }
-
- template<class Func>
- void ForEach(Func func) const
- {
- for (const Chunk* it = root; it != chunk; it = it->next)
- for (uint32 i = 0; i < SIZE; ++i)
- func(it->data[i]);
-
- if (chunk)
- for (uint32 i = 0; i < index; ++i)
- func(chunk->data[i]);
- }
-
- template<class Func>
- void ForEach(Func func)
- {
- for (Chunk* it = root; it != chunk; it = it->next)
- for (uint32 i = 0; i < SIZE; ++i)
- func(it->data[i]);
-
- if (chunk)
- for (uint32 i = 0; i < index; ++i)
- func(chunk->data[i]);
- }
-
- template<class Func>
- void ForEachChunk(Func func) const
- {
- for (const Chunk* it = root; it != chunk; it = it->next)
- func(it->data, SIZE);
-
- if (chunk)
- func(chunk->data, index);
- }
-
- void ToArray(T* destination) const
- {
- uint32 curIndex = 0;
-
- for (const Chunk* it = root; it != chunk; it = it->next)
- {
- memcpy(&destination[curIndex], it->data, sizeof(T) * SIZE);
- curIndex += SIZE;
- }
-
- if (chunk && index > 0)
- {
- memcpy(&destination[curIndex], chunk->data, sizeof(T) * index);
- }
- }
- };
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- template<uint32 CHUNK_SIZE>
- class MemoryBuffer : private MemoryPool<uint8, CHUNK_SIZE>
- {
- public:
- template<class U>
- U* Add(U* data, size_t size, bool allowOverlap = true)
- {
- return (U*)(MemoryPool<uint8, CHUNK_SIZE>::AddRange((uint8*)data, size, allowOverlap));
- }
-
- template<class T>
- T* Add(const T& val, bool allowOverlap = true)
- {
- return static_cast<T*>(Add(&val, sizeof(T), allowOverlap));
- }
- };
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-}
-
-#endif //USE_OPTICK \ No newline at end of file
diff --git a/external/optick/optick_message.cpp b/external/optick/optick_message.cpp
deleted file mode 100644
index b421d50..0000000
--- a/external/optick/optick_message.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-#include "optick.config.h"
-
-#if USE_OPTICK
-#include "optick_common.h"
-#include "optick_core.h"
-#include "optick_message.h"
-#include "optick_server.h"
-
-namespace Optick
-{
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct MessageHeader
-{
- uint32 mark;
- uint32 length;
-
- static const uint32 MESSAGE_MARK = 0xB50FB50F;
-
- bool IsValid() const { return mark == MESSAGE_MARK; }
-
- MessageHeader() : mark(0), length(0) {}
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-class MessageFactory
-{
- typedef IMessage* (*MessageCreateFunction)(InputDataStream& str);
- MessageCreateFunction factory[IMessage::COUNT];
-
- template<class T>
- void RegisterMessage()
- {
- factory[T::GetMessageType()] = T::Create;
- }
-
- MessageFactory()
- {
- memset(&factory[0], 0, sizeof(MessageCreateFunction));
-
- RegisterMessage<StartMessage>();
- RegisterMessage<StopMessage>();
- RegisterMessage<CancelMessage>();
- RegisterMessage<TurnSamplingMessage>();
-
- for (uint32 msg = 0; msg < IMessage::COUNT; ++msg)
- {
- OPTICK_ASSERT(factory[msg] != nullptr, "Message is not registered to factory");
- }
- }
-public:
- static MessageFactory& Get()
- {
- static MessageFactory instance;
- return instance;
- }
-
- IMessage* Create(InputDataStream& str)
- {
- MessageHeader header;
- str.Read(header);
-
- size_t length = str.Length();
-
- uint16 applicationID = 0;
- uint16 messageType = IMessage::COUNT;
-
- str >> applicationID;
- str >> messageType;
-
- OPTICK_VERIFY( 0 <= messageType && messageType < IMessage::COUNT && factory[messageType] != nullptr, "Unknown message type!", return nullptr )
-
- IMessage* result = factory[messageType](str);
-
- if (header.length + str.Length() != length)
- {
- OPTICK_FAILED("Message Stream is corrupted! Invalid Protocol?")
- return nullptr;
- }
-
- return result;
- }
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator<<(OutputDataStream& os, const DataResponse& val)
-{
- return os << val.version << (uint32)val.type;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-IMessage* IMessage::Create(InputDataStream& str)
-{
- MessageHeader header;
-
- while (str.Peek(header))
- {
- if (header.IsValid())
- {
- if (str.Length() < header.length + sizeof(MessageHeader))
- break; // Not enough data yet
-
- return MessageFactory::Get().Create(str);
- }
- else
- {
- // Some garbage in the stream?
- str.Skip(1);
- }
- }
-
- return nullptr;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void StartMessage::Apply()
-{
- Core& core = Core::Get();
- core.SetSettings(settings);
- core.StartCapture();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-IMessage* StartMessage::Create(InputDataStream& stream)
-{
- StartMessage* msg = Memory::New<StartMessage>();
- CaptureSettings& settings = msg->settings;
- stream >> settings.mode
- >> settings.categoryMask
- >> settings.samplingFrequency
- >> settings.frameLimit
- >> settings.timeLimitUs
- >> settings.spikeLimitUs
- >> settings.memoryLimitMb;
- string password;
- stream >> settings.password;
- settings.password = base64_decode(password);
- return msg;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void StopMessage::Apply()
-{
- Core::Get().DumpCapture();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-IMessage* StopMessage::Create(InputDataStream&)
-{
- return Memory::New<StopMessage>();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void CancelMessage::Apply()
-{
- Core::Get().CancelCapture();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-IMessage* CancelMessage::Create(InputDataStream&)
-{
- return Memory::New<CancelMessage>();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-IMessage* TurnSamplingMessage::Create( InputDataStream& stream )
-{
- TurnSamplingMessage* msg = Memory::New<TurnSamplingMessage>();
- stream >> msg->index;
- stream >> msg->isSampling;
- return msg;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void TurnSamplingMessage::Apply()
-{
- // Backward compatibility
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-}
-
-#endif //USE_OPTICK \ No newline at end of file
diff --git a/external/optick/optick_message.h b/external/optick/optick_message.h
deleted file mode 100644
index a6d553e..0000000
--- a/external/optick/optick_message.h
+++ /dev/null
@@ -1,130 +0,0 @@
-#pragma once
-#include "optick.config.h"
-
-#if USE_OPTICK
-
-#include "optick_common.h"
-#include "optick_serialization.h"
-
-namespace Optick
-{
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-static const uint32 NETWORK_PROTOCOL_VERSION = 24;
-static const uint16 NETWORK_APPLICATION_ID = 0xB50F;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct DataResponse
-{
- enum Type : uint16
- {
- FrameDescriptionBoard = 0, // DescriptionBoard for Instrumental Frames
- EventFrame = 1, // Instrumental Data
- SamplingFrame = 2, // Sampling Data
- NullFrame = 3, // Last Fame Mark
- ReportProgress = 4, // Report Current Progress
- Handshake = 5, // Handshake Response
- Reserved_0 = 6,
- SynchronizationData = 7, // Synchronization Data for the thread
- TagsPack = 8, // Pack of tags
- CallstackDescriptionBoard = 9, // DescriptionBoard with resolved function addresses
- CallstackPack = 10, // Pack of CallStacks
- Reserved_1 = 11,
- Reserved_2 = 12,
- Reserved_3 = 13,
- Reserved_4 = 14,
- //...
- Reserved_255 = 255,
-
- FiberSynchronizationData = 1 << 8, // Synchronization Data for the Fibers
- SyscallPack,
- SummaryPack,
- };
-
- uint32 version;
- uint32 size;
- Type type;
- uint16 application;
-
- DataResponse(Type t, uint32 s) : version(NETWORK_PROTOCOL_VERSION), size(s), type(t), application(NETWORK_APPLICATION_ID){}
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-OutputDataStream& operator << (OutputDataStream& os, const DataResponse& val);
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-class IMessage
-{
-public:
- enum Type : uint16
- {
- Start,
- Stop,
- Cancel,
- TurnSampling,
- COUNT,
- };
-
- virtual void Apply() = 0;
- virtual ~IMessage() {}
-
- static IMessage* Create( InputDataStream& str );
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-template<IMessage::Type MESSAGE_TYPE>
-class Message : public IMessage
-{
- enum { id = MESSAGE_TYPE };
-public:
- static uint32 GetMessageType() { return id; }
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct CaptureSettings
-{
- // Capture Mode
- uint32 mode;
- // Category Filter
- uint32 categoryMask;
- // Tracer: Sampling Frequency
- uint32 samplingFrequency;
- // Max Duration for a capture (frames)
- uint32 frameLimit;
- // Max Duration for a capture (us)
- uint32 timeLimitUs;
- // Max Duration for a capture (us)
- uint32 spikeLimitUs;
- // Max Memory for a capture (MB)
- uint64 memoryLimitMb;
- // Tracer: Root Password for the Device
- string password;
-
- CaptureSettings() : mode(0), categoryMask(0), samplingFrequency(0), frameLimit(0), timeLimitUs(0), spikeLimitUs(0), memoryLimitMb(0) {}
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct StartMessage : public Message<IMessage::Start>
-{
- CaptureSettings settings;
- static IMessage* Create(InputDataStream&);
- virtual void Apply() override;
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct StopMessage : public Message<IMessage::Stop>
-{
- static IMessage* Create(InputDataStream&);
- virtual void Apply() override;
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct CancelMessage : public Message<IMessage::Cancel>
-{
- static IMessage* Create(InputDataStream&);
- virtual void Apply() override;
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-struct TurnSamplingMessage : public Message<IMessage::TurnSampling>
-{
- int32 index;
- byte isSampling;
-
- static IMessage* Create(InputDataStream& stream);
- virtual void Apply() override;
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-}
-
-#endif //USE_OPTICK \ No newline at end of file
diff --git a/external/optick/optick_serialization.cpp b/external/optick/optick_serialization.cpp
deleted file mode 100644
index a47a9b7..0000000
--- a/external/optick/optick_serialization.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-#include "optick.config.h"
-
-#if USE_OPTICK
-
-#include "optick_common.h"
-#include "optick_serialization.h"
-
-namespace Optick
-{
- string OutputDataStream::GetData()
- {
- flush();
- return str();
- }
-
- OutputDataStream & OutputDataStream::Write(const char * buffer, size_t size)
- {
- write(buffer, size);
- return *this;
- }
-
- OutputDataStream OutputDataStream::Empty;
-
- OutputDataStream &operator << ( OutputDataStream &stream, const char* val )
- {
- uint32 length = val == nullptr ? 0 : (uint32)strlen(val);
- stream << length;
-
- if (length > 0)
- {
- stream.write( val, length );
- }
- return stream;
- }
-
- OutputDataStream &operator << ( OutputDataStream &stream, int val )
- {
- stream.write( (char*)&val, sizeof(int) );
- return stream;
- }
-
- OutputDataStream &operator << ( OutputDataStream &stream, int64 val )
- {
- stream.write( (char*)&val, sizeof(int64) );
- return stream;
- }
-
- OutputDataStream &operator << ( OutputDataStream &stream, char val )
- {
- stream.write( (char*)&val, sizeof(char) );
- return stream;
- }
-
- OutputDataStream &operator << (OutputDataStream &stream, int8 val)
- {
- stream.write((char*)&val, sizeof(val));
- return stream;
- }
-
- OutputDataStream &operator << ( OutputDataStream &stream, byte val )
- {
- stream.write( (char*)&val, sizeof(byte) );
- return stream;
- }
-
- OutputDataStream & operator<<(OutputDataStream &stream, uint64 val)
- {
- stream.write( (char*)&val, sizeof(uint64) );
- return stream;
- }
-
- OutputDataStream & operator<<(OutputDataStream &stream, uint32 val)
- {
- stream.write( (char*)&val, sizeof(uint32) );
- return stream;
- }
-
- OutputDataStream & operator<<(OutputDataStream &stream, float val)
- {
- stream.write((char*)&val, sizeof(float));
- return stream;
- }
-
- OutputDataStream & operator<<(OutputDataStream &stream, const string& val)
- {
- stream << (uint32)val.length();
- if (!val.empty())
- stream.write(&val[0], sizeof(val[0]) * val.length());
- return stream;
- }
-
- OutputDataStream & operator<<(OutputDataStream &stream, const wstring& val)
- {
- size_t count = val.length() * sizeof(wchar_t);
- stream << (uint32)count;
- if (!val.empty())
- stream.write((char*)(&val[0]), count);
- return stream;
- }
-
- InputDataStream &operator >> (InputDataStream &stream, int16 &val)
- {
- stream.read((char*)&val, sizeof(int16));
- return stream;
- }
-
- InputDataStream &operator >> ( InputDataStream &stream, int32 &val )
- {
- stream.read( (char*)&val, sizeof(int) );
- return stream;
- }
-
- InputDataStream &operator >> ( InputDataStream &stream, int64 &val )
- {
- stream.read( (char*)&val, sizeof(int64) );
- return stream;
- }
-
- InputDataStream & operator>>( InputDataStream &stream, byte &val )
- {
- stream.read( (char*)&val, sizeof(byte) );
- return stream;
- }
-
- InputDataStream & operator >> (InputDataStream &stream, uint16 &val)
- {
- stream.read((char*)&val, sizeof(uint16));
- return stream;
- }
-
- InputDataStream & operator>>( InputDataStream &stream, uint32 &val )
- {
- stream.read( (char*)&val, sizeof(uint32) );
- return stream;
- }
-
- InputDataStream & operator>>( InputDataStream &stream, uint64 &val )
- {
- stream.read( (char*)&val, sizeof(uint64) );
- return stream;
- }
-
- InputDataStream & operator >> ( InputDataStream &stream, string &val)
- {
- int32 length = 0;
- stream >> length;
- val.resize(length + 1);
- stream.read( (char*)&val[0], length);
- return stream;
- }
-
- InputDataStream::InputDataStream() :
- stringstream( ios_base::in | ios_base::out )
- {
- }
-
- void InputDataStream::Append(const char *buffer, size_t length)
- {
- write( buffer, length );
- }
-
- size_t InputDataStream::Length()
- {
- return (size_t)(tellp() - tellg());
- }
-
- bool InputDataStream::Skip(size_t length)
- {
- bool result = Length() <= length;
- seekg(length, ios_base::cur);
- return result;
- }
-
-
-
-}
-
-#endif //USE_OPTICK \ No newline at end of file
diff --git a/external/optick/optick_serialization.h b/external/optick/optick_serialization.h
deleted file mode 100644
index 91de32d..0000000
--- a/external/optick/optick_serialization.h
+++ /dev/null
@@ -1,120 +0,0 @@
-#pragma once
-#include "optick_common.h"
-
-#if USE_OPTICK
-#include "optick_memory.h"
-
-#if defined(OPTICK_MSVC)
-#pragma warning( push )
-
-//C4250. inherits 'std::basic_ostream'
-#pragma warning( disable : 4250 )
-
-//C4127. Conditional expression is constant
-#pragma warning( disable : 4127 )
-#endif
-
-namespace Optick
-{
- class OutputDataStream : private ostringstream
- {
- public:
- static OutputDataStream Empty;
- // Move constructor rocks!
- // Beware of one copy here(do not use it in performance critical parts)
- string GetData();
-
- // It is important to make private inheritance in order to avoid collision with default operator implementation
- friend OutputDataStream &operator << ( OutputDataStream &stream, const char* val );
- friend OutputDataStream &operator << ( OutputDataStream &stream, int val );
- friend OutputDataStream &operator << ( OutputDataStream &stream, uint64 val );
- friend OutputDataStream &operator << ( OutputDataStream &stream, uint32 val );
- friend OutputDataStream &operator << ( OutputDataStream &stream, int64 val );
- friend OutputDataStream &operator << ( OutputDataStream &stream, char val );
- friend OutputDataStream &operator << ( OutputDataStream &stream, byte val );
- friend OutputDataStream &operator << ( OutputDataStream &stream, int8 val);
- friend OutputDataStream &operator << ( OutputDataStream &stream, float val);
- friend OutputDataStream &operator << ( OutputDataStream &stream, const string& val );
- friend OutputDataStream &operator << ( OutputDataStream &stream, const wstring& val );
-
- OutputDataStream& Write(const char* buffer, size_t size);
- };
-
- template<class T>
- OutputDataStream& operator<<(OutputDataStream &stream, const vector<T>& val)
- {
- stream << (uint32)val.size();
-
- for(auto it = val.begin(); it != val.end(); ++it)
- {
- const T& element = *it;
- stream << element;
- }
-
- return stream;
- }
-
- template<class T, uint32 N>
- OutputDataStream& operator<<(OutputDataStream &stream, const MemoryPool<T, N>& val)
- {
- stream << (uint32)val.Size();
-
- val.ForEach([&](const T& data)
- {
- stream << data;
- });
-
- return stream;
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- class InputDataStream : private stringstream {
- public:
- bool CanRead() { return !eof(); }
-
- InputDataStream();
-
- void Append(const char *buffer, size_t length);
- bool Skip(size_t length);
- size_t Length();
-
- template<class T>
- bool Peek(T& data)
- {
- if (Length() < sizeof(T))
- return false;
-
- pos_type currentPos = tellg();
- read((char*)&data, sizeof(T));
- seekg(currentPos);
- return true;
- }
-
- template<class T>
- bool Read(T& data)
- {
- if (Length() < sizeof(T))
- return false;
-
- read((char*)&data, sizeof(T));
- return true;
- }
-
- friend InputDataStream &operator >> (InputDataStream &stream, byte &val );
- friend InputDataStream &operator >> (InputDataStream &stream, int16 &val);
- friend InputDataStream &operator >> (InputDataStream &stream, uint16 &val);
- friend InputDataStream &operator >> (InputDataStream &stream, int32 &val );
- friend InputDataStream &operator >> (InputDataStream &stream, uint32 &val );
- friend InputDataStream &operator >> (InputDataStream &stream, int64 &val );
- friend InputDataStream &operator >> (InputDataStream &stream, uint64 &val );
- friend InputDataStream &operator >> (InputDataStream &stream, string &val);
- };
-
-
-}
-
-#if defined(OPTICK_MSVC)
-#pragma warning( pop )
-#endif
-
-#endif //USE_OPTICK \ No newline at end of file
diff --git a/external/optick/optick_server.cpp b/external/optick/optick_server.cpp
deleted file mode 100644
index 7596d3a..0000000
--- a/external/optick/optick_server.cpp
+++ /dev/null
@@ -1,338 +0,0 @@
-#include "optick.config.h"
-
-#if USE_OPTICK
-#include "optick_server.h"
-#include "optick_common.h"
-
-#if defined(OPTICK_MSVC)
-#define USE_WINDOWS_SOCKETS (1)
-#else
-#define USE_BERKELEY_SOCKETS (1)
-#endif
-#define SOCKET_PROTOCOL_TCP (6)
-#if defined(USE_BERKELEY_SOCKETS)
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <limits.h>
-typedef int TcpSocket;
-#elif defined(USE_WINDOWS_SOCKETS)
-#include <winsock2.h>
-#include <basetsd.h>
-typedef UINT_PTR TcpSocket;
-#else
-#error Platform not supported
-#endif
-
-
-#if defined(OPTICK_MSVC)
-#pragma comment( lib, "ws2_32.lib" )
-#endif
-
-namespace Optick
-{
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-static const short DEFAULT_PORT = 31318;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-#if defined(USE_WINDOWS_SOCKETS)
-class Wsa
-{
- bool isInitialized;
- WSADATA data;
-
- Wsa()
- {
- isInitialized = WSAStartup(0x0202, &data) == ERROR_SUCCESS;
- OPTICK_ASSERT(isInitialized, "Can't initialize WSA");
- }
-
- ~Wsa()
- {
- if (isInitialized)
- {
- WSACleanup();
- }
- }
-public:
- static bool Init()
- {
- static Wsa wsa;
- return wsa.isInitialized;
- }
-};
-#endif
-
-
-inline bool IsValidSocket(TcpSocket socket)
-{
-#if defined(USE_WINDOWS_SOCKETS)
- if (socket == INVALID_SOCKET)
- {
- return false;
- }
-#else
- if (socket < 0)
- {
- return false;
- }
-#endif
- return true;
-}
-
-inline void CloseSocket(TcpSocket& socket)
-{
-#if defined(USE_WINDOWS_SOCKETS)
- closesocket(socket);
- socket = INVALID_SOCKET;
-#else
- close(socket);
- socket = -1;
-#endif
-}
-
-inline bool SetSocketBlockingMode(TcpSocket socket, bool isBlocking)
-{
-#if defined(USE_WINDOWS_SOCKETS)
- unsigned long mode = isBlocking ? 0 : 1;
- return (ioctlsocket(socket, FIONBIO, &mode) == 0) ? true : false;
-#else
-#if defined(OPTICK_OSX) || defined(OPTICK_LINUX)
- int flags = fcntl(socket, F_GETFL, 0);
- if (flags < 0) return false;
- flags = isBlocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
- return (fcntl(socket, F_SETFL, flags) == 0) ? true : false;
-#else
- int nonblocking = isBlocking ? 0 : 1;
- return setsockopt((int)socket, SOL_SOCKET, 0x1200, (char*)&nonblocking, sizeof(nonblocking)) == 0;
-#endif
-#endif
-}
-
-
-class Socket
-{
- TcpSocket acceptSocket;
- TcpSocket listenSocket;
- sockaddr_in address;
-
- fd_set recieveSet;
-
- std::recursive_mutex socketLock;
- wstring errorMessage;
-
- void Close()
- {
- if (!IsValidSocket(listenSocket))
- {
- CloseSocket(listenSocket);
- }
- }
-
- bool Bind(short port)
- {
- address.sin_family = AF_INET;
- address.sin_addr.s_addr = INADDR_ANY;
- address.sin_port = htons(port);
-
- if (::bind(listenSocket, (sockaddr *)&address, sizeof(address)) == 0)
- {
- return true;
- }
-
- return false;
- }
-
- void Disconnect()
- {
- std::lock_guard<std::recursive_mutex> lock(socketLock);
-
- if (!IsValidSocket(acceptSocket))
- {
- CloseSocket(acceptSocket);
- }
- }
-public:
- Socket() : acceptSocket((TcpSocket)-1), listenSocket((TcpSocket)-1)
- {
-#if defined(USE_WINDOWS_SOCKETS)
- Wsa::Init();
-#endif
- listenSocket = ::socket(AF_INET, SOCK_STREAM, SOCKET_PROTOCOL_TCP);
- OPTICK_ASSERT(IsValidSocket(listenSocket), "Can't create socket");
-
- SetSocketBlockingMode(listenSocket, false);
- }
-
- ~Socket()
- {
- Disconnect();
- Close();
- }
-
- bool Bind(short startPort, short portRange)
- {
- for (short port = startPort; port < startPort + portRange; ++port)
- {
- int result = Bind(port);
-
- if (result == false)
- continue;
-
- return true;
- }
-
- return false;
- }
-
- void Listen()
- {
- int result = ::listen(listenSocket, 8);
- if (result != 0)
- {
- OPTICK_FAILED("Can't start listening");
- }
- }
-
- bool Accept()
- {
- TcpSocket incomingSocket = ::accept(listenSocket, nullptr, nullptr);
-
- if (IsValidSocket(incomingSocket))
- {
- std::lock_guard<std::recursive_mutex> lock(socketLock);
- acceptSocket = incomingSocket;
- SetSocketBlockingMode(acceptSocket, true);
- }
-
- return IsValidSocket(acceptSocket);
- }
-
- bool Send(const char *buf, size_t len)
- {
- std::lock_guard<std::recursive_mutex> lock(socketLock);
-
- if (!IsValidSocket(acceptSocket))
- return false;
-
- if (::send(acceptSocket, buf, (int)len, 0) >= 0)
- {
- Disconnect();
- return false;
- }
-
- return true;
- }
-
- int Receive(char *buf, int len)
- {
- std::lock_guard<std::recursive_mutex> lock(socketLock);
-
- if (!IsValidSocket(acceptSocket))
- return 0;
-
- FD_ZERO(&recieveSet);
- FD_SET(acceptSocket, &recieveSet);
-
- static timeval lim = { 0, 0 };
-
-#if defined(USE_BERKELEY_SOCKETS)
- if (::select(acceptSocket + 1, &recieveSet, nullptr, nullptr, &lim) == 1)
-#elif defined(USE_WINDOWS_SOCKETS)
- if (::select(0, &recieveSet, nullptr, nullptr, &lim) == 1)
-#else
-#error Platform not supported
-#endif
- {
- return ::recv(acceptSocket, buf, len, 0);
- }
-
- return 0;
- }
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-Server::Server(short port) : socket(Memory::New<Socket>())
-{
- if (!socket->Bind(port, 4))
- {
- OPTICK_FAILED("Failed to bind a socket! Most probably the port is blocked by anti-virus! Change the port and verify that your game has enough permissions to communicate over the TCP\IP.");
- }
- else
- {
- socket->Listen();
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Server::Update()
-{
- std::lock_guard<std::recursive_mutex> lock(socketLock);
-
- if (!InitConnection())
- return;
-
- int length = -1;
- while ( (length = socket->Receive( buffer, BIFFER_SIZE ) ) > 0 )
- {
- networkStream.Append(buffer, length);
- }
-
- while (IMessage *message = IMessage::Create(networkStream))
- {
- message->Apply();
- Memory::Delete(message);
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void Server::Send(DataResponse::Type type, OutputDataStream& stream)
-{
- std::lock_guard<std::recursive_mutex> lock(socketLock);
-
- string data = stream.GetData();
-
- DataResponse response(type, (uint32)data.size());
- socket->Send((char*)&response, sizeof(response));
- socket->Send(data.c_str(), data.size());
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool Server::InitConnection()
-{
- return socket->Accept();
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-string Server::GetHostName() const
-{
- const uint32 HOST_NAME_LENGTH = 256;
- char hostname[HOST_NAME_LENGTH] = { 0 };
-
-#if defined(USE_BERKELEY_SOCKETS)
-#if defined(OPTICK_LINUX) || defined(OPTICK_OSX)
- gethostname(hostname, HOST_NAME_LENGTH);
-#endif
-#elif defined(OPTICK_PC)
- DWORD length = HOST_NAME_LENGTH;
- GetComputerNameA(hostname, &length);
-#endif
-
- return hostname;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-Server::~Server()
-{
- if (socket)
- {
- Memory::Delete(socket);
- socket = nullptr;
- }
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-Server & Server::Get()
-{
- static Server instance(DEFAULT_PORT);
- return instance;
-}
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-}
-
-#endif //USE_OPTICK \ No newline at end of file
diff --git a/external/optick/optick_server.h b/external/optick/optick_server.h
deleted file mode 100644
index b44153e..0000000
--- a/external/optick/optick_server.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#pragma once
-#include "optick.config.h"
-
-#if USE_OPTICK
-#include "optick_message.h"
-
-#include <mutex>
-#include <thread>
-
-namespace Optick
-{
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-class Socket;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-class Server
-{
- InputDataStream networkStream;
-
- static const int BIFFER_SIZE = 1024;
- char buffer[BIFFER_SIZE];
-
- Socket* socket;
-
- std::recursive_mutex socketLock;
-
- Server( short port );
- ~Server();
-
- bool InitConnection();
-
-public:
- void Send(DataResponse::Type type, OutputDataStream& stream = OutputDataStream::Empty);
- void Update();
-
- string GetHostName() const;
-
- static Server &Get();
-};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-}
-
-#endif //USE_OPTICK \ No newline at end of file