mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-24 15:31:05 +00:00
citra: Migrate to tracy profiler from Microprofile
This commit is contained in:
parent
8e2415f455
commit
f6efa049dd
@ -83,6 +83,7 @@ CMAKE_DEPENDENT_OPTION(ENABLE_SOFTWARE_RENDERER "Enables the software renderer"
|
|||||||
CMAKE_DEPENDENT_OPTION(ENABLE_OPENGL "Enables the OpenGL renderer" ON "NOT APPLE" OFF)
|
CMAKE_DEPENDENT_OPTION(ENABLE_OPENGL "Enables the OpenGL renderer" ON "NOT APPLE" OFF)
|
||||||
option(ENABLE_VULKAN "Enables the Vulkan renderer" ON)
|
option(ENABLE_VULKAN "Enables the Vulkan renderer" ON)
|
||||||
|
|
||||||
|
option(ENABLE_PROFILING "Enables integration with the Tracy profiler" ON)
|
||||||
option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF)
|
option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF)
|
||||||
|
|
||||||
CMAKE_DEPENDENT_OPTION(CITRA_ENABLE_BUNDLE_TARGET "Enable the distribution bundling target." ON "NOT ANDROID AND NOT IOS" OFF)
|
CMAKE_DEPENDENT_OPTION(CITRA_ENABLE_BUNDLE_TARGET "Enable the distribution bundling target." ON "NOT ANDROID AND NOT IOS" OFF)
|
||||||
|
9
externals/CMakeLists.txt
vendored
9
externals/CMakeLists.txt
vendored
@ -129,10 +129,6 @@ else()
|
|||||||
add_subdirectory(inih)
|
add_subdirectory(inih)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# MicroProfile
|
|
||||||
add_library(microprofile INTERFACE)
|
|
||||||
target_include_directories(microprofile SYSTEM INTERFACE ./microprofile)
|
|
||||||
|
|
||||||
# Nihstro
|
# Nihstro
|
||||||
add_library(nihstro-headers INTERFACE)
|
add_library(nihstro-headers INTERFACE)
|
||||||
target_include_directories(nihstro-headers SYSTEM INTERFACE ./nihstro/include)
|
target_include_directories(nihstro-headers SYSTEM INTERFACE ./nihstro/include)
|
||||||
@ -401,3 +397,8 @@ if (ENABLE_VULKAN)
|
|||||||
add_subdirectory(libadrenotools)
|
add_subdirectory(libadrenotools)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Tracy
|
||||||
|
if (ENABLE_PROFILING)
|
||||||
|
add_subdirectory(tracy)
|
||||||
|
endif()
|
||||||
|
7
externals/microprofile/README.md
vendored
7
externals/microprofile/README.md
vendored
@ -1,7 +0,0 @@
|
|||||||
# microprofile
|
|
||||||
|
|
||||||
MicroProfile is a embeddable profiler in a single file, written in C++
|
|
||||||
|
|
||||||
It can display profile information in the application, or by generating captures via a minimal built in webserver.
|
|
||||||
|
|
||||||
For more information see the project webpage at https://bitbucket.org/jonasmeyer/microprofile
|
|
3597
externals/microprofile/microprofile.h
vendored
3597
externals/microprofile/microprofile.h
vendored
File diff suppressed because it is too large
Load Diff
3868
externals/microprofile/microprofile_html.h
vendored
3868
externals/microprofile/microprofile_html.h
vendored
File diff suppressed because it is too large
Load Diff
3354
externals/microprofile/microprofileui.h
vendored
3354
externals/microprofile/microprofileui.h
vendored
File diff suppressed because it is too large
Load Diff
3
externals/tracy/CMakeLists.txt
vendored
Normal file
3
externals/tracy/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
add_library(tracy STATIC public/TracyClient.cpp)
|
||||||
|
target_include_directories(tracy PUBLIC public)
|
||||||
|
target_compile_definitions(tracy PRIVATE TRACY_ENABLE TRACY_ON_DEMAND)
|
58
externals/tracy/public/TracyClient.cpp
vendored
Normal file
58
externals/tracy/public/TracyClient.cpp
vendored
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
//
|
||||||
|
// Tracy profiler
|
||||||
|
// ----------------
|
||||||
|
//
|
||||||
|
// For fast integration, compile and
|
||||||
|
// link with this source file (and none
|
||||||
|
// other) in your executable (or in the
|
||||||
|
// main DLL / shared object on multi-DLL
|
||||||
|
// projects).
|
||||||
|
//
|
||||||
|
|
||||||
|
// Define TRACY_ENABLE to enable profiler.
|
||||||
|
|
||||||
|
#include "common/TracySystem.cpp"
|
||||||
|
|
||||||
|
#ifdef TRACY_ENABLE
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(push, 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "common/tracy_lz4.cpp"
|
||||||
|
#include "client/TracyProfiler.cpp"
|
||||||
|
#include "client/TracyCallstack.cpp"
|
||||||
|
#include "client/TracySysPower.cpp"
|
||||||
|
#include "client/TracySysTime.cpp"
|
||||||
|
#include "client/TracySysTrace.cpp"
|
||||||
|
#include "common/TracySocket.cpp"
|
||||||
|
#include "client/tracy_rpmalloc.cpp"
|
||||||
|
#include "client/TracyDxt1.cpp"
|
||||||
|
#include "client/TracyAlloc.cpp"
|
||||||
|
#include "client/TracyOverride.cpp"
|
||||||
|
|
||||||
|
#if TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 3 || TRACY_HAS_CALLSTACK == 4 || TRACY_HAS_CALLSTACK == 6
|
||||||
|
# include "libbacktrace/alloc.cpp"
|
||||||
|
# include "libbacktrace/dwarf.cpp"
|
||||||
|
# include "libbacktrace/fileline.cpp"
|
||||||
|
# include "libbacktrace/mmapio.cpp"
|
||||||
|
# include "libbacktrace/posix.cpp"
|
||||||
|
# include "libbacktrace/sort.cpp"
|
||||||
|
# include "libbacktrace/state.cpp"
|
||||||
|
# if TRACY_HAS_CALLSTACK == 4
|
||||||
|
# include "libbacktrace/macho.cpp"
|
||||||
|
# else
|
||||||
|
# include "libbacktrace/elf.cpp"
|
||||||
|
# endif
|
||||||
|
# include "common/TracyStackFrames.cpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# pragma comment(lib, "ws2_32.lib")
|
||||||
|
# pragma comment(lib, "dbghelp.lib")
|
||||||
|
# pragma comment(lib, "advapi32.lib")
|
||||||
|
# pragma comment(lib, "user32.lib")
|
||||||
|
# pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
43
externals/tracy/public/client/TracyAlloc.cpp
vendored
Normal file
43
externals/tracy/public/client/TracyAlloc.cpp
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#include "../common/TracyAlloc.hpp"
|
||||||
|
|
||||||
|
#ifdef TRACY_USE_RPMALLOC
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
#include "../common/TracyForceInline.hpp"
|
||||||
|
#include "../common/TracyYield.hpp"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
extern thread_local bool RpThreadInitDone;
|
||||||
|
extern std::atomic<int> RpInitDone;
|
||||||
|
extern std::atomic<int> RpInitLock;
|
||||||
|
|
||||||
|
tracy_no_inline static void InitRpmallocPlumbing()
|
||||||
|
{
|
||||||
|
const auto done = RpInitDone.load( std::memory_order_acquire );
|
||||||
|
if( !done )
|
||||||
|
{
|
||||||
|
int expected = 0;
|
||||||
|
while( !RpInitLock.compare_exchange_weak( expected, 1, std::memory_order_release, std::memory_order_relaxed ) ) { expected = 0; YieldThread(); }
|
||||||
|
const auto done = RpInitDone.load( std::memory_order_acquire );
|
||||||
|
if( !done )
|
||||||
|
{
|
||||||
|
rpmalloc_initialize();
|
||||||
|
RpInitDone.store( 1, std::memory_order_release );
|
||||||
|
}
|
||||||
|
RpInitLock.store( 0, std::memory_order_release );
|
||||||
|
}
|
||||||
|
rpmalloc_thread_initialize();
|
||||||
|
RpThreadInitDone = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACY_API void InitRpmalloc()
|
||||||
|
{
|
||||||
|
if( !RpThreadInitDone ) InitRpmallocPlumbing();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
419
externals/tracy/public/client/TracyArmCpuTable.hpp
vendored
Normal file
419
externals/tracy/public/client/TracyArmCpuTable.hpp
vendored
Normal file
@ -0,0 +1,419 @@
|
|||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
#if defined __linux__ && defined __ARM_ARCH
|
||||||
|
|
||||||
|
static const char* DecodeArmImplementer( uint32_t v )
|
||||||
|
{
|
||||||
|
static char buf[16];
|
||||||
|
switch( v )
|
||||||
|
{
|
||||||
|
case 0x41: return "ARM";
|
||||||
|
case 0x42: return "Broadcom";
|
||||||
|
case 0x43: return "Cavium";
|
||||||
|
case 0x44: return "DEC";
|
||||||
|
case 0x46: return "Fujitsu";
|
||||||
|
case 0x48: return "HiSilicon";
|
||||||
|
case 0x49: return "Infineon";
|
||||||
|
case 0x4d: return "Motorola";
|
||||||
|
case 0x4e: return "Nvidia";
|
||||||
|
case 0x50: return "Applied Micro";
|
||||||
|
case 0x51: return "Qualcomm";
|
||||||
|
case 0x53: return "Samsung";
|
||||||
|
case 0x54: return "Texas Instruments";
|
||||||
|
case 0x56: return "Marvell";
|
||||||
|
case 0x61: return "Apple";
|
||||||
|
case 0x66: return "Faraday";
|
||||||
|
case 0x68: return "HXT";
|
||||||
|
case 0x69: return "Intel";
|
||||||
|
case 0xc0: return "Ampere Computing";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
sprintf( buf, "0x%x", v );
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* DecodeArmPart( uint32_t impl, uint32_t part )
|
||||||
|
{
|
||||||
|
static char buf[16];
|
||||||
|
switch( impl )
|
||||||
|
{
|
||||||
|
case 0x41: // ARM
|
||||||
|
switch( part )
|
||||||
|
{
|
||||||
|
case 0x810: return "810";
|
||||||
|
case 0x920: return "920";
|
||||||
|
case 0x922: return "922";
|
||||||
|
case 0x926: return "926";
|
||||||
|
case 0x940: return "940";
|
||||||
|
case 0x946: return "946";
|
||||||
|
case 0x966: return "966";
|
||||||
|
case 0xa20: return "1020";
|
||||||
|
case 0xa22: return "1022";
|
||||||
|
case 0xa26: return "1026";
|
||||||
|
case 0xb02: return "11 MPCore";
|
||||||
|
case 0xb36: return "1136";
|
||||||
|
case 0xb56: return "1156";
|
||||||
|
case 0xb76: return "1176";
|
||||||
|
case 0xc05: return " Cortex-A5";
|
||||||
|
case 0xc07: return " Cortex-A7";
|
||||||
|
case 0xc08: return " Cortex-A8";
|
||||||
|
case 0xc09: return " Cortex-A9";
|
||||||
|
case 0xc0c: return " Cortex-A12";
|
||||||
|
case 0xc0d: return " Rockchip RK3288";
|
||||||
|
case 0xc0e: return " Cortex-A17";
|
||||||
|
case 0xc0f: return " Cortex-A15";
|
||||||
|
case 0xc14: return " Cortex-R4";
|
||||||
|
case 0xc15: return " Cortex-R5";
|
||||||
|
case 0xc17: return " Cortex-R7";
|
||||||
|
case 0xc18: return " Cortex-R8";
|
||||||
|
case 0xc20: return " Cortex-M0";
|
||||||
|
case 0xc21: return " Cortex-M1";
|
||||||
|
case 0xc23: return " Cortex-M3";
|
||||||
|
case 0xc24: return " Cortex-M4";
|
||||||
|
case 0xc27: return " Cortex-M7";
|
||||||
|
case 0xc60: return " Cortex-M0+";
|
||||||
|
case 0xd00: return " AArch64 simulator";
|
||||||
|
case 0xd01: return " Cortex-A32";
|
||||||
|
case 0xd02: return " Cortex-A34";
|
||||||
|
case 0xd03: return " Cortex-A53";
|
||||||
|
case 0xd04: return " Cortex-A35";
|
||||||
|
case 0xd05: return " Cortex-A55";
|
||||||
|
case 0xd06: return " Cortex-A65";
|
||||||
|
case 0xd07: return " Cortex-A57";
|
||||||
|
case 0xd08: return " Cortex-A72";
|
||||||
|
case 0xd09: return " Cortex-A73";
|
||||||
|
case 0xd0a: return " Cortex-A75";
|
||||||
|
case 0xd0b: return " Cortex-A76";
|
||||||
|
case 0xd0c: return " Neoverse N1";
|
||||||
|
case 0xd0d: return " Cortex-A77";
|
||||||
|
case 0xd0e: return " Cortex-A76AE";
|
||||||
|
case 0xd0f: return " AEMv8";
|
||||||
|
case 0xd13: return " Cortex-R52";
|
||||||
|
case 0xd20: return " Cortex-M23";
|
||||||
|
case 0xd21: return " Cortex-M33";
|
||||||
|
case 0xd22: return " Cortex-M55";
|
||||||
|
case 0xd40: return " Neoverse V1";
|
||||||
|
case 0xd41: return " Cortex-A78";
|
||||||
|
case 0xd42: return " Cortex-A78AE";
|
||||||
|
case 0xd43: return " Cortex-A65AE";
|
||||||
|
case 0xd44: return " Cortex-X1";
|
||||||
|
case 0xd47: return " Cortex-A710";
|
||||||
|
case 0xd48: return " Cortex-X2";
|
||||||
|
case 0xd49: return " Neoverse N2";
|
||||||
|
case 0xd4a: return " Neoverse E1";
|
||||||
|
case 0xd4b: return " Cortex-A78C";
|
||||||
|
case 0xd4c: return " Cortex-X1C";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
case 0x42: // Broadcom
|
||||||
|
switch( part )
|
||||||
|
{
|
||||||
|
case 0xf: return " Brahma B15";
|
||||||
|
case 0x100: return " Brahma B53";
|
||||||
|
case 0x516: return " ThunderX2";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
case 0x43: // Cavium
|
||||||
|
switch( part )
|
||||||
|
{
|
||||||
|
case 0xa0: return " ThunderX";
|
||||||
|
case 0xa1: return " ThunderX 88XX";
|
||||||
|
case 0xa2: return " ThunderX 81XX";
|
||||||
|
case 0xa3: return " ThunderX 83XX";
|
||||||
|
case 0xaf: return " ThunderX2 99xx";
|
||||||
|
case 0xb0: return " OcteonTX2";
|
||||||
|
case 0xb1: return " OcteonTX2 T98";
|
||||||
|
case 0xb2: return " OcteonTX2 T96";
|
||||||
|
case 0xb3: return " OcteonTX2 F95";
|
||||||
|
case 0xb4: return " OcteonTX2 F95N";
|
||||||
|
case 0xb5: return " OcteonTX2 F95MM";
|
||||||
|
case 0xb6: return " OcteonTX2 F95O";
|
||||||
|
case 0xb8: return " ThunderX3 T110";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
case 0x44: // DEC
|
||||||
|
switch( part )
|
||||||
|
{
|
||||||
|
case 0xa10: return " SA110";
|
||||||
|
case 0xa11: return " SA1100";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
case 0x46: // Fujitsu
|
||||||
|
switch( part )
|
||||||
|
{
|
||||||
|
case 0x1: return " A64FX";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
case 0x48: // HiSilicon
|
||||||
|
switch( part )
|
||||||
|
{
|
||||||
|
case 0xd01: return " TSV100";
|
||||||
|
case 0xd40: return " Kirin 980";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
case 0x4e: // Nvidia
|
||||||
|
switch( part )
|
||||||
|
{
|
||||||
|
case 0x0: return " Denver";
|
||||||
|
case 0x3: return " Denver 2";
|
||||||
|
case 0x4: return " Carmel";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
case 0x50: // Applied Micro
|
||||||
|
switch( part )
|
||||||
|
{
|
||||||
|
case 0x0: return " X-Gene";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
case 0x51: // Qualcomm
|
||||||
|
switch( part )
|
||||||
|
{
|
||||||
|
case 0xf: return " Scorpion";
|
||||||
|
case 0x2d: return " Scorpion";
|
||||||
|
case 0x4d: return " Krait";
|
||||||
|
case 0x6f: return " Krait";
|
||||||
|
case 0x200: return " Kryo";
|
||||||
|
case 0x201: return " Kryo Silver (Snapdragon 821)";
|
||||||
|
case 0x205: return " Kryo Gold";
|
||||||
|
case 0x211: return " Kryo Silver (Snapdragon 820)";
|
||||||
|
case 0x800: return " Kryo 260 / 280 Gold";
|
||||||
|
case 0x801: return " Kryo 260 / 280 Silver";
|
||||||
|
case 0x802: return " Kryo 385 Gold";
|
||||||
|
case 0x803: return " Kryo 385 Silver";
|
||||||
|
case 0x804: return " Kryo 485 Gold";
|
||||||
|
case 0x805: return " Kryo 4xx/5xx Silver";
|
||||||
|
case 0xc00: return " Falkor";
|
||||||
|
case 0xc01: return " Saphira";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
case 0x53: // Samsung
|
||||||
|
switch( part )
|
||||||
|
{
|
||||||
|
case 0x1: return " Exynos M1/M2";
|
||||||
|
case 0x2: return " Exynos M3";
|
||||||
|
case 0x3: return " Exynos M4";
|
||||||
|
case 0x4: return " Exynos M5";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
case 0x54: // Texas Instruments
|
||||||
|
switch( part )
|
||||||
|
{
|
||||||
|
case 0x925: return " TI925";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
case 0x56: // Marvell
|
||||||
|
switch( part )
|
||||||
|
{
|
||||||
|
case 0x131: return " Feroceon 88FR131";
|
||||||
|
case 0x581: return " PJ4 / PJ4B";
|
||||||
|
case 0x584: return " PJ4B-MP / PJ4C";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
case 0x61: // Apple
|
||||||
|
switch( part )
|
||||||
|
{
|
||||||
|
case 0x1: return " Cyclone";
|
||||||
|
case 0x2: return " Typhoon";
|
||||||
|
case 0x3: return " Typhoon/Capri";
|
||||||
|
case 0x4: return " Twister";
|
||||||
|
case 0x5: return " Twister/Elba/Malta";
|
||||||
|
case 0x6: return " Hurricane";
|
||||||
|
case 0x7: return " Hurricane/Myst";
|
||||||
|
case 0x22: return " M1 Icestorm";
|
||||||
|
case 0x23: return " M1 Firestorm";
|
||||||
|
case 0x24: return " M1 Icestorm Pro";
|
||||||
|
case 0x25: return " M1 Firestorm Pro";
|
||||||
|
case 0x28: return " M1 Icestorm Max";
|
||||||
|
case 0x29: return " M1 Firestorm Max";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
case 0x66: // Faraday
|
||||||
|
switch( part )
|
||||||
|
{
|
||||||
|
case 0x526: return " FA526";
|
||||||
|
case 0x626: return " FA626";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
case 0x68: // HXT
|
||||||
|
switch( part )
|
||||||
|
{
|
||||||
|
case 0x0: return " Phecda";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
case 0xc0: // Ampere Computing
|
||||||
|
switch( part )
|
||||||
|
{
|
||||||
|
case 0xac3: return " Ampere1";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
sprintf( buf, " 0x%x", part );
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined __APPLE__ && TARGET_OS_IPHONE == 1
|
||||||
|
|
||||||
|
static const char* DecodeIosDevice( const char* id )
|
||||||
|
{
|
||||||
|
static const char* DeviceTable[] = {
|
||||||
|
"i386", "32-bit simulator",
|
||||||
|
"x86_64", "64-bit simulator",
|
||||||
|
"iPhone1,1", "iPhone",
|
||||||
|
"iPhone1,2", "iPhone 3G",
|
||||||
|
"iPhone2,1", "iPhone 3GS",
|
||||||
|
"iPhone3,1", "iPhone 4 (GSM)",
|
||||||
|
"iPhone3,2", "iPhone 4 (GSM)",
|
||||||
|
"iPhone3,3", "iPhone 4 (CDMA)",
|
||||||
|
"iPhone4,1", "iPhone 4S",
|
||||||
|
"iPhone5,1", "iPhone 5 (A1428)",
|
||||||
|
"iPhone5,2", "iPhone 5 (A1429)",
|
||||||
|
"iPhone5,3", "iPhone 5c (A1456/A1532)",
|
||||||
|
"iPhone5,4", "iPhone 5c (A1507/A1516/1526/A1529)",
|
||||||
|
"iPhone6,1", "iPhone 5s (A1433/A1533)",
|
||||||
|
"iPhone6,2", "iPhone 5s (A1457/A1518/A1528/A1530)",
|
||||||
|
"iPhone7,1", "iPhone 6 Plus",
|
||||||
|
"iPhone7,2", "iPhone 6",
|
||||||
|
"iPhone8,1", "iPhone 6S",
|
||||||
|
"iPhone8,2", "iPhone 6S Plus",
|
||||||
|
"iPhone8,4", "iPhone SE",
|
||||||
|
"iPhone9,1", "iPhone 7 (CDMA)",
|
||||||
|
"iPhone9,2", "iPhone 7 Plus (CDMA)",
|
||||||
|
"iPhone9,3", "iPhone 7 (GSM)",
|
||||||
|
"iPhone9,4", "iPhone 7 Plus (GSM)",
|
||||||
|
"iPhone10,1", "iPhone 8 (CDMA)",
|
||||||
|
"iPhone10,2", "iPhone 8 Plus (CDMA)",
|
||||||
|
"iPhone10,3", "iPhone X (CDMA)",
|
||||||
|
"iPhone10,4", "iPhone 8 (GSM)",
|
||||||
|
"iPhone10,5", "iPhone 8 Plus (GSM)",
|
||||||
|
"iPhone10,6", "iPhone X (GSM)",
|
||||||
|
"iPhone11,2", "iPhone XS",
|
||||||
|
"iPhone11,4", "iPhone XS Max",
|
||||||
|
"iPhone11,6", "iPhone XS Max China",
|
||||||
|
"iPhone11,8", "iPhone XR",
|
||||||
|
"iPhone12,1", "iPhone 11",
|
||||||
|
"iPhone12,3", "iPhone 11 Pro",
|
||||||
|
"iPhone12,5", "iPhone 11 Pro Max",
|
||||||
|
"iPhone12,8", "iPhone SE 2nd Gen",
|
||||||
|
"iPhone13,1", "iPhone 12 Mini",
|
||||||
|
"iPhone13,2", "iPhone 12",
|
||||||
|
"iPhone13,3", "iPhone 12 Pro",
|
||||||
|
"iPhone13,4", "iPhone 12 Pro Max",
|
||||||
|
"iPhone14,2", "iPhone 13 Pro",
|
||||||
|
"iPhone14,3", "iPhone 13 Pro Max",
|
||||||
|
"iPhone14,4", "iPhone 13 Mini",
|
||||||
|
"iPhone14,5", "iPhone 13",
|
||||||
|
"iPhone14,6", "iPhone SE 3rd Gen",
|
||||||
|
"iPhone14,7", "iPhone 14",
|
||||||
|
"iPhone14,8", "iPhone 14 Plus",
|
||||||
|
"iPhone15,2", "iPhone 14 Pro",
|
||||||
|
"iPhone15,3", "iPhone 14 Pro Max",
|
||||||
|
"iPhone15,4", "iPhone 15",
|
||||||
|
"iPhone15,5", "iPhone 15 Plus",
|
||||||
|
"iPhone16,1", "iPhone 15 Pro",
|
||||||
|
"iPhone16,2", "iPhone 15 Pro Max",
|
||||||
|
"iPad1,1", "iPad (A1219/A1337)",
|
||||||
|
"iPad2,1", "iPad 2 (A1395)",
|
||||||
|
"iPad2,2", "iPad 2 (A1396)",
|
||||||
|
"iPad2,3", "iPad 2 (A1397)",
|
||||||
|
"iPad2,4", "iPad 2 (A1395)",
|
||||||
|
"iPad2,5", "iPad Mini (A1432)",
|
||||||
|
"iPad2,6", "iPad Mini (A1454)",
|
||||||
|
"iPad2,7", "iPad Mini (A1455)",
|
||||||
|
"iPad3,1", "iPad 3 (A1416)",
|
||||||
|
"iPad3,2", "iPad 3 (A1403)",
|
||||||
|
"iPad3,3", "iPad 3 (A1430)",
|
||||||
|
"iPad3,4", "iPad 4 (A1458)",
|
||||||
|
"iPad3,5", "iPad 4 (A1459)",
|
||||||
|
"iPad3,6", "iPad 4 (A1460)",
|
||||||
|
"iPad4,1", "iPad Air (A1474)",
|
||||||
|
"iPad4,2", "iPad Air (A1475)",
|
||||||
|
"iPad4,3", "iPad Air (A1476)",
|
||||||
|
"iPad4,4", "iPad Mini 2 (A1489)",
|
||||||
|
"iPad4,5", "iPad Mini 2 (A1490)",
|
||||||
|
"iPad4,6", "iPad Mini 2 (A1491)",
|
||||||
|
"iPad4,7", "iPad Mini 3 (A1599)",
|
||||||
|
"iPad4,8", "iPad Mini 3 (A1600)",
|
||||||
|
"iPad4,9", "iPad Mini 3 (A1601)",
|
||||||
|
"iPad5,1", "iPad Mini 4 (A1538)",
|
||||||
|
"iPad5,2", "iPad Mini 4 (A1550)",
|
||||||
|
"iPad5,3", "iPad Air 2 (A1566)",
|
||||||
|
"iPad5,4", "iPad Air 2 (A1567)",
|
||||||
|
"iPad6,3", "iPad Pro 9.7\" (A1673)",
|
||||||
|
"iPad6,4", "iPad Pro 9.7\" (A1674)",
|
||||||
|
"iPad6,5", "iPad Pro 9.7\" (A1675)",
|
||||||
|
"iPad6,7", "iPad Pro 12.9\" (A1584)",
|
||||||
|
"iPad6,8", "iPad Pro 12.9\" (A1652)",
|
||||||
|
"iPad6,11", "iPad 5th gen (A1822)",
|
||||||
|
"iPad6,12", "iPad 5th gen (A1823)",
|
||||||
|
"iPad7,1", "iPad Pro 12.9\" 2nd gen (A1670)",
|
||||||
|
"iPad7,2", "iPad Pro 12.9\" 2nd gen (A1671/A1821)",
|
||||||
|
"iPad7,3", "iPad Pro 10.5\" (A1701)",
|
||||||
|
"iPad7,4", "iPad Pro 10.5\" (A1709)",
|
||||||
|
"iPad7,5", "iPad 6th gen (A1893)",
|
||||||
|
"iPad7,6", "iPad 6th gen (A1954)",
|
||||||
|
"iPad7,11", "iPad 7th gen 10.2\" (Wifi)",
|
||||||
|
"iPad7,12", "iPad 7th gen 10.2\" (Wifi+Cellular)",
|
||||||
|
"iPad8,1", "iPad Pro 11\" (A1980)",
|
||||||
|
"iPad8,2", "iPad Pro 11\" (A1980)",
|
||||||
|
"iPad8,3", "iPad Pro 11\" (A1934/A1979/A2013)",
|
||||||
|
"iPad8,4", "iPad Pro 11\" (A1934/A1979/A2013)",
|
||||||
|
"iPad8,5", "iPad Pro 12.9\" 3rd gen (A1876)",
|
||||||
|
"iPad8,6", "iPad Pro 12.9\" 3rd gen (A1876)",
|
||||||
|
"iPad8,7", "iPad Pro 12.9\" 3rd gen (A1895/A1983/A2014)",
|
||||||
|
"iPad8,8", "iPad Pro 12.9\" 3rd gen (A1895/A1983/A2014)",
|
||||||
|
"iPad8,9", "iPad Pro 11\" 2nd gen (Wifi)",
|
||||||
|
"iPad8,10", "iPad Pro 11\" 2nd gen (Wifi+Cellular)",
|
||||||
|
"iPad8,11", "iPad Pro 12.9\" 4th gen (Wifi)",
|
||||||
|
"iPad8,12", "iPad Pro 12.9\" 4th gen (Wifi+Cellular)",
|
||||||
|
"iPad11,1", "iPad Mini 5th gen (A2133)",
|
||||||
|
"iPad11,2", "iPad Mini 5th gen (A2124/A2125/A2126)",
|
||||||
|
"iPad11,3", "iPad Air 3rd gen (A2152)",
|
||||||
|
"iPad11,4", "iPad Air 3rd gen (A2123/A2153/A2154)",
|
||||||
|
"iPad11,6", "iPad 8th gen (WiFi)",
|
||||||
|
"iPad11,7", "iPad 8th gen (WiFi+Cellular)",
|
||||||
|
"iPad12,1", "iPad 9th Gen (WiFi)",
|
||||||
|
"iPad12,2", "iPad 9th Gen (WiFi+Cellular)",
|
||||||
|
"iPad13,1", "iPad Air 4th gen (WiFi)",
|
||||||
|
"iPad13,2", "iPad Air 4th gen (WiFi+Cellular)",
|
||||||
|
"iPad13,4", "iPad Pro 11\" 3rd gen",
|
||||||
|
"iPad13,5", "iPad Pro 11\" 3rd gen",
|
||||||
|
"iPad13,6", "iPad Pro 11\" 3rd gen",
|
||||||
|
"iPad13,7", "iPad Pro 11\" 3rd gen",
|
||||||
|
"iPad13,8", "iPad Pro 12.9\" 5th gen",
|
||||||
|
"iPad13,9", "iPad Pro 12.9\" 5th gen",
|
||||||
|
"iPad13,10", "iPad Pro 12.9\" 5th gen",
|
||||||
|
"iPad13,11", "iPad Pro 12.9\" 5th gen",
|
||||||
|
"iPad13,16", "iPad Air 5th Gen (WiFi)",
|
||||||
|
"iPad13,17", "iPad Air 5th Gen (WiFi+Cellular)",
|
||||||
|
"iPad13,18", "iPad 10th Gen",
|
||||||
|
"iPad13,19", "iPad 10th Gen",
|
||||||
|
"iPad14,1", "iPad mini 6th Gen (WiFi)",
|
||||||
|
"iPad14,2", "iPad mini 6th Gen (WiFi+Cellular)",
|
||||||
|
"iPad14,3", "iPad Pro 11\" 4th Gen",
|
||||||
|
"iPad14,4", "iPad Pro 11\" 4th Gen",
|
||||||
|
"iPad14,5", "iPad Pro 12.9\" 6th Gen",
|
||||||
|
"iPad14,6", "iPad Pro 12.9\" 6th Gen",
|
||||||
|
"iPod1,1", "iPod Touch",
|
||||||
|
"iPod2,1", "iPod Touch 2nd gen",
|
||||||
|
"iPod3,1", "iPod Touch 3rd gen",
|
||||||
|
"iPod4,1", "iPod Touch 4th gen",
|
||||||
|
"iPod5,1", "iPod Touch 5th gen",
|
||||||
|
"iPod7,1", "iPod Touch 6th gen",
|
||||||
|
"iPod9,1", "iPod Touch 7th gen",
|
||||||
|
nullptr
|
||||||
|
};
|
||||||
|
|
||||||
|
auto ptr = DeviceTable;
|
||||||
|
while( *ptr )
|
||||||
|
{
|
||||||
|
if( strcmp( ptr[0], id ) == 0 ) return ptr[1];
|
||||||
|
ptr += 2;
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
1369
externals/tracy/public/client/TracyCallstack.cpp
vendored
Normal file
1369
externals/tracy/public/client/TracyCallstack.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
35
externals/tracy/public/client/TracyCallstack.h
vendored
Normal file
35
externals/tracy/public/client/TracyCallstack.h
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef __TRACYCALLSTACK_H__
|
||||||
|
#define __TRACYCALLSTACK_H__
|
||||||
|
|
||||||
|
#ifndef TRACY_NO_CALLSTACK
|
||||||
|
|
||||||
|
# if !defined _WIN32
|
||||||
|
# include <sys/param.h>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined _WIN32
|
||||||
|
# include "../common/TracyUwp.hpp"
|
||||||
|
# ifndef TRACY_UWP
|
||||||
|
# define TRACY_HAS_CALLSTACK 1
|
||||||
|
# endif
|
||||||
|
# elif defined __ANDROID__
|
||||||
|
# if !defined __arm__ || __ANDROID_API__ >= 21
|
||||||
|
# define TRACY_HAS_CALLSTACK 2
|
||||||
|
# else
|
||||||
|
# define TRACY_HAS_CALLSTACK 5
|
||||||
|
# endif
|
||||||
|
# elif defined __linux
|
||||||
|
# if defined _GNU_SOURCE && defined __GLIBC__
|
||||||
|
# define TRACY_HAS_CALLSTACK 3
|
||||||
|
# else
|
||||||
|
# define TRACY_HAS_CALLSTACK 2
|
||||||
|
# endif
|
||||||
|
# elif defined __APPLE__
|
||||||
|
# define TRACY_HAS_CALLSTACK 4
|
||||||
|
# elif defined BSD
|
||||||
|
# define TRACY_HAS_CALLSTACK 6
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
153
externals/tracy/public/client/TracyCallstack.hpp
vendored
Normal file
153
externals/tracy/public/client/TracyCallstack.hpp
vendored
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
#ifndef __TRACYCALLSTACK_HPP__
|
||||||
|
#define __TRACYCALLSTACK_HPP__
|
||||||
|
|
||||||
|
#include "../common/TracyApi.h"
|
||||||
|
#include "../common/TracyForceInline.hpp"
|
||||||
|
#include "TracyCallstack.h"
|
||||||
|
|
||||||
|
#if TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 5
|
||||||
|
# include <unwind.h>
|
||||||
|
#elif TRACY_HAS_CALLSTACK >= 3
|
||||||
|
# ifdef TRACY_LIBUNWIND_BACKTRACE
|
||||||
|
// libunwind is, in general, significantly faster than execinfo based backtraces
|
||||||
|
# define UNW_LOCAL_ONLY
|
||||||
|
# include <libunwind.h>
|
||||||
|
# else
|
||||||
|
# include <execinfo.h>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TRACY_HAS_CALLSTACK
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
static tracy_force_inline void* Callstack( int depth ) { return nullptr; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifdef TRACY_DEBUGINFOD
|
||||||
|
# include <elfutils/debuginfod.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "../common/TracyAlloc.hpp"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
struct CallstackSymbolData
|
||||||
|
{
|
||||||
|
const char* file;
|
||||||
|
uint32_t line;
|
||||||
|
bool needFree;
|
||||||
|
uint64_t symAddr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CallstackEntry
|
||||||
|
{
|
||||||
|
const char* name;
|
||||||
|
const char* file;
|
||||||
|
uint32_t line;
|
||||||
|
uint32_t symLen;
|
||||||
|
uint64_t symAddr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CallstackEntryData
|
||||||
|
{
|
||||||
|
const CallstackEntry* data;
|
||||||
|
uint8_t size;
|
||||||
|
const char* imageName;
|
||||||
|
};
|
||||||
|
|
||||||
|
CallstackSymbolData DecodeSymbolAddress( uint64_t ptr );
|
||||||
|
const char* DecodeCallstackPtrFast( uint64_t ptr );
|
||||||
|
CallstackEntryData DecodeCallstackPtr( uint64_t ptr );
|
||||||
|
void InitCallstack();
|
||||||
|
void InitCallstackCritical();
|
||||||
|
void EndCallstack();
|
||||||
|
const char* GetKernelModulePath( uint64_t addr );
|
||||||
|
|
||||||
|
#ifdef TRACY_DEBUGINFOD
|
||||||
|
const uint8_t* GetBuildIdForImage( const char* image, size_t& size );
|
||||||
|
debuginfod_client* GetDebuginfodClient();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TRACY_HAS_CALLSTACK == 1
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
typedef unsigned long (__stdcall *___tracy_t_RtlWalkFrameChain)( void**, unsigned long, unsigned long );
|
||||||
|
TRACY_API extern ___tracy_t_RtlWalkFrameChain ___tracy_RtlWalkFrameChain;
|
||||||
|
}
|
||||||
|
|
||||||
|
static tracy_force_inline void* Callstack( int depth )
|
||||||
|
{
|
||||||
|
assert( depth >= 1 && depth < 63 );
|
||||||
|
auto trace = (uintptr_t*)tracy_malloc( ( 1 + depth ) * sizeof( uintptr_t ) );
|
||||||
|
const auto num = ___tracy_RtlWalkFrameChain( (void**)( trace + 1 ), depth, 0 );
|
||||||
|
*trace = num;
|
||||||
|
return trace;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 5
|
||||||
|
|
||||||
|
struct BacktraceState
|
||||||
|
{
|
||||||
|
void** current;
|
||||||
|
void** end;
|
||||||
|
};
|
||||||
|
|
||||||
|
static _Unwind_Reason_Code tracy_unwind_callback( struct _Unwind_Context* ctx, void* arg )
|
||||||
|
{
|
||||||
|
auto state = (BacktraceState*)arg;
|
||||||
|
uintptr_t pc = _Unwind_GetIP( ctx );
|
||||||
|
if( pc )
|
||||||
|
{
|
||||||
|
if( state->current == state->end ) return _URC_END_OF_STACK;
|
||||||
|
*state->current++ = (void*)pc;
|
||||||
|
}
|
||||||
|
return _URC_NO_REASON;
|
||||||
|
}
|
||||||
|
|
||||||
|
static tracy_force_inline void* Callstack( int depth )
|
||||||
|
{
|
||||||
|
assert( depth >= 1 && depth < 63 );
|
||||||
|
|
||||||
|
auto trace = (uintptr_t*)tracy_malloc( ( 1 + depth ) * sizeof( uintptr_t ) );
|
||||||
|
BacktraceState state = { (void**)(trace+1), (void**)(trace+1+depth) };
|
||||||
|
_Unwind_Backtrace( tracy_unwind_callback, &state );
|
||||||
|
|
||||||
|
*trace = (uintptr_t*)state.current - trace + 1;
|
||||||
|
|
||||||
|
return trace;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif TRACY_HAS_CALLSTACK == 3 || TRACY_HAS_CALLSTACK == 4 || TRACY_HAS_CALLSTACK == 6
|
||||||
|
|
||||||
|
static tracy_force_inline void* Callstack( int depth )
|
||||||
|
{
|
||||||
|
assert( depth >= 1 );
|
||||||
|
|
||||||
|
auto trace = (uintptr_t*)tracy_malloc( ( 1 + (size_t)depth ) * sizeof( uintptr_t ) );
|
||||||
|
|
||||||
|
#ifdef TRACY_LIBUNWIND_BACKTRACE
|
||||||
|
size_t num = unw_backtrace( (void**)(trace+1), depth );
|
||||||
|
#else
|
||||||
|
const auto num = (size_t)backtrace( (void**)(trace+1), depth );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*trace = num;
|
||||||
|
|
||||||
|
return trace;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
12
externals/tracy/public/client/TracyCpuid.hpp
vendored
Normal file
12
externals/tracy/public/client/TracyCpuid.hpp
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef __TRACYCPUID_HPP__
|
||||||
|
#define __TRACYCPUID_HPP__
|
||||||
|
|
||||||
|
// Prior to GCC 11 the cpuid.h header did not have any include guards and thus
|
||||||
|
// including it more than once would cause a compiler error due to symbol
|
||||||
|
// redefinitions. In order to support older GCC versions, we have to wrap this
|
||||||
|
// include between custom include guards to prevent this issue.
|
||||||
|
// See also https://github.com/wolfpld/tracy/issues/452
|
||||||
|
|
||||||
|
#include <cpuid.h>
|
||||||
|
|
||||||
|
#endif
|
11
externals/tracy/public/client/TracyDebug.hpp
vendored
Normal file
11
externals/tracy/public/client/TracyDebug.hpp
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef __TRACYPRINT_HPP__
|
||||||
|
#define __TRACYPRINT_HPP__
|
||||||
|
|
||||||
|
#ifdef TRACY_VERBOSE
|
||||||
|
# include <stdio.h>
|
||||||
|
# define TracyDebug(...) fprintf( stderr, __VA_ARGS__ );
|
||||||
|
#else
|
||||||
|
# define TracyDebug(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
644
externals/tracy/public/client/TracyDxt1.cpp
vendored
Normal file
644
externals/tracy/public/client/TracyDxt1.cpp
vendored
Normal file
@ -0,0 +1,644 @@
|
|||||||
|
#include "TracyDxt1.hpp"
|
||||||
|
#include "../common/TracyForceInline.hpp"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef __ARM_NEON
|
||||||
|
# include <arm_neon.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined __AVX__ && !defined __SSE4_1__
|
||||||
|
# define __SSE4_1__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined __SSE4_1__ || defined __AVX2__
|
||||||
|
# ifdef _MSC_VER
|
||||||
|
# include <intrin.h>
|
||||||
|
# else
|
||||||
|
# include <x86intrin.h>
|
||||||
|
# ifndef _mm256_cvtsi256_si32
|
||||||
|
# define _mm256_cvtsi256_si32( v ) ( _mm_cvtsi128_si32( _mm256_castsi256_si128( v ) ) )
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
static inline uint16_t to565( uint8_t r, uint8_t g, uint8_t b )
|
||||||
|
{
|
||||||
|
return ( ( r & 0xF8 ) << 8 ) | ( ( g & 0xFC ) << 3 ) | ( b >> 3 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint16_t to565( uint32_t c )
|
||||||
|
{
|
||||||
|
return
|
||||||
|
( ( c & 0xF80000 ) >> 19 ) |
|
||||||
|
( ( c & 0x00FC00 ) >> 5 ) |
|
||||||
|
( ( c & 0x0000F8 ) << 8 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static const uint16_t DivTable[255*3+1] = {
|
||||||
|
0xffff, 0xffff, 0xffff, 0xffff, 0xcccc, 0xaaaa, 0x9249, 0x8000, 0x71c7, 0x6666, 0x5d17, 0x5555, 0x4ec4, 0x4924, 0x4444, 0x4000,
|
||||||
|
0x3c3c, 0x38e3, 0x35e5, 0x3333, 0x30c3, 0x2e8b, 0x2c85, 0x2aaa, 0x28f5, 0x2762, 0x25ed, 0x2492, 0x234f, 0x2222, 0x2108, 0x2000,
|
||||||
|
0x1f07, 0x1e1e, 0x1d41, 0x1c71, 0x1bac, 0x1af2, 0x1a41, 0x1999, 0x18f9, 0x1861, 0x17d0, 0x1745, 0x16c1, 0x1642, 0x15c9, 0x1555,
|
||||||
|
0x14e5, 0x147a, 0x1414, 0x13b1, 0x1352, 0x12f6, 0x129e, 0x1249, 0x11f7, 0x11a7, 0x115b, 0x1111, 0x10c9, 0x1084, 0x1041, 0x1000,
|
||||||
|
0x0fc0, 0x0f83, 0x0f48, 0x0f0f, 0x0ed7, 0x0ea0, 0x0e6c, 0x0e38, 0x0e07, 0x0dd6, 0x0da7, 0x0d79, 0x0d4c, 0x0d20, 0x0cf6, 0x0ccc,
|
||||||
|
0x0ca4, 0x0c7c, 0x0c56, 0x0c30, 0x0c0c, 0x0be8, 0x0bc5, 0x0ba2, 0x0b81, 0x0b60, 0x0b40, 0x0b21, 0x0b02, 0x0ae4, 0x0ac7, 0x0aaa,
|
||||||
|
0x0a8e, 0x0a72, 0x0a57, 0x0a3d, 0x0a23, 0x0a0a, 0x09f1, 0x09d8, 0x09c0, 0x09a9, 0x0991, 0x097b, 0x0964, 0x094f, 0x0939, 0x0924,
|
||||||
|
0x090f, 0x08fb, 0x08e7, 0x08d3, 0x08c0, 0x08ad, 0x089a, 0x0888, 0x0876, 0x0864, 0x0853, 0x0842, 0x0831, 0x0820, 0x0810, 0x0800,
|
||||||
|
0x07f0, 0x07e0, 0x07d1, 0x07c1, 0x07b3, 0x07a4, 0x0795, 0x0787, 0x0779, 0x076b, 0x075d, 0x0750, 0x0743, 0x0736, 0x0729, 0x071c,
|
||||||
|
0x070f, 0x0703, 0x06f7, 0x06eb, 0x06df, 0x06d3, 0x06c8, 0x06bc, 0x06b1, 0x06a6, 0x069b, 0x0690, 0x0685, 0x067b, 0x0670, 0x0666,
|
||||||
|
0x065c, 0x0652, 0x0648, 0x063e, 0x0634, 0x062b, 0x0621, 0x0618, 0x060f, 0x0606, 0x05fd, 0x05f4, 0x05eb, 0x05e2, 0x05d9, 0x05d1,
|
||||||
|
0x05c9, 0x05c0, 0x05b8, 0x05b0, 0x05a8, 0x05a0, 0x0598, 0x0590, 0x0588, 0x0581, 0x0579, 0x0572, 0x056b, 0x0563, 0x055c, 0x0555,
|
||||||
|
0x054e, 0x0547, 0x0540, 0x0539, 0x0532, 0x052b, 0x0525, 0x051e, 0x0518, 0x0511, 0x050b, 0x0505, 0x04fe, 0x04f8, 0x04f2, 0x04ec,
|
||||||
|
0x04e6, 0x04e0, 0x04da, 0x04d4, 0x04ce, 0x04c8, 0x04c3, 0x04bd, 0x04b8, 0x04b2, 0x04ad, 0x04a7, 0x04a2, 0x049c, 0x0497, 0x0492,
|
||||||
|
0x048d, 0x0487, 0x0482, 0x047d, 0x0478, 0x0473, 0x046e, 0x0469, 0x0465, 0x0460, 0x045b, 0x0456, 0x0452, 0x044d, 0x0448, 0x0444,
|
||||||
|
0x043f, 0x043b, 0x0436, 0x0432, 0x042d, 0x0429, 0x0425, 0x0421, 0x041c, 0x0418, 0x0414, 0x0410, 0x040c, 0x0408, 0x0404, 0x0400,
|
||||||
|
0x03fc, 0x03f8, 0x03f4, 0x03f0, 0x03ec, 0x03e8, 0x03e4, 0x03e0, 0x03dd, 0x03d9, 0x03d5, 0x03d2, 0x03ce, 0x03ca, 0x03c7, 0x03c3,
|
||||||
|
0x03c0, 0x03bc, 0x03b9, 0x03b5, 0x03b2, 0x03ae, 0x03ab, 0x03a8, 0x03a4, 0x03a1, 0x039e, 0x039b, 0x0397, 0x0394, 0x0391, 0x038e,
|
||||||
|
0x038b, 0x0387, 0x0384, 0x0381, 0x037e, 0x037b, 0x0378, 0x0375, 0x0372, 0x036f, 0x036c, 0x0369, 0x0366, 0x0364, 0x0361, 0x035e,
|
||||||
|
0x035b, 0x0358, 0x0355, 0x0353, 0x0350, 0x034d, 0x034a, 0x0348, 0x0345, 0x0342, 0x0340, 0x033d, 0x033a, 0x0338, 0x0335, 0x0333,
|
||||||
|
0x0330, 0x032e, 0x032b, 0x0329, 0x0326, 0x0324, 0x0321, 0x031f, 0x031c, 0x031a, 0x0317, 0x0315, 0x0313, 0x0310, 0x030e, 0x030c,
|
||||||
|
0x0309, 0x0307, 0x0305, 0x0303, 0x0300, 0x02fe, 0x02fc, 0x02fa, 0x02f7, 0x02f5, 0x02f3, 0x02f1, 0x02ef, 0x02ec, 0x02ea, 0x02e8,
|
||||||
|
0x02e6, 0x02e4, 0x02e2, 0x02e0, 0x02de, 0x02dc, 0x02da, 0x02d8, 0x02d6, 0x02d4, 0x02d2, 0x02d0, 0x02ce, 0x02cc, 0x02ca, 0x02c8,
|
||||||
|
0x02c6, 0x02c4, 0x02c2, 0x02c0, 0x02be, 0x02bc, 0x02bb, 0x02b9, 0x02b7, 0x02b5, 0x02b3, 0x02b1, 0x02b0, 0x02ae, 0x02ac, 0x02aa,
|
||||||
|
0x02a8, 0x02a7, 0x02a5, 0x02a3, 0x02a1, 0x02a0, 0x029e, 0x029c, 0x029b, 0x0299, 0x0297, 0x0295, 0x0294, 0x0292, 0x0291, 0x028f,
|
||||||
|
0x028d, 0x028c, 0x028a, 0x0288, 0x0287, 0x0285, 0x0284, 0x0282, 0x0280, 0x027f, 0x027d, 0x027c, 0x027a, 0x0279, 0x0277, 0x0276,
|
||||||
|
0x0274, 0x0273, 0x0271, 0x0270, 0x026e, 0x026d, 0x026b, 0x026a, 0x0268, 0x0267, 0x0265, 0x0264, 0x0263, 0x0261, 0x0260, 0x025e,
|
||||||
|
0x025d, 0x025c, 0x025a, 0x0259, 0x0257, 0x0256, 0x0255, 0x0253, 0x0252, 0x0251, 0x024f, 0x024e, 0x024d, 0x024b, 0x024a, 0x0249,
|
||||||
|
0x0247, 0x0246, 0x0245, 0x0243, 0x0242, 0x0241, 0x0240, 0x023e, 0x023d, 0x023c, 0x023b, 0x0239, 0x0238, 0x0237, 0x0236, 0x0234,
|
||||||
|
0x0233, 0x0232, 0x0231, 0x0230, 0x022e, 0x022d, 0x022c, 0x022b, 0x022a, 0x0229, 0x0227, 0x0226, 0x0225, 0x0224, 0x0223, 0x0222,
|
||||||
|
0x0220, 0x021f, 0x021e, 0x021d, 0x021c, 0x021b, 0x021a, 0x0219, 0x0218, 0x0216, 0x0215, 0x0214, 0x0213, 0x0212, 0x0211, 0x0210,
|
||||||
|
0x020f, 0x020e, 0x020d, 0x020c, 0x020b, 0x020a, 0x0209, 0x0208, 0x0207, 0x0206, 0x0205, 0x0204, 0x0203, 0x0202, 0x0201, 0x0200,
|
||||||
|
0x01ff, 0x01fe, 0x01fd, 0x01fc, 0x01fb, 0x01fa, 0x01f9, 0x01f8, 0x01f7, 0x01f6, 0x01f5, 0x01f4, 0x01f3, 0x01f2, 0x01f1, 0x01f0,
|
||||||
|
0x01ef, 0x01ee, 0x01ed, 0x01ec, 0x01eb, 0x01ea, 0x01e9, 0x01e9, 0x01e8, 0x01e7, 0x01e6, 0x01e5, 0x01e4, 0x01e3, 0x01e2, 0x01e1,
|
||||||
|
0x01e0, 0x01e0, 0x01df, 0x01de, 0x01dd, 0x01dc, 0x01db, 0x01da, 0x01da, 0x01d9, 0x01d8, 0x01d7, 0x01d6, 0x01d5, 0x01d4, 0x01d4,
|
||||||
|
0x01d3, 0x01d2, 0x01d1, 0x01d0, 0x01cf, 0x01cf, 0x01ce, 0x01cd, 0x01cc, 0x01cb, 0x01cb, 0x01ca, 0x01c9, 0x01c8, 0x01c7, 0x01c7,
|
||||||
|
0x01c6, 0x01c5, 0x01c4, 0x01c3, 0x01c3, 0x01c2, 0x01c1, 0x01c0, 0x01c0, 0x01bf, 0x01be, 0x01bd, 0x01bd, 0x01bc, 0x01bb, 0x01ba,
|
||||||
|
0x01ba, 0x01b9, 0x01b8, 0x01b7, 0x01b7, 0x01b6, 0x01b5, 0x01b4, 0x01b4, 0x01b3, 0x01b2, 0x01b2, 0x01b1, 0x01b0, 0x01af, 0x01af,
|
||||||
|
0x01ae, 0x01ad, 0x01ad, 0x01ac, 0x01ab, 0x01aa, 0x01aa, 0x01a9, 0x01a8, 0x01a8, 0x01a7, 0x01a6, 0x01a6, 0x01a5, 0x01a4, 0x01a4,
|
||||||
|
0x01a3, 0x01a2, 0x01a2, 0x01a1, 0x01a0, 0x01a0, 0x019f, 0x019e, 0x019e, 0x019d, 0x019c, 0x019c, 0x019b, 0x019a, 0x019a, 0x0199,
|
||||||
|
0x0198, 0x0198, 0x0197, 0x0197, 0x0196, 0x0195, 0x0195, 0x0194, 0x0193, 0x0193, 0x0192, 0x0192, 0x0191, 0x0190, 0x0190, 0x018f,
|
||||||
|
0x018f, 0x018e, 0x018d, 0x018d, 0x018c, 0x018b, 0x018b, 0x018a, 0x018a, 0x0189, 0x0189, 0x0188, 0x0187, 0x0187, 0x0186, 0x0186,
|
||||||
|
0x0185, 0x0184, 0x0184, 0x0183, 0x0183, 0x0182, 0x0182, 0x0181, 0x0180, 0x0180, 0x017f, 0x017f, 0x017e, 0x017e, 0x017d, 0x017d,
|
||||||
|
0x017c, 0x017b, 0x017b, 0x017a, 0x017a, 0x0179, 0x0179, 0x0178, 0x0178, 0x0177, 0x0177, 0x0176, 0x0175, 0x0175, 0x0174, 0x0174,
|
||||||
|
0x0173, 0x0173, 0x0172, 0x0172, 0x0171, 0x0171, 0x0170, 0x0170, 0x016f, 0x016f, 0x016e, 0x016e, 0x016d, 0x016d, 0x016c, 0x016c,
|
||||||
|
0x016b, 0x016b, 0x016a, 0x016a, 0x0169, 0x0169, 0x0168, 0x0168, 0x0167, 0x0167, 0x0166, 0x0166, 0x0165, 0x0165, 0x0164, 0x0164,
|
||||||
|
0x0163, 0x0163, 0x0162, 0x0162, 0x0161, 0x0161, 0x0160, 0x0160, 0x015f, 0x015f, 0x015e, 0x015e, 0x015d, 0x015d, 0x015d, 0x015c,
|
||||||
|
0x015c, 0x015b, 0x015b, 0x015a, 0x015a, 0x0159, 0x0159, 0x0158, 0x0158, 0x0158, 0x0157, 0x0157, 0x0156, 0x0156
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined __ARM_NEON && defined __aarch64__
|
||||||
|
static const uint16_t DivTableNEON[255*3+1] = {
|
||||||
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||||
|
0x0000, 0x1c71, 0x1af2, 0x1999, 0x1861, 0x1745, 0x1642, 0x1555, 0x147a, 0x13b1, 0x12f6, 0x1249, 0x11a7, 0x1111, 0x1084, 0x1000,
|
||||||
|
0x0f83, 0x0f0f, 0x0ea0, 0x0e38, 0x0dd6, 0x0d79, 0x0d20, 0x0ccc, 0x0c7c, 0x0c30, 0x0be8, 0x0ba2, 0x0b60, 0x0b21, 0x0ae4, 0x0aaa,
|
||||||
|
0x0a72, 0x0a3d, 0x0a0a, 0x09d8, 0x09a9, 0x097b, 0x094f, 0x0924, 0x08fb, 0x08d3, 0x08ad, 0x0888, 0x0864, 0x0842, 0x0820, 0x0800,
|
||||||
|
0x07e0, 0x07c1, 0x07a4, 0x0787, 0x076b, 0x0750, 0x0736, 0x071c, 0x0703, 0x06eb, 0x06d3, 0x06bc, 0x06a6, 0x0690, 0x067b, 0x0666,
|
||||||
|
0x0652, 0x063e, 0x062b, 0x0618, 0x0606, 0x05f4, 0x05e2, 0x05d1, 0x05c0, 0x05b0, 0x05a0, 0x0590, 0x0581, 0x0572, 0x0563, 0x0555,
|
||||||
|
0x0547, 0x0539, 0x052b, 0x051e, 0x0511, 0x0505, 0x04f8, 0x04ec, 0x04e0, 0x04d4, 0x04c8, 0x04bd, 0x04b2, 0x04a7, 0x049c, 0x0492,
|
||||||
|
0x0487, 0x047d, 0x0473, 0x0469, 0x0460, 0x0456, 0x044d, 0x0444, 0x043b, 0x0432, 0x0429, 0x0421, 0x0418, 0x0410, 0x0408, 0x0400,
|
||||||
|
0x03f8, 0x03f0, 0x03e8, 0x03e0, 0x03d9, 0x03d2, 0x03ca, 0x03c3, 0x03bc, 0x03b5, 0x03ae, 0x03a8, 0x03a1, 0x039b, 0x0394, 0x038e,
|
||||||
|
0x0387, 0x0381, 0x037b, 0x0375, 0x036f, 0x0369, 0x0364, 0x035e, 0x0358, 0x0353, 0x034d, 0x0348, 0x0342, 0x033d, 0x0338, 0x0333,
|
||||||
|
0x032e, 0x0329, 0x0324, 0x031f, 0x031a, 0x0315, 0x0310, 0x030c, 0x0307, 0x0303, 0x02fe, 0x02fa, 0x02f5, 0x02f1, 0x02ec, 0x02e8,
|
||||||
|
0x02e4, 0x02e0, 0x02dc, 0x02d8, 0x02d4, 0x02d0, 0x02cc, 0x02c8, 0x02c4, 0x02c0, 0x02bc, 0x02b9, 0x02b5, 0x02b1, 0x02ae, 0x02aa,
|
||||||
|
0x02a7, 0x02a3, 0x02a0, 0x029c, 0x0299, 0x0295, 0x0292, 0x028f, 0x028c, 0x0288, 0x0285, 0x0282, 0x027f, 0x027c, 0x0279, 0x0276,
|
||||||
|
0x0273, 0x0270, 0x026d, 0x026a, 0x0267, 0x0264, 0x0261, 0x025e, 0x025c, 0x0259, 0x0256, 0x0253, 0x0251, 0x024e, 0x024b, 0x0249,
|
||||||
|
0x0246, 0x0243, 0x0241, 0x023e, 0x023c, 0x0239, 0x0237, 0x0234, 0x0232, 0x0230, 0x022d, 0x022b, 0x0229, 0x0226, 0x0224, 0x0222,
|
||||||
|
0x021f, 0x021d, 0x021b, 0x0219, 0x0216, 0x0214, 0x0212, 0x0210, 0x020e, 0x020c, 0x020a, 0x0208, 0x0206, 0x0204, 0x0202, 0x0200,
|
||||||
|
0x01fe, 0x01fc, 0x01fa, 0x01f8, 0x01f6, 0x01f4, 0x01f2, 0x01f0, 0x01ee, 0x01ec, 0x01ea, 0x01e9, 0x01e7, 0x01e5, 0x01e3, 0x01e1,
|
||||||
|
0x01e0, 0x01de, 0x01dc, 0x01da, 0x01d9, 0x01d7, 0x01d5, 0x01d4, 0x01d2, 0x01d0, 0x01cf, 0x01cd, 0x01cb, 0x01ca, 0x01c8, 0x01c7,
|
||||||
|
0x01c5, 0x01c3, 0x01c2, 0x01c0, 0x01bf, 0x01bd, 0x01bc, 0x01ba, 0x01b9, 0x01b7, 0x01b6, 0x01b4, 0x01b3, 0x01b2, 0x01b0, 0x01af,
|
||||||
|
0x01ad, 0x01ac, 0x01aa, 0x01a9, 0x01a8, 0x01a6, 0x01a5, 0x01a4, 0x01a2, 0x01a1, 0x01a0, 0x019e, 0x019d, 0x019c, 0x019a, 0x0199,
|
||||||
|
0x0198, 0x0197, 0x0195, 0x0194, 0x0193, 0x0192, 0x0190, 0x018f, 0x018e, 0x018d, 0x018b, 0x018a, 0x0189, 0x0188, 0x0187, 0x0186,
|
||||||
|
0x0184, 0x0183, 0x0182, 0x0181, 0x0180, 0x017f, 0x017e, 0x017d, 0x017b, 0x017a, 0x0179, 0x0178, 0x0177, 0x0176, 0x0175, 0x0174,
|
||||||
|
0x0173, 0x0172, 0x0171, 0x0170, 0x016f, 0x016e, 0x016d, 0x016c, 0x016b, 0x016a, 0x0169, 0x0168, 0x0167, 0x0166, 0x0165, 0x0164,
|
||||||
|
0x0163, 0x0162, 0x0161, 0x0160, 0x015f, 0x015e, 0x015d, 0x015c, 0x015b, 0x015a, 0x0159, 0x0158, 0x0158, 0x0157, 0x0156, 0x0155,
|
||||||
|
0x0154, 0x0153, 0x0152, 0x0151, 0x0150, 0x0150, 0x014f, 0x014e, 0x014d, 0x014c, 0x014b, 0x014a, 0x014a, 0x0149, 0x0148, 0x0147,
|
||||||
|
0x0146, 0x0146, 0x0145, 0x0144, 0x0143, 0x0142, 0x0142, 0x0141, 0x0140, 0x013f, 0x013e, 0x013e, 0x013d, 0x013c, 0x013b, 0x013b,
|
||||||
|
0x013a, 0x0139, 0x0138, 0x0138, 0x0137, 0x0136, 0x0135, 0x0135, 0x0134, 0x0133, 0x0132, 0x0132, 0x0131, 0x0130, 0x0130, 0x012f,
|
||||||
|
0x012e, 0x012e, 0x012d, 0x012c, 0x012b, 0x012b, 0x012a, 0x0129, 0x0129, 0x0128, 0x0127, 0x0127, 0x0126, 0x0125, 0x0125, 0x0124,
|
||||||
|
0x0123, 0x0123, 0x0122, 0x0121, 0x0121, 0x0120, 0x0120, 0x011f, 0x011e, 0x011e, 0x011d, 0x011c, 0x011c, 0x011b, 0x011b, 0x011a,
|
||||||
|
0x0119, 0x0119, 0x0118, 0x0118, 0x0117, 0x0116, 0x0116, 0x0115, 0x0115, 0x0114, 0x0113, 0x0113, 0x0112, 0x0112, 0x0111, 0x0111,
|
||||||
|
0x0110, 0x010f, 0x010f, 0x010e, 0x010e, 0x010d, 0x010d, 0x010c, 0x010c, 0x010b, 0x010a, 0x010a, 0x0109, 0x0109, 0x0108, 0x0108,
|
||||||
|
0x0107, 0x0107, 0x0106, 0x0106, 0x0105, 0x0105, 0x0104, 0x0104, 0x0103, 0x0103, 0x0102, 0x0102, 0x0101, 0x0101, 0x0100, 0x0100,
|
||||||
|
0x00ff, 0x00ff, 0x00fe, 0x00fe, 0x00fd, 0x00fd, 0x00fc, 0x00fc, 0x00fb, 0x00fb, 0x00fa, 0x00fa, 0x00f9, 0x00f9, 0x00f8, 0x00f8,
|
||||||
|
0x00f7, 0x00f7, 0x00f6, 0x00f6, 0x00f5, 0x00f5, 0x00f4, 0x00f4, 0x00f4, 0x00f3, 0x00f3, 0x00f2, 0x00f2, 0x00f1, 0x00f1, 0x00f0,
|
||||||
|
0x00f0, 0x00f0, 0x00ef, 0x00ef, 0x00ee, 0x00ee, 0x00ed, 0x00ed, 0x00ed, 0x00ec, 0x00ec, 0x00eb, 0x00eb, 0x00ea, 0x00ea, 0x00ea,
|
||||||
|
0x00e9, 0x00e9, 0x00e8, 0x00e8, 0x00e7, 0x00e7, 0x00e7, 0x00e6, 0x00e6, 0x00e5, 0x00e5, 0x00e5, 0x00e4, 0x00e4, 0x00e3, 0x00e3,
|
||||||
|
0x00e3, 0x00e2, 0x00e2, 0x00e1, 0x00e1, 0x00e1, 0x00e0, 0x00e0, 0x00e0, 0x00df, 0x00df, 0x00de, 0x00de, 0x00de, 0x00dd, 0x00dd,
|
||||||
|
0x00dd, 0x00dc, 0x00dc, 0x00db, 0x00db, 0x00db, 0x00da, 0x00da, 0x00da, 0x00d9, 0x00d9, 0x00d9, 0x00d8, 0x00d8, 0x00d7, 0x00d7,
|
||||||
|
0x00d7, 0x00d6, 0x00d6, 0x00d6, 0x00d5, 0x00d5, 0x00d5, 0x00d4, 0x00d4, 0x00d4, 0x00d3, 0x00d3, 0x00d3, 0x00d2, 0x00d2, 0x00d2,
|
||||||
|
0x00d1, 0x00d1, 0x00d1, 0x00d0, 0x00d0, 0x00d0, 0x00cf, 0x00cf, 0x00cf, 0x00ce, 0x00ce, 0x00ce, 0x00cd, 0x00cd, 0x00cd, 0x00cc,
|
||||||
|
0x00cc, 0x00cc, 0x00cb, 0x00cb, 0x00cb, 0x00ca, 0x00ca, 0x00ca, 0x00c9, 0x00c9, 0x00c9, 0x00c9, 0x00c8, 0x00c8, 0x00c8, 0x00c7,
|
||||||
|
0x00c7, 0x00c7, 0x00c6, 0x00c6, 0x00c6, 0x00c5, 0x00c5, 0x00c5, 0x00c5, 0x00c4, 0x00c4, 0x00c4, 0x00c3, 0x00c3, 0x00c3, 0x00c3,
|
||||||
|
0x00c2, 0x00c2, 0x00c2, 0x00c1, 0x00c1, 0x00c1, 0x00c1, 0x00c0, 0x00c0, 0x00c0, 0x00bf, 0x00bf, 0x00bf, 0x00bf, 0x00be, 0x00be,
|
||||||
|
0x00be, 0x00bd, 0x00bd, 0x00bd, 0x00bd, 0x00bc, 0x00bc, 0x00bc, 0x00bc, 0x00bb, 0x00bb, 0x00bb, 0x00ba, 0x00ba, 0x00ba, 0x00ba,
|
||||||
|
0x00b9, 0x00b9, 0x00b9, 0x00b9, 0x00b8, 0x00b8, 0x00b8, 0x00b8, 0x00b7, 0x00b7, 0x00b7, 0x00b7, 0x00b6, 0x00b6, 0x00b6, 0x00b6,
|
||||||
|
0x00b5, 0x00b5, 0x00b5, 0x00b5, 0x00b4, 0x00b4, 0x00b4, 0x00b4, 0x00b3, 0x00b3, 0x00b3, 0x00b3, 0x00b2, 0x00b2, 0x00b2, 0x00b2,
|
||||||
|
0x00b1, 0x00b1, 0x00b1, 0x00b1, 0x00b0, 0x00b0, 0x00b0, 0x00b0, 0x00af, 0x00af, 0x00af, 0x00af, 0x00ae, 0x00ae, 0x00ae, 0x00ae,
|
||||||
|
0x00ae, 0x00ad, 0x00ad, 0x00ad, 0x00ad, 0x00ac, 0x00ac, 0x00ac, 0x00ac, 0x00ac, 0x00ab, 0x00ab, 0x00ab, 0x00ab,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static tracy_force_inline uint64_t ProcessRGB( const uint8_t* src )
|
||||||
|
{
|
||||||
|
#ifdef __SSE4_1__
|
||||||
|
__m128i px0 = _mm_loadu_si128(((__m128i*)src) + 0);
|
||||||
|
__m128i px1 = _mm_loadu_si128(((__m128i*)src) + 1);
|
||||||
|
__m128i px2 = _mm_loadu_si128(((__m128i*)src) + 2);
|
||||||
|
__m128i px3 = _mm_loadu_si128(((__m128i*)src) + 3);
|
||||||
|
|
||||||
|
__m128i smask = _mm_set1_epi32( 0xF8FCF8 );
|
||||||
|
__m128i sd0 = _mm_and_si128( px0, smask );
|
||||||
|
__m128i sd1 = _mm_and_si128( px1, smask );
|
||||||
|
__m128i sd2 = _mm_and_si128( px2, smask );
|
||||||
|
__m128i sd3 = _mm_and_si128( px3, smask );
|
||||||
|
|
||||||
|
__m128i sc = _mm_shuffle_epi32(sd0, _MM_SHUFFLE(0, 0, 0, 0));
|
||||||
|
|
||||||
|
__m128i sc0 = _mm_cmpeq_epi8(sd0, sc);
|
||||||
|
__m128i sc1 = _mm_cmpeq_epi8(sd1, sc);
|
||||||
|
__m128i sc2 = _mm_cmpeq_epi8(sd2, sc);
|
||||||
|
__m128i sc3 = _mm_cmpeq_epi8(sd3, sc);
|
||||||
|
|
||||||
|
__m128i sm0 = _mm_and_si128(sc0, sc1);
|
||||||
|
__m128i sm1 = _mm_and_si128(sc2, sc3);
|
||||||
|
__m128i sm = _mm_and_si128(sm0, sm1);
|
||||||
|
|
||||||
|
if( _mm_testc_si128(sm, _mm_set1_epi32(-1)) )
|
||||||
|
{
|
||||||
|
return uint64_t( to565( src[0], src[1], src[2] ) ) << 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
__m128i amask = _mm_set1_epi32( 0xFFFFFF );
|
||||||
|
px0 = _mm_and_si128( px0, amask );
|
||||||
|
px1 = _mm_and_si128( px1, amask );
|
||||||
|
px2 = _mm_and_si128( px2, amask );
|
||||||
|
px3 = _mm_and_si128( px3, amask );
|
||||||
|
|
||||||
|
__m128i min0 = _mm_min_epu8( px0, px1 );
|
||||||
|
__m128i min1 = _mm_min_epu8( px2, px3 );
|
||||||
|
__m128i min2 = _mm_min_epu8( min0, min1 );
|
||||||
|
|
||||||
|
__m128i max0 = _mm_max_epu8( px0, px1 );
|
||||||
|
__m128i max1 = _mm_max_epu8( px2, px3 );
|
||||||
|
__m128i max2 = _mm_max_epu8( max0, max1 );
|
||||||
|
|
||||||
|
__m128i min3 = _mm_shuffle_epi32( min2, _MM_SHUFFLE( 2, 3, 0, 1 ) );
|
||||||
|
__m128i max3 = _mm_shuffle_epi32( max2, _MM_SHUFFLE( 2, 3, 0, 1 ) );
|
||||||
|
__m128i min4 = _mm_min_epu8( min2, min3 );
|
||||||
|
__m128i max4 = _mm_max_epu8( max2, max3 );
|
||||||
|
|
||||||
|
__m128i min5 = _mm_shuffle_epi32( min4, _MM_SHUFFLE( 0, 0, 2, 2 ) );
|
||||||
|
__m128i max5 = _mm_shuffle_epi32( max4, _MM_SHUFFLE( 0, 0, 2, 2 ) );
|
||||||
|
__m128i rmin = _mm_min_epu8( min4, min5 );
|
||||||
|
__m128i rmax = _mm_max_epu8( max4, max5 );
|
||||||
|
|
||||||
|
__m128i range1 = _mm_subs_epu8( rmax, rmin );
|
||||||
|
__m128i range2 = _mm_sad_epu8( rmax, rmin );
|
||||||
|
|
||||||
|
uint32_t vrange = _mm_cvtsi128_si32( range2 ) >> 1;
|
||||||
|
__m128i range = _mm_set1_epi16( DivTable[vrange] );
|
||||||
|
|
||||||
|
__m128i inset1 = _mm_srli_epi16( range1, 4 );
|
||||||
|
__m128i inset = _mm_and_si128( inset1, _mm_set1_epi8( 0xF ) );
|
||||||
|
__m128i min = _mm_adds_epu8( rmin, inset );
|
||||||
|
__m128i max = _mm_subs_epu8( rmax, inset );
|
||||||
|
|
||||||
|
__m128i c0 = _mm_subs_epu8( px0, rmin );
|
||||||
|
__m128i c1 = _mm_subs_epu8( px1, rmin );
|
||||||
|
__m128i c2 = _mm_subs_epu8( px2, rmin );
|
||||||
|
__m128i c3 = _mm_subs_epu8( px3, rmin );
|
||||||
|
|
||||||
|
__m128i is0 = _mm_maddubs_epi16( c0, _mm_set1_epi8( 1 ) );
|
||||||
|
__m128i is1 = _mm_maddubs_epi16( c1, _mm_set1_epi8( 1 ) );
|
||||||
|
__m128i is2 = _mm_maddubs_epi16( c2, _mm_set1_epi8( 1 ) );
|
||||||
|
__m128i is3 = _mm_maddubs_epi16( c3, _mm_set1_epi8( 1 ) );
|
||||||
|
|
||||||
|
__m128i s0 = _mm_hadd_epi16( is0, is1 );
|
||||||
|
__m128i s1 = _mm_hadd_epi16( is2, is3 );
|
||||||
|
|
||||||
|
__m128i m0 = _mm_mulhi_epu16( s0, range );
|
||||||
|
__m128i m1 = _mm_mulhi_epu16( s1, range );
|
||||||
|
|
||||||
|
__m128i p0 = _mm_packus_epi16( m0, m1 );
|
||||||
|
|
||||||
|
__m128i p1 = _mm_or_si128( _mm_srai_epi32( p0, 6 ), _mm_srai_epi32( p0, 12 ) );
|
||||||
|
__m128i p2 = _mm_or_si128( _mm_srai_epi32( p0, 18 ), p0 );
|
||||||
|
__m128i p3 = _mm_or_si128( p1, p2 );
|
||||||
|
__m128i p =_mm_shuffle_epi8( p3, _mm_set1_epi32( 0x0C080400 ) );
|
||||||
|
|
||||||
|
uint32_t vmin = _mm_cvtsi128_si32( min );
|
||||||
|
uint32_t vmax = _mm_cvtsi128_si32( max );
|
||||||
|
uint32_t vp = _mm_cvtsi128_si32( p );
|
||||||
|
|
||||||
|
return uint64_t( ( uint64_t( to565( vmin ) ) << 16 ) | to565( vmax ) | ( uint64_t( vp ) << 32 ) );
|
||||||
|
#elif defined __ARM_NEON
|
||||||
|
# ifdef __aarch64__
|
||||||
|
uint8x16x4_t px = vld4q_u8( src );
|
||||||
|
|
||||||
|
uint8x16_t lr = px.val[0];
|
||||||
|
uint8x16_t lg = px.val[1];
|
||||||
|
uint8x16_t lb = px.val[2];
|
||||||
|
|
||||||
|
uint8_t rmaxr = vmaxvq_u8( lr );
|
||||||
|
uint8_t rmaxg = vmaxvq_u8( lg );
|
||||||
|
uint8_t rmaxb = vmaxvq_u8( lb );
|
||||||
|
|
||||||
|
uint8_t rminr = vminvq_u8( lr );
|
||||||
|
uint8_t rming = vminvq_u8( lg );
|
||||||
|
uint8_t rminb = vminvq_u8( lb );
|
||||||
|
|
||||||
|
int rr = rmaxr - rminr;
|
||||||
|
int rg = rmaxg - rming;
|
||||||
|
int rb = rmaxb - rminb;
|
||||||
|
|
||||||
|
int vrange1 = rr + rg + rb;
|
||||||
|
uint16_t vrange2 = DivTableNEON[vrange1];
|
||||||
|
|
||||||
|
uint8_t insetr = rr >> 4;
|
||||||
|
uint8_t insetg = rg >> 4;
|
||||||
|
uint8_t insetb = rb >> 4;
|
||||||
|
|
||||||
|
uint8_t minr = rminr + insetr;
|
||||||
|
uint8_t ming = rming + insetg;
|
||||||
|
uint8_t minb = rminb + insetb;
|
||||||
|
|
||||||
|
uint8_t maxr = rmaxr - insetr;
|
||||||
|
uint8_t maxg = rmaxg - insetg;
|
||||||
|
uint8_t maxb = rmaxb - insetb;
|
||||||
|
|
||||||
|
uint8x16_t cr = vsubq_u8( lr, vdupq_n_u8( rminr ) );
|
||||||
|
uint8x16_t cg = vsubq_u8( lg, vdupq_n_u8( rming ) );
|
||||||
|
uint8x16_t cb = vsubq_u8( lb, vdupq_n_u8( rminb ) );
|
||||||
|
|
||||||
|
uint16x8_t is0l = vaddl_u8( vget_low_u8( cr ), vget_low_u8( cg ) );
|
||||||
|
uint16x8_t is0h = vaddl_u8( vget_high_u8( cr ), vget_high_u8( cg ) );
|
||||||
|
uint16x8_t is1l = vaddw_u8( is0l, vget_low_u8( cb ) );
|
||||||
|
uint16x8_t is1h = vaddw_u8( is0h, vget_high_u8( cb ) );
|
||||||
|
|
||||||
|
int16x8_t range = vdupq_n_s16( vrange2 );
|
||||||
|
uint16x8_t m0 = vreinterpretq_u16_s16( vqdmulhq_s16( vreinterpretq_s16_u16( is1l ), range ) );
|
||||||
|
uint16x8_t m1 = vreinterpretq_u16_s16( vqdmulhq_s16( vreinterpretq_s16_u16( is1h ), range ) );
|
||||||
|
|
||||||
|
uint8x8_t p00 = vmovn_u16( m0 );
|
||||||
|
uint8x8_t p01 = vmovn_u16( m1 );
|
||||||
|
uint8x16_t p0 = vcombine_u8( p00, p01 );
|
||||||
|
|
||||||
|
uint32x4_t p1 = vaddq_u32( vshrq_n_u32( vreinterpretq_u32_u8( p0 ), 6 ), vshrq_n_u32( vreinterpretq_u32_u8( p0 ), 12 ) );
|
||||||
|
uint32x4_t p2 = vaddq_u32( vshrq_n_u32( vreinterpretq_u32_u8( p0 ), 18 ), vreinterpretq_u32_u8( p0 ) );
|
||||||
|
uint32x4_t p3 = vaddq_u32( p1, p2 );
|
||||||
|
|
||||||
|
uint16x4x2_t p4 = vuzp_u16( vget_low_u16( vreinterpretq_u16_u32( p3 ) ), vget_high_u16( vreinterpretq_u16_u32( p3 ) ) );
|
||||||
|
uint8x8x2_t p = vuzp_u8( vreinterpret_u8_u16( p4.val[0] ), vreinterpret_u8_u16( p4.val[0] ) );
|
||||||
|
|
||||||
|
uint32_t vp;
|
||||||
|
vst1_lane_u32( &vp, vreinterpret_u32_u8( p.val[0] ), 0 );
|
||||||
|
|
||||||
|
return uint64_t( ( uint64_t( to565( minr, ming, minb ) ) << 16 ) | to565( maxr, maxg, maxb ) | ( uint64_t( vp ) << 32 ) );
|
||||||
|
# else
|
||||||
|
uint32x4_t px0 = vld1q_u32( (uint32_t*)src );
|
||||||
|
uint32x4_t px1 = vld1q_u32( (uint32_t*)src + 4 );
|
||||||
|
uint32x4_t px2 = vld1q_u32( (uint32_t*)src + 8 );
|
||||||
|
uint32x4_t px3 = vld1q_u32( (uint32_t*)src + 12 );
|
||||||
|
|
||||||
|
uint32x4_t smask = vdupq_n_u32( 0xF8FCF8 );
|
||||||
|
uint32x4_t sd0 = vandq_u32( smask, px0 );
|
||||||
|
uint32x4_t sd1 = vandq_u32( smask, px1 );
|
||||||
|
uint32x4_t sd2 = vandq_u32( smask, px2 );
|
||||||
|
uint32x4_t sd3 = vandq_u32( smask, px3 );
|
||||||
|
|
||||||
|
uint32x4_t sc = vdupq_n_u32( sd0[0] );
|
||||||
|
|
||||||
|
uint32x4_t sc0 = vceqq_u32( sd0, sc );
|
||||||
|
uint32x4_t sc1 = vceqq_u32( sd1, sc );
|
||||||
|
uint32x4_t sc2 = vceqq_u32( sd2, sc );
|
||||||
|
uint32x4_t sc3 = vceqq_u32( sd3, sc );
|
||||||
|
|
||||||
|
uint32x4_t sm0 = vandq_u32( sc0, sc1 );
|
||||||
|
uint32x4_t sm1 = vandq_u32( sc2, sc3 );
|
||||||
|
int64x2_t sm = vreinterpretq_s64_u32( vandq_u32( sm0, sm1 ) );
|
||||||
|
|
||||||
|
if( sm[0] == -1 && sm[1] == -1 )
|
||||||
|
{
|
||||||
|
return uint64_t( to565( src[0], src[1], src[2] ) ) << 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32x4_t mask = vdupq_n_u32( 0xFFFFFF );
|
||||||
|
uint8x16_t l0 = vreinterpretq_u8_u32( vandq_u32( mask, px0 ) );
|
||||||
|
uint8x16_t l1 = vreinterpretq_u8_u32( vandq_u32( mask, px1 ) );
|
||||||
|
uint8x16_t l2 = vreinterpretq_u8_u32( vandq_u32( mask, px2 ) );
|
||||||
|
uint8x16_t l3 = vreinterpretq_u8_u32( vandq_u32( mask, px3 ) );
|
||||||
|
|
||||||
|
uint8x16_t min0 = vminq_u8( l0, l1 );
|
||||||
|
uint8x16_t min1 = vminq_u8( l2, l3 );
|
||||||
|
uint8x16_t min2 = vminq_u8( min0, min1 );
|
||||||
|
|
||||||
|
uint8x16_t max0 = vmaxq_u8( l0, l1 );
|
||||||
|
uint8x16_t max1 = vmaxq_u8( l2, l3 );
|
||||||
|
uint8x16_t max2 = vmaxq_u8( max0, max1 );
|
||||||
|
|
||||||
|
uint8x16_t min3 = vreinterpretq_u8_u32( vrev64q_u32( vreinterpretq_u32_u8( min2 ) ) );
|
||||||
|
uint8x16_t max3 = vreinterpretq_u8_u32( vrev64q_u32( vreinterpretq_u32_u8( max2 ) ) );
|
||||||
|
|
||||||
|
uint8x16_t min4 = vminq_u8( min2, min3 );
|
||||||
|
uint8x16_t max4 = vmaxq_u8( max2, max3 );
|
||||||
|
|
||||||
|
uint8x16_t min5 = vcombine_u8( vget_high_u8( min4 ), vget_low_u8( min4 ) );
|
||||||
|
uint8x16_t max5 = vcombine_u8( vget_high_u8( max4 ), vget_low_u8( max4 ) );
|
||||||
|
|
||||||
|
uint8x16_t rmin = vminq_u8( min4, min5 );
|
||||||
|
uint8x16_t rmax = vmaxq_u8( max4, max5 );
|
||||||
|
|
||||||
|
uint8x16_t range1 = vsubq_u8( rmax, rmin );
|
||||||
|
uint8x8_t range2 = vget_low_u8( range1 );
|
||||||
|
uint8x8x2_t range3 = vzip_u8( range2, vdup_n_u8( 0 ) );
|
||||||
|
uint16x4_t range4 = vreinterpret_u16_u8( range3.val[0] );
|
||||||
|
|
||||||
|
uint16_t vrange1;
|
||||||
|
uint16x4_t range5 = vpadd_u16( range4, range4 );
|
||||||
|
uint16x4_t range6 = vpadd_u16( range5, range5 );
|
||||||
|
vst1_lane_u16( &vrange1, range6, 0 );
|
||||||
|
|
||||||
|
uint32_t vrange2 = ( 2 << 16 ) / uint32_t( vrange1 + 1 );
|
||||||
|
uint16x8_t range = vdupq_n_u16( vrange2 );
|
||||||
|
|
||||||
|
uint8x16_t inset = vshrq_n_u8( range1, 4 );
|
||||||
|
uint8x16_t min = vaddq_u8( rmin, inset );
|
||||||
|
uint8x16_t max = vsubq_u8( rmax, inset );
|
||||||
|
|
||||||
|
uint8x16_t c0 = vsubq_u8( l0, rmin );
|
||||||
|
uint8x16_t c1 = vsubq_u8( l1, rmin );
|
||||||
|
uint8x16_t c2 = vsubq_u8( l2, rmin );
|
||||||
|
uint8x16_t c3 = vsubq_u8( l3, rmin );
|
||||||
|
|
||||||
|
uint16x8_t is0 = vpaddlq_u8( c0 );
|
||||||
|
uint16x8_t is1 = vpaddlq_u8( c1 );
|
||||||
|
uint16x8_t is2 = vpaddlq_u8( c2 );
|
||||||
|
uint16x8_t is3 = vpaddlq_u8( c3 );
|
||||||
|
|
||||||
|
uint16x4_t is4 = vpadd_u16( vget_low_u16( is0 ), vget_high_u16( is0 ) );
|
||||||
|
uint16x4_t is5 = vpadd_u16( vget_low_u16( is1 ), vget_high_u16( is1 ) );
|
||||||
|
uint16x4_t is6 = vpadd_u16( vget_low_u16( is2 ), vget_high_u16( is2 ) );
|
||||||
|
uint16x4_t is7 = vpadd_u16( vget_low_u16( is3 ), vget_high_u16( is3 ) );
|
||||||
|
|
||||||
|
uint16x8_t s0 = vcombine_u16( is4, is5 );
|
||||||
|
uint16x8_t s1 = vcombine_u16( is6, is7 );
|
||||||
|
|
||||||
|
uint16x8_t m0 = vreinterpretq_u16_s16( vqdmulhq_s16( vreinterpretq_s16_u16( s0 ), vreinterpretq_s16_u16( range ) ) );
|
||||||
|
uint16x8_t m1 = vreinterpretq_u16_s16( vqdmulhq_s16( vreinterpretq_s16_u16( s1 ), vreinterpretq_s16_u16( range ) ) );
|
||||||
|
|
||||||
|
uint8x8_t p00 = vmovn_u16( m0 );
|
||||||
|
uint8x8_t p01 = vmovn_u16( m1 );
|
||||||
|
uint8x16_t p0 = vcombine_u8( p00, p01 );
|
||||||
|
|
||||||
|
uint32x4_t p1 = vaddq_u32( vshrq_n_u32( vreinterpretq_u32_u8( p0 ), 6 ), vshrq_n_u32( vreinterpretq_u32_u8( p0 ), 12 ) );
|
||||||
|
uint32x4_t p2 = vaddq_u32( vshrq_n_u32( vreinterpretq_u32_u8( p0 ), 18 ), vreinterpretq_u32_u8( p0 ) );
|
||||||
|
uint32x4_t p3 = vaddq_u32( p1, p2 );
|
||||||
|
|
||||||
|
uint16x4x2_t p4 = vuzp_u16( vget_low_u16( vreinterpretq_u16_u32( p3 ) ), vget_high_u16( vreinterpretq_u16_u32( p3 ) ) );
|
||||||
|
uint8x8x2_t p = vuzp_u8( vreinterpret_u8_u16( p4.val[0] ), vreinterpret_u8_u16( p4.val[0] ) );
|
||||||
|
|
||||||
|
uint32_t vmin, vmax, vp;
|
||||||
|
vst1q_lane_u32( &vmin, vreinterpretq_u32_u8( min ), 0 );
|
||||||
|
vst1q_lane_u32( &vmax, vreinterpretq_u32_u8( max ), 0 );
|
||||||
|
vst1_lane_u32( &vp, vreinterpret_u32_u8( p.val[0] ), 0 );
|
||||||
|
|
||||||
|
return uint64_t( ( uint64_t( to565( vmin ) ) << 16 ) | to565( vmax ) | ( uint64_t( vp ) << 32 ) );
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
uint32_t ref;
|
||||||
|
memcpy( &ref, src, 4 );
|
||||||
|
uint32_t refMask = ref & 0xF8FCF8;
|
||||||
|
auto stmp = src + 4;
|
||||||
|
for( int i=1; i<16; i++ )
|
||||||
|
{
|
||||||
|
uint32_t px;
|
||||||
|
memcpy( &px, stmp, 4 );
|
||||||
|
if( ( px & 0xF8FCF8 ) != refMask ) break;
|
||||||
|
stmp += 4;
|
||||||
|
}
|
||||||
|
if( stmp == src + 64 )
|
||||||
|
{
|
||||||
|
return uint64_t( to565( ref ) ) << 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t min[3] = { src[0], src[1], src[2] };
|
||||||
|
uint8_t max[3] = { src[0], src[1], src[2] };
|
||||||
|
auto tmp = src + 4;
|
||||||
|
for( int i=1; i<16; i++ )
|
||||||
|
{
|
||||||
|
for( int j=0; j<3; j++ )
|
||||||
|
{
|
||||||
|
if( tmp[j] < min[j] ) min[j] = tmp[j];
|
||||||
|
else if( tmp[j] > max[j] ) max[j] = tmp[j];
|
||||||
|
}
|
||||||
|
tmp += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t range = DivTable[max[0] - min[0] + max[1] - min[1] + max[2] - min[2]];
|
||||||
|
const uint32_t rmin = min[0] + min[1] + min[2];
|
||||||
|
for( int i=0; i<3; i++ )
|
||||||
|
{
|
||||||
|
const uint8_t inset = ( max[i] - min[i] ) >> 4;
|
||||||
|
min[i] += inset;
|
||||||
|
max[i] -= inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t data = 0;
|
||||||
|
for( int i=0; i<16; i++ )
|
||||||
|
{
|
||||||
|
const uint32_t c = src[0] + src[1] + src[2] - rmin;
|
||||||
|
const uint8_t idx = ( c * range ) >> 16;
|
||||||
|
data |= idx << (i*2);
|
||||||
|
src += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return uint64_t( ( uint64_t( to565( min[0], min[1], min[2] ) ) << 16 ) | to565( max[0], max[1], max[2] ) | ( uint64_t( data ) << 32 ) );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __AVX2__
|
||||||
|
static tracy_force_inline void ProcessRGB_AVX( const uint8_t* src, char*& dst )
|
||||||
|
{
|
||||||
|
__m256i px0 = _mm256_loadu_si256(((__m256i*)src) + 0);
|
||||||
|
__m256i px1 = _mm256_loadu_si256(((__m256i*)src) + 1);
|
||||||
|
__m256i px2 = _mm256_loadu_si256(((__m256i*)src) + 2);
|
||||||
|
__m256i px3 = _mm256_loadu_si256(((__m256i*)src) + 3);
|
||||||
|
|
||||||
|
__m256i smask = _mm256_set1_epi32( 0xF8FCF8 );
|
||||||
|
__m256i sd0 = _mm256_and_si256( px0, smask );
|
||||||
|
__m256i sd1 = _mm256_and_si256( px1, smask );
|
||||||
|
__m256i sd2 = _mm256_and_si256( px2, smask );
|
||||||
|
__m256i sd3 = _mm256_and_si256( px3, smask );
|
||||||
|
|
||||||
|
__m256i sc = _mm256_shuffle_epi32(sd0, _MM_SHUFFLE(0, 0, 0, 0));
|
||||||
|
|
||||||
|
__m256i sc0 = _mm256_cmpeq_epi8( sd0, sc );
|
||||||
|
__m256i sc1 = _mm256_cmpeq_epi8( sd1, sc );
|
||||||
|
__m256i sc2 = _mm256_cmpeq_epi8( sd2, sc );
|
||||||
|
__m256i sc3 = _mm256_cmpeq_epi8( sd3, sc );
|
||||||
|
|
||||||
|
__m256i sm0 = _mm256_and_si256( sc0, sc1 );
|
||||||
|
__m256i sm1 = _mm256_and_si256( sc2, sc3 );
|
||||||
|
__m256i sm = _mm256_and_si256( sm0, sm1 );
|
||||||
|
|
||||||
|
const int64_t solid0 = 1 - _mm_testc_si128( _mm256_castsi256_si128( sm ), _mm_set1_epi32( -1 ) );
|
||||||
|
const int64_t solid1 = 1 - _mm_testc_si128( _mm256_extracti128_si256( sm, 1 ), _mm_set1_epi32( -1 ) );
|
||||||
|
|
||||||
|
if( solid0 + solid1 == 0 )
|
||||||
|
{
|
||||||
|
const auto c0 = uint64_t( to565( src[0], src[1], src[2] ) ) << 16;
|
||||||
|
const auto c1 = uint64_t( to565( src[16], src[17], src[18] ) ) << 16;
|
||||||
|
memcpy( dst, &c0, 8 );
|
||||||
|
memcpy( dst+8, &c1, 8 );
|
||||||
|
dst += 16;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
__m256i amask = _mm256_set1_epi32( 0xFFFFFF );
|
||||||
|
px0 = _mm256_and_si256( px0, amask );
|
||||||
|
px1 = _mm256_and_si256( px1, amask );
|
||||||
|
px2 = _mm256_and_si256( px2, amask );
|
||||||
|
px3 = _mm256_and_si256( px3, amask );
|
||||||
|
|
||||||
|
__m256i min0 = _mm256_min_epu8( px0, px1 );
|
||||||
|
__m256i min1 = _mm256_min_epu8( px2, px3 );
|
||||||
|
__m256i min2 = _mm256_min_epu8( min0, min1 );
|
||||||
|
|
||||||
|
__m256i max0 = _mm256_max_epu8( px0, px1 );
|
||||||
|
__m256i max1 = _mm256_max_epu8( px2, px3 );
|
||||||
|
__m256i max2 = _mm256_max_epu8( max0, max1 );
|
||||||
|
|
||||||
|
__m256i min3 = _mm256_shuffle_epi32( min2, _MM_SHUFFLE( 2, 3, 0, 1 ) );
|
||||||
|
__m256i max3 = _mm256_shuffle_epi32( max2, _MM_SHUFFLE( 2, 3, 0, 1 ) );
|
||||||
|
__m256i min4 = _mm256_min_epu8( min2, min3 );
|
||||||
|
__m256i max4 = _mm256_max_epu8( max2, max3 );
|
||||||
|
|
||||||
|
__m256i min5 = _mm256_shuffle_epi32( min4, _MM_SHUFFLE( 0, 0, 2, 2 ) );
|
||||||
|
__m256i max5 = _mm256_shuffle_epi32( max4, _MM_SHUFFLE( 0, 0, 2, 2 ) );
|
||||||
|
__m256i rmin = _mm256_min_epu8( min4, min5 );
|
||||||
|
__m256i rmax = _mm256_max_epu8( max4, max5 );
|
||||||
|
|
||||||
|
__m256i range1 = _mm256_subs_epu8( rmax, rmin );
|
||||||
|
__m256i range2 = _mm256_sad_epu8( rmax, rmin );
|
||||||
|
|
||||||
|
uint16_t vrange0 = DivTable[_mm256_cvtsi256_si32( range2 ) >> 1];
|
||||||
|
uint16_t vrange1 = DivTable[_mm256_extract_epi16( range2, 8 ) >> 1];
|
||||||
|
__m256i range00 = _mm256_set1_epi16( vrange0 );
|
||||||
|
__m256i range = _mm256_inserti128_si256( range00, _mm_set1_epi16( vrange1 ), 1 );
|
||||||
|
|
||||||
|
__m256i inset1 = _mm256_srli_epi16( range1, 4 );
|
||||||
|
__m256i inset = _mm256_and_si256( inset1, _mm256_set1_epi8( 0xF ) );
|
||||||
|
__m256i min = _mm256_adds_epu8( rmin, inset );
|
||||||
|
__m256i max = _mm256_subs_epu8( rmax, inset );
|
||||||
|
|
||||||
|
__m256i c0 = _mm256_subs_epu8( px0, rmin );
|
||||||
|
__m256i c1 = _mm256_subs_epu8( px1, rmin );
|
||||||
|
__m256i c2 = _mm256_subs_epu8( px2, rmin );
|
||||||
|
__m256i c3 = _mm256_subs_epu8( px3, rmin );
|
||||||
|
|
||||||
|
__m256i is0 = _mm256_maddubs_epi16( c0, _mm256_set1_epi8( 1 ) );
|
||||||
|
__m256i is1 = _mm256_maddubs_epi16( c1, _mm256_set1_epi8( 1 ) );
|
||||||
|
__m256i is2 = _mm256_maddubs_epi16( c2, _mm256_set1_epi8( 1 ) );
|
||||||
|
__m256i is3 = _mm256_maddubs_epi16( c3, _mm256_set1_epi8( 1 ) );
|
||||||
|
|
||||||
|
__m256i s0 = _mm256_hadd_epi16( is0, is1 );
|
||||||
|
__m256i s1 = _mm256_hadd_epi16( is2, is3 );
|
||||||
|
|
||||||
|
__m256i m0 = _mm256_mulhi_epu16( s0, range );
|
||||||
|
__m256i m1 = _mm256_mulhi_epu16( s1, range );
|
||||||
|
|
||||||
|
__m256i p0 = _mm256_packus_epi16( m0, m1 );
|
||||||
|
|
||||||
|
__m256i p1 = _mm256_or_si256( _mm256_srai_epi32( p0, 6 ), _mm256_srai_epi32( p0, 12 ) );
|
||||||
|
__m256i p2 = _mm256_or_si256( _mm256_srai_epi32( p0, 18 ), p0 );
|
||||||
|
__m256i p3 = _mm256_or_si256( p1, p2 );
|
||||||
|
__m256i p =_mm256_shuffle_epi8( p3, _mm256_set1_epi32( 0x0C080400 ) );
|
||||||
|
|
||||||
|
__m256i mm0 = _mm256_unpacklo_epi8( _mm256_setzero_si256(), min );
|
||||||
|
__m256i mm1 = _mm256_unpacklo_epi8( _mm256_setzero_si256(), max );
|
||||||
|
__m256i mm2 = _mm256_unpacklo_epi64( mm1, mm0 );
|
||||||
|
__m256i mmr = _mm256_slli_epi64( _mm256_srli_epi64( mm2, 11 ), 11 );
|
||||||
|
__m256i mmg = _mm256_slli_epi64( _mm256_srli_epi64( mm2, 26 ), 5 );
|
||||||
|
__m256i mmb = _mm256_srli_epi64( _mm256_slli_epi64( mm2, 16 ), 59 );
|
||||||
|
__m256i mm3 = _mm256_or_si256( mmr, mmg );
|
||||||
|
__m256i mm4 = _mm256_or_si256( mm3, mmb );
|
||||||
|
__m256i mm5 = _mm256_shuffle_epi8( mm4, _mm256_set1_epi32( 0x09080100 ) );
|
||||||
|
|
||||||
|
__m256i d0 = _mm256_unpacklo_epi32( mm5, p );
|
||||||
|
__m256i d1 = _mm256_permute4x64_epi64( d0, _MM_SHUFFLE( 3, 2, 2, 0 ) );
|
||||||
|
__m128i d2 = _mm256_castsi256_si128( d1 );
|
||||||
|
|
||||||
|
__m128i mask = _mm_set_epi64x( 0xFFFF0000 | -solid1, 0xFFFF0000 | -solid0 );
|
||||||
|
__m128i d3 = _mm_and_si128( d2, mask );
|
||||||
|
_mm_storeu_si128( (__m128i*)dst, d3 );
|
||||||
|
dst += 16;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void CompressImageDxt1( const char* src, char* dst, int w, int h )
|
||||||
|
{
|
||||||
|
assert( (w % 4) == 0 && (h % 4) == 0 );
|
||||||
|
|
||||||
|
#ifdef __AVX2__
|
||||||
|
if( w%8 == 0 )
|
||||||
|
{
|
||||||
|
uint32_t buf[8*4];
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
auto blocks = w * h / 32;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
auto tmp = (char*)buf;
|
||||||
|
memcpy( tmp, src, 8*4 );
|
||||||
|
memcpy( tmp + 8*4, src + w * 4, 8*4 );
|
||||||
|
memcpy( tmp + 16*4, src + w * 8, 8*4 );
|
||||||
|
memcpy( tmp + 24*4, src + w * 12, 8*4 );
|
||||||
|
src += 8*4;
|
||||||
|
if( ++i == w/8 )
|
||||||
|
{
|
||||||
|
src += w * 3 * 4;
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessRGB_AVX( (uint8_t*)buf, dst );
|
||||||
|
}
|
||||||
|
while( --blocks );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
uint32_t buf[4*4];
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
auto ptr = dst;
|
||||||
|
auto blocks = w * h / 16;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
auto tmp = (char*)buf;
|
||||||
|
memcpy( tmp, src, 4*4 );
|
||||||
|
memcpy( tmp + 4*4, src + w * 4, 4*4 );
|
||||||
|
memcpy( tmp + 8*4, src + w * 8, 4*4 );
|
||||||
|
memcpy( tmp + 12*4, src + w * 12, 4*4 );
|
||||||
|
src += 4*4;
|
||||||
|
if( ++i == w/4 )
|
||||||
|
{
|
||||||
|
src += w * 3 * 4;
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto c = ProcessRGB( (uint8_t*)buf );
|
||||||
|
memcpy( ptr, &c, sizeof( uint64_t ) );
|
||||||
|
ptr += sizeof( uint64_t );
|
||||||
|
}
|
||||||
|
while( --blocks );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
externals/tracy/public/client/TracyDxt1.hpp
vendored
Normal file
11
externals/tracy/public/client/TracyDxt1.hpp
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef __TRACYDXT1_HPP__
|
||||||
|
#define __TRACYDXT1_HPP__
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
void CompressImageDxt1( const char* src, char* dst, int w, int h );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
118
externals/tracy/public/client/TracyFastVector.hpp
vendored
Normal file
118
externals/tracy/public/client/TracyFastVector.hpp
vendored
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
#ifndef __TRACYFASTVECTOR_HPP__
|
||||||
|
#define __TRACYFASTVECTOR_HPP__
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "../common/TracyAlloc.hpp"
|
||||||
|
#include "../common/TracyForceInline.hpp"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class FastVector
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using iterator = T*;
|
||||||
|
using const_iterator = const T*;
|
||||||
|
|
||||||
|
FastVector( size_t capacity )
|
||||||
|
: m_ptr( (T*)tracy_malloc( sizeof( T ) * capacity ) )
|
||||||
|
, m_write( m_ptr )
|
||||||
|
, m_end( m_ptr + capacity )
|
||||||
|
{
|
||||||
|
assert( capacity != 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
FastVector( const FastVector& ) = delete;
|
||||||
|
FastVector( FastVector&& ) = delete;
|
||||||
|
|
||||||
|
~FastVector()
|
||||||
|
{
|
||||||
|
tracy_free( m_ptr );
|
||||||
|
}
|
||||||
|
|
||||||
|
FastVector& operator=( const FastVector& ) = delete;
|
||||||
|
FastVector& operator=( FastVector&& ) = delete;
|
||||||
|
|
||||||
|
bool empty() const { return m_ptr == m_write; }
|
||||||
|
size_t size() const { return m_write - m_ptr; }
|
||||||
|
|
||||||
|
T* data() { return m_ptr; }
|
||||||
|
const T* data() const { return m_ptr; };
|
||||||
|
|
||||||
|
T* begin() { return m_ptr; }
|
||||||
|
const T* begin() const { return m_ptr; }
|
||||||
|
T* end() { return m_write; }
|
||||||
|
const T* end() const { return m_write; }
|
||||||
|
|
||||||
|
T& front() { assert( !empty() ); return m_ptr[0]; }
|
||||||
|
const T& front() const { assert( !empty() ); return m_ptr[0]; }
|
||||||
|
|
||||||
|
T& back() { assert( !empty() ); return m_write[-1]; }
|
||||||
|
const T& back() const { assert( !empty() ); return m_write[-1]; }
|
||||||
|
|
||||||
|
T& operator[]( size_t idx ) { return m_ptr[idx]; }
|
||||||
|
const T& operator[]( size_t idx ) const { return m_ptr[idx]; }
|
||||||
|
|
||||||
|
T* push_next()
|
||||||
|
{
|
||||||
|
if( m_write == m_end ) AllocMore();
|
||||||
|
return m_write++;
|
||||||
|
}
|
||||||
|
|
||||||
|
T* prepare_next()
|
||||||
|
{
|
||||||
|
if( m_write == m_end ) AllocMore();
|
||||||
|
return m_write;
|
||||||
|
}
|
||||||
|
|
||||||
|
void commit_next()
|
||||||
|
{
|
||||||
|
m_write++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
m_write = m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap( FastVector& vec )
|
||||||
|
{
|
||||||
|
const auto ptr1 = m_ptr;
|
||||||
|
const auto ptr2 = vec.m_ptr;
|
||||||
|
const auto write1 = m_write;
|
||||||
|
const auto write2 = vec.m_write;
|
||||||
|
const auto end1 = m_end;
|
||||||
|
const auto end2 = vec.m_end;
|
||||||
|
|
||||||
|
m_ptr = ptr2;
|
||||||
|
vec.m_ptr = ptr1;
|
||||||
|
m_write = write2;
|
||||||
|
vec.m_write = write1;
|
||||||
|
m_end = end2;
|
||||||
|
vec.m_end = end1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
tracy_no_inline void AllocMore()
|
||||||
|
{
|
||||||
|
const auto cap = size_t( m_end - m_ptr ) * 2;
|
||||||
|
const auto size = size_t( m_write - m_ptr );
|
||||||
|
T* ptr = (T*)tracy_malloc( sizeof( T ) * cap );
|
||||||
|
memcpy( ptr, m_ptr, size * sizeof( T ) );
|
||||||
|
tracy_free_fast( m_ptr );
|
||||||
|
m_ptr = ptr;
|
||||||
|
m_write = m_ptr + size;
|
||||||
|
m_end = m_ptr + cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
T* m_ptr;
|
||||||
|
T* m_write;
|
||||||
|
T* m_end;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
546
externals/tracy/public/client/TracyLock.hpp
vendored
Normal file
546
externals/tracy/public/client/TracyLock.hpp
vendored
Normal file
@ -0,0 +1,546 @@
|
|||||||
|
#ifndef __TRACYLOCK_HPP__
|
||||||
|
#define __TRACYLOCK_HPP__
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#include "../common/TracySystem.hpp"
|
||||||
|
#include "../common/TracyAlign.hpp"
|
||||||
|
#include "TracyProfiler.hpp"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
class LockableCtx
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
tracy_force_inline LockableCtx( const SourceLocationData* srcloc )
|
||||||
|
: m_id( GetLockCounter().fetch_add( 1, std::memory_order_relaxed ) )
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
, m_lockCount( 0 )
|
||||||
|
, m_active( false )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
assert( m_id != (std::numeric_limits<uint32_t>::max)() );
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::LockAnnounce );
|
||||||
|
MemWrite( &item->lockAnnounce.id, m_id );
|
||||||
|
MemWrite( &item->lockAnnounce.time, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->lockAnnounce.lckloc, (uint64_t)srcloc );
|
||||||
|
MemWrite( &item->lockAnnounce.type, LockType::Lockable );
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
GetProfiler().DeferItem( *item );
|
||||||
|
#endif
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
LockableCtx( const LockableCtx& ) = delete;
|
||||||
|
LockableCtx& operator=( const LockableCtx& ) = delete;
|
||||||
|
|
||||||
|
tracy_force_inline ~LockableCtx()
|
||||||
|
{
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::LockTerminate );
|
||||||
|
MemWrite( &item->lockTerminate.id, m_id );
|
||||||
|
MemWrite( &item->lockTerminate.time, Profiler::GetTime() );
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
GetProfiler().DeferItem( *item );
|
||||||
|
#endif
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline bool BeforeLock()
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
bool queue = false;
|
||||||
|
const auto locks = m_lockCount.fetch_add( 1, std::memory_order_relaxed );
|
||||||
|
const auto active = m_active.load( std::memory_order_relaxed );
|
||||||
|
if( locks == 0 || active )
|
||||||
|
{
|
||||||
|
const bool connected = GetProfiler().IsConnected();
|
||||||
|
if( active != connected ) m_active.store( connected, std::memory_order_relaxed );
|
||||||
|
if( connected ) queue = true;
|
||||||
|
}
|
||||||
|
if( !queue ) return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::LockWait );
|
||||||
|
MemWrite( &item->lockWait.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->lockWait.id, m_id );
|
||||||
|
MemWrite( &item->lockWait.time, Profiler::GetTime() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void AfterLock()
|
||||||
|
{
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::LockObtain );
|
||||||
|
MemWrite( &item->lockObtain.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->lockObtain.id, m_id );
|
||||||
|
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void AfterUnlock()
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
m_lockCount.fetch_sub( 1, std::memory_order_relaxed );
|
||||||
|
if( !m_active.load( std::memory_order_relaxed ) ) return;
|
||||||
|
if( !GetProfiler().IsConnected() )
|
||||||
|
{
|
||||||
|
m_active.store( false, std::memory_order_relaxed );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::LockRelease );
|
||||||
|
MemWrite( &item->lockRelease.id, m_id );
|
||||||
|
MemWrite( &item->lockRelease.time, Profiler::GetTime() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void AfterTryLock( bool acquired )
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if( !acquired ) return;
|
||||||
|
|
||||||
|
bool queue = false;
|
||||||
|
const auto locks = m_lockCount.fetch_add( 1, std::memory_order_relaxed );
|
||||||
|
const auto active = m_active.load( std::memory_order_relaxed );
|
||||||
|
if( locks == 0 || active )
|
||||||
|
{
|
||||||
|
const bool connected = GetProfiler().IsConnected();
|
||||||
|
if( active != connected ) m_active.store( connected, std::memory_order_relaxed );
|
||||||
|
if( connected ) queue = true;
|
||||||
|
}
|
||||||
|
if( !queue ) return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if( acquired )
|
||||||
|
{
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::LockObtain );
|
||||||
|
MemWrite( &item->lockObtain.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->lockObtain.id, m_id );
|
||||||
|
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void Mark( const SourceLocationData* srcloc )
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
const auto active = m_active.load( std::memory_order_relaxed );
|
||||||
|
if( !active ) return;
|
||||||
|
const auto connected = GetProfiler().IsConnected();
|
||||||
|
if( !connected )
|
||||||
|
{
|
||||||
|
if( active ) m_active.store( false, std::memory_order_relaxed );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::LockMark );
|
||||||
|
MemWrite( &item->lockMark.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->lockMark.id, m_id );
|
||||||
|
MemWrite( &item->lockMark.srcloc, (uint64_t)srcloc );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void CustomName( const char* name, size_t size )
|
||||||
|
{
|
||||||
|
assert( size < (std::numeric_limits<uint16_t>::max)() );
|
||||||
|
auto ptr = (char*)tracy_malloc( size );
|
||||||
|
memcpy( ptr, name, size );
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::LockName );
|
||||||
|
MemWrite( &item->lockNameFat.id, m_id );
|
||||||
|
MemWrite( &item->lockNameFat.name, (uint64_t)ptr );
|
||||||
|
MemWrite( &item->lockNameFat.size, (uint16_t)size );
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
GetProfiler().DeferItem( *item );
|
||||||
|
#endif
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_id;
|
||||||
|
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
std::atomic<uint32_t> m_lockCount;
|
||||||
|
std::atomic<bool> m_active;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class Lockable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
tracy_force_inline Lockable( const SourceLocationData* srcloc )
|
||||||
|
: m_ctx( srcloc )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Lockable( const Lockable& ) = delete;
|
||||||
|
Lockable& operator=( const Lockable& ) = delete;
|
||||||
|
|
||||||
|
tracy_force_inline void lock()
|
||||||
|
{
|
||||||
|
const auto runAfter = m_ctx.BeforeLock();
|
||||||
|
m_lockable.lock();
|
||||||
|
if( runAfter ) m_ctx.AfterLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void unlock()
|
||||||
|
{
|
||||||
|
m_lockable.unlock();
|
||||||
|
m_ctx.AfterUnlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline bool try_lock()
|
||||||
|
{
|
||||||
|
const auto acquired = m_lockable.try_lock();
|
||||||
|
m_ctx.AfterTryLock( acquired );
|
||||||
|
return acquired;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void Mark( const SourceLocationData* srcloc )
|
||||||
|
{
|
||||||
|
m_ctx.Mark( srcloc );
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void CustomName( const char* name, size_t size )
|
||||||
|
{
|
||||||
|
m_ctx.CustomName( name, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T m_lockable;
|
||||||
|
LockableCtx m_ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class SharedLockableCtx
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
tracy_force_inline SharedLockableCtx( const SourceLocationData* srcloc )
|
||||||
|
: m_id( GetLockCounter().fetch_add( 1, std::memory_order_relaxed ) )
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
, m_lockCount( 0 )
|
||||||
|
, m_active( false )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
assert( m_id != (std::numeric_limits<uint32_t>::max)() );
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::LockAnnounce );
|
||||||
|
MemWrite( &item->lockAnnounce.id, m_id );
|
||||||
|
MemWrite( &item->lockAnnounce.time, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->lockAnnounce.lckloc, (uint64_t)srcloc );
|
||||||
|
MemWrite( &item->lockAnnounce.type, LockType::SharedLockable );
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
GetProfiler().DeferItem( *item );
|
||||||
|
#endif
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedLockableCtx( const SharedLockableCtx& ) = delete;
|
||||||
|
SharedLockableCtx& operator=( const SharedLockableCtx& ) = delete;
|
||||||
|
|
||||||
|
tracy_force_inline ~SharedLockableCtx()
|
||||||
|
{
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::LockTerminate );
|
||||||
|
MemWrite( &item->lockTerminate.id, m_id );
|
||||||
|
MemWrite( &item->lockTerminate.time, Profiler::GetTime() );
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
GetProfiler().DeferItem( *item );
|
||||||
|
#endif
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline bool BeforeLock()
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
bool queue = false;
|
||||||
|
const auto locks = m_lockCount.fetch_add( 1, std::memory_order_relaxed );
|
||||||
|
const auto active = m_active.load( std::memory_order_relaxed );
|
||||||
|
if( locks == 0 || active )
|
||||||
|
{
|
||||||
|
const bool connected = GetProfiler().IsConnected();
|
||||||
|
if( active != connected ) m_active.store( connected, std::memory_order_relaxed );
|
||||||
|
if( connected ) queue = true;
|
||||||
|
}
|
||||||
|
if( !queue ) return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::LockWait );
|
||||||
|
MemWrite( &item->lockWait.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->lockWait.id, m_id );
|
||||||
|
MemWrite( &item->lockWait.time, Profiler::GetTime() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void AfterLock()
|
||||||
|
{
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::LockObtain );
|
||||||
|
MemWrite( &item->lockObtain.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->lockObtain.id, m_id );
|
||||||
|
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void AfterUnlock()
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
m_lockCount.fetch_sub( 1, std::memory_order_relaxed );
|
||||||
|
if( !m_active.load( std::memory_order_relaxed ) ) return;
|
||||||
|
if( !GetProfiler().IsConnected() )
|
||||||
|
{
|
||||||
|
m_active.store( false, std::memory_order_relaxed );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::LockRelease );
|
||||||
|
MemWrite( &item->lockRelease.id, m_id );
|
||||||
|
MemWrite( &item->lockRelease.time, Profiler::GetTime() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void AfterTryLock( bool acquired )
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if( !acquired ) return;
|
||||||
|
|
||||||
|
bool queue = false;
|
||||||
|
const auto locks = m_lockCount.fetch_add( 1, std::memory_order_relaxed );
|
||||||
|
const auto active = m_active.load( std::memory_order_relaxed );
|
||||||
|
if( locks == 0 || active )
|
||||||
|
{
|
||||||
|
const bool connected = GetProfiler().IsConnected();
|
||||||
|
if( active != connected ) m_active.store( connected, std::memory_order_relaxed );
|
||||||
|
if( connected ) queue = true;
|
||||||
|
}
|
||||||
|
if( !queue ) return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if( acquired )
|
||||||
|
{
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::LockObtain );
|
||||||
|
MemWrite( &item->lockObtain.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->lockObtain.id, m_id );
|
||||||
|
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline bool BeforeLockShared()
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
bool queue = false;
|
||||||
|
const auto locks = m_lockCount.fetch_add( 1, std::memory_order_relaxed );
|
||||||
|
const auto active = m_active.load( std::memory_order_relaxed );
|
||||||
|
if( locks == 0 || active )
|
||||||
|
{
|
||||||
|
const bool connected = GetProfiler().IsConnected();
|
||||||
|
if( active != connected ) m_active.store( connected, std::memory_order_relaxed );
|
||||||
|
if( connected ) queue = true;
|
||||||
|
}
|
||||||
|
if( !queue ) return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::LockSharedWait );
|
||||||
|
MemWrite( &item->lockWait.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->lockWait.id, m_id );
|
||||||
|
MemWrite( &item->lockWait.time, Profiler::GetTime() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void AfterLockShared()
|
||||||
|
{
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::LockSharedObtain );
|
||||||
|
MemWrite( &item->lockObtain.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->lockObtain.id, m_id );
|
||||||
|
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void AfterUnlockShared()
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
m_lockCount.fetch_sub( 1, std::memory_order_relaxed );
|
||||||
|
if( !m_active.load( std::memory_order_relaxed ) ) return;
|
||||||
|
if( !GetProfiler().IsConnected() )
|
||||||
|
{
|
||||||
|
m_active.store( false, std::memory_order_relaxed );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::LockSharedRelease );
|
||||||
|
MemWrite( &item->lockReleaseShared.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->lockReleaseShared.id, m_id );
|
||||||
|
MemWrite( &item->lockReleaseShared.time, Profiler::GetTime() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void AfterTryLockShared( bool acquired )
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if( !acquired ) return;
|
||||||
|
|
||||||
|
bool queue = false;
|
||||||
|
const auto locks = m_lockCount.fetch_add( 1, std::memory_order_relaxed );
|
||||||
|
const auto active = m_active.load( std::memory_order_relaxed );
|
||||||
|
if( locks == 0 || active )
|
||||||
|
{
|
||||||
|
const bool connected = GetProfiler().IsConnected();
|
||||||
|
if( active != connected ) m_active.store( connected, std::memory_order_relaxed );
|
||||||
|
if( connected ) queue = true;
|
||||||
|
}
|
||||||
|
if( !queue ) return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if( acquired )
|
||||||
|
{
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::LockSharedObtain );
|
||||||
|
MemWrite( &item->lockObtain.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->lockObtain.id, m_id );
|
||||||
|
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void Mark( const SourceLocationData* srcloc )
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
const auto active = m_active.load( std::memory_order_relaxed );
|
||||||
|
if( !active ) return;
|
||||||
|
const auto connected = GetProfiler().IsConnected();
|
||||||
|
if( !connected )
|
||||||
|
{
|
||||||
|
if( active ) m_active.store( false, std::memory_order_relaxed );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::LockMark );
|
||||||
|
MemWrite( &item->lockMark.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->lockMark.id, m_id );
|
||||||
|
MemWrite( &item->lockMark.srcloc, (uint64_t)srcloc );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void CustomName( const char* name, size_t size )
|
||||||
|
{
|
||||||
|
assert( size < (std::numeric_limits<uint16_t>::max)() );
|
||||||
|
auto ptr = (char*)tracy_malloc( size );
|
||||||
|
memcpy( ptr, name, size );
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::LockName );
|
||||||
|
MemWrite( &item->lockNameFat.id, m_id );
|
||||||
|
MemWrite( &item->lockNameFat.name, (uint64_t)ptr );
|
||||||
|
MemWrite( &item->lockNameFat.size, (uint16_t)size );
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
GetProfiler().DeferItem( *item );
|
||||||
|
#endif
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_id;
|
||||||
|
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
std::atomic<uint32_t> m_lockCount;
|
||||||
|
std::atomic<bool> m_active;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class SharedLockable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
tracy_force_inline SharedLockable( const SourceLocationData* srcloc )
|
||||||
|
: m_ctx( srcloc )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedLockable( const SharedLockable& ) = delete;
|
||||||
|
SharedLockable& operator=( const SharedLockable& ) = delete;
|
||||||
|
|
||||||
|
tracy_force_inline void lock()
|
||||||
|
{
|
||||||
|
const auto runAfter = m_ctx.BeforeLock();
|
||||||
|
m_lockable.lock();
|
||||||
|
if( runAfter ) m_ctx.AfterLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void unlock()
|
||||||
|
{
|
||||||
|
m_lockable.unlock();
|
||||||
|
m_ctx.AfterUnlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline bool try_lock()
|
||||||
|
{
|
||||||
|
const auto acquired = m_lockable.try_lock();
|
||||||
|
m_ctx.AfterTryLock( acquired );
|
||||||
|
return acquired;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void lock_shared()
|
||||||
|
{
|
||||||
|
const auto runAfter = m_ctx.BeforeLockShared();
|
||||||
|
m_lockable.lock_shared();
|
||||||
|
if( runAfter ) m_ctx.AfterLockShared();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void unlock_shared()
|
||||||
|
{
|
||||||
|
m_lockable.unlock_shared();
|
||||||
|
m_ctx.AfterUnlockShared();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline bool try_lock_shared()
|
||||||
|
{
|
||||||
|
const auto acquired = m_lockable.try_lock_shared();
|
||||||
|
m_ctx.AfterTryLockShared( acquired );
|
||||||
|
return acquired;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void Mark( const SourceLocationData* srcloc )
|
||||||
|
{
|
||||||
|
m_ctx.Mark( srcloc );
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void CustomName( const char* name, size_t size )
|
||||||
|
{
|
||||||
|
m_ctx.CustomName( name, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T m_lockable;
|
||||||
|
SharedLockableCtx m_ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
26
externals/tracy/public/client/TracyOverride.cpp
vendored
Normal file
26
externals/tracy/public/client/TracyOverride.cpp
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifdef TRACY_ENABLE
|
||||||
|
# ifdef __linux__
|
||||||
|
# include "TracyDebug.hpp"
|
||||||
|
# ifdef TRACY_VERBOSE
|
||||||
|
# include <dlfcn.h>
|
||||||
|
# include <link.h>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
extern "C" int dlclose( void* hnd )
|
||||||
|
{
|
||||||
|
#ifdef TRACY_VERBOSE
|
||||||
|
struct link_map* lm;
|
||||||
|
if( dlinfo( hnd, RTLD_DI_LINKMAP, &lm ) == 0 )
|
||||||
|
{
|
||||||
|
TracyDebug( "Overriding dlclose for %s\n", lm->l_name );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TracyDebug( "Overriding dlclose for unknown object (%s)\n", dlerror() );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
# endif
|
||||||
|
#endif
|
4530
externals/tracy/public/client/TracyProfiler.cpp
vendored
Normal file
4530
externals/tracy/public/client/TracyProfiler.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1009
externals/tracy/public/client/TracyProfiler.hpp
vendored
Normal file
1009
externals/tracy/public/client/TracyProfiler.hpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
141
externals/tracy/public/client/TracyRingBuffer.hpp
vendored
Normal file
141
externals/tracy/public/client/TracyRingBuffer.hpp
vendored
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
#include <atomic>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <linux/perf_event.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "TracyDebug.hpp"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
class RingBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RingBuffer( unsigned int size, int fd, int id, int cpu = -1 )
|
||||||
|
: m_size( size )
|
||||||
|
, m_id( id )
|
||||||
|
, m_cpu( cpu )
|
||||||
|
, m_fd( fd )
|
||||||
|
{
|
||||||
|
const auto pageSize = uint32_t( getpagesize() );
|
||||||
|
assert( size >= pageSize );
|
||||||
|
assert( __builtin_popcount( size ) == 1 );
|
||||||
|
m_mapSize = size + pageSize;
|
||||||
|
auto mapAddr = mmap( nullptr, m_mapSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
|
||||||
|
if( mapAddr == MAP_FAILED )
|
||||||
|
{
|
||||||
|
TracyDebug( "mmap failed: errno %i (%s)\n", errno, strerror( errno ) );
|
||||||
|
m_fd = 0;
|
||||||
|
m_metadata = nullptr;
|
||||||
|
close( fd );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_metadata = (perf_event_mmap_page*)mapAddr;
|
||||||
|
assert( m_metadata->data_offset == pageSize );
|
||||||
|
m_buffer = ((char*)mapAddr) + pageSize;
|
||||||
|
m_tail = m_metadata->data_tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
~RingBuffer()
|
||||||
|
{
|
||||||
|
if( m_metadata ) munmap( m_metadata, m_mapSize );
|
||||||
|
if( m_fd ) close( m_fd );
|
||||||
|
}
|
||||||
|
|
||||||
|
RingBuffer( const RingBuffer& ) = delete;
|
||||||
|
RingBuffer& operator=( const RingBuffer& ) = delete;
|
||||||
|
|
||||||
|
RingBuffer( RingBuffer&& other )
|
||||||
|
{
|
||||||
|
memcpy( (char*)&other, (char*)this, sizeof( RingBuffer ) );
|
||||||
|
m_metadata = nullptr;
|
||||||
|
m_fd = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RingBuffer& operator=( RingBuffer&& other )
|
||||||
|
{
|
||||||
|
memcpy( (char*)&other, (char*)this, sizeof( RingBuffer ) );
|
||||||
|
m_metadata = nullptr;
|
||||||
|
m_fd = 0;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsValid() const { return m_metadata != nullptr; }
|
||||||
|
int GetId() const { return m_id; }
|
||||||
|
int GetCpu() const { return m_cpu; }
|
||||||
|
|
||||||
|
void Enable()
|
||||||
|
{
|
||||||
|
ioctl( m_fd, PERF_EVENT_IOC_ENABLE, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Read( void* dst, uint64_t offset, uint64_t cnt )
|
||||||
|
{
|
||||||
|
const auto size = m_size;
|
||||||
|
auto src = ( m_tail + offset ) % size;
|
||||||
|
if( src + cnt <= size )
|
||||||
|
{
|
||||||
|
memcpy( dst, m_buffer + src, cnt );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto s0 = size - src;
|
||||||
|
const auto buf = m_buffer;
|
||||||
|
memcpy( dst, buf + src, s0 );
|
||||||
|
memcpy( (char*)dst + s0, buf, cnt - s0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Advance( uint64_t cnt )
|
||||||
|
{
|
||||||
|
m_tail += cnt;
|
||||||
|
StoreTail();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CheckTscCaps() const
|
||||||
|
{
|
||||||
|
return m_metadata->cap_user_time_zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t ConvertTimeToTsc( int64_t timestamp ) const
|
||||||
|
{
|
||||||
|
if( !m_metadata->cap_user_time_zero ) return 0;
|
||||||
|
const auto time = timestamp - m_metadata->time_zero;
|
||||||
|
const auto quot = time / m_metadata->time_mult;
|
||||||
|
const auto rem = time % m_metadata->time_mult;
|
||||||
|
return ( quot << m_metadata->time_shift ) + ( rem << m_metadata->time_shift ) / m_metadata->time_mult;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t LoadHead() const
|
||||||
|
{
|
||||||
|
return std::atomic_load_explicit( (const volatile std::atomic<uint64_t>*)&m_metadata->data_head, std::memory_order_acquire );
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t GetTail() const
|
||||||
|
{
|
||||||
|
return m_tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void StoreTail()
|
||||||
|
{
|
||||||
|
std::atomic_store_explicit( (volatile std::atomic<uint64_t>*)&m_metadata->data_tail, m_tail, std::memory_order_release );
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int m_size;
|
||||||
|
uint64_t m_tail;
|
||||||
|
char* m_buffer;
|
||||||
|
int m_id;
|
||||||
|
int m_cpu;
|
||||||
|
perf_event_mmap_page* m_metadata;
|
||||||
|
|
||||||
|
size_t m_mapSize;
|
||||||
|
int m_fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
175
externals/tracy/public/client/TracyScoped.hpp
vendored
Normal file
175
externals/tracy/public/client/TracyScoped.hpp
vendored
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
#ifndef __TRACYSCOPED_HPP__
|
||||||
|
#define __TRACYSCOPED_HPP__
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../common/TracySystem.hpp"
|
||||||
|
#include "../common/TracyAlign.hpp"
|
||||||
|
#include "../common/TracyAlloc.hpp"
|
||||||
|
#include "TracyProfiler.hpp"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
class ScopedZone
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScopedZone( const ScopedZone& ) = delete;
|
||||||
|
ScopedZone( ScopedZone&& ) = delete;
|
||||||
|
ScopedZone& operator=( const ScopedZone& ) = delete;
|
||||||
|
ScopedZone& operator=( ScopedZone&& ) = delete;
|
||||||
|
|
||||||
|
tracy_force_inline ScopedZone( const SourceLocationData* srcloc, bool is_active = true )
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active( is_active && GetProfiler().IsConnected() )
|
||||||
|
#else
|
||||||
|
: m_active( is_active )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
m_connectionId = GetProfiler().ConnectionId();
|
||||||
|
#endif
|
||||||
|
TracyQueuePrepare( QueueType::ZoneBegin );
|
||||||
|
MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->zoneBegin.srcloc, (uint64_t)srcloc );
|
||||||
|
TracyQueueCommit( zoneBeginThread );
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline ScopedZone( const SourceLocationData* srcloc, int depth, bool is_active = true )
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active( is_active && GetProfiler().IsConnected() )
|
||||||
|
#else
|
||||||
|
: m_active( is_active )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
m_connectionId = GetProfiler().ConnectionId();
|
||||||
|
#endif
|
||||||
|
GetProfiler().SendCallstack( depth );
|
||||||
|
|
||||||
|
TracyQueuePrepare( QueueType::ZoneBeginCallstack );
|
||||||
|
MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->zoneBegin.srcloc, (uint64_t)srcloc );
|
||||||
|
TracyQueueCommit( zoneBeginThread );
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline ScopedZone( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, bool is_active = true )
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active( is_active && GetProfiler().IsConnected() )
|
||||||
|
#else
|
||||||
|
: m_active( is_active )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
m_connectionId = GetProfiler().ConnectionId();
|
||||||
|
#endif
|
||||||
|
TracyQueuePrepare( QueueType::ZoneBeginAllocSrcLoc );
|
||||||
|
const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz );
|
||||||
|
MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->zoneBegin.srcloc, srcloc );
|
||||||
|
TracyQueueCommit( zoneBeginThread );
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline ScopedZone( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, int depth, bool is_active = true )
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active( is_active && GetProfiler().IsConnected() )
|
||||||
|
#else
|
||||||
|
: m_active( is_active )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
m_connectionId = GetProfiler().ConnectionId();
|
||||||
|
#endif
|
||||||
|
GetProfiler().SendCallstack( depth );
|
||||||
|
|
||||||
|
TracyQueuePrepare( QueueType::ZoneBeginAllocSrcLocCallstack );
|
||||||
|
const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz );
|
||||||
|
MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->zoneBegin.srcloc, srcloc );
|
||||||
|
TracyQueueCommit( zoneBeginThread );
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline ~ScopedZone()
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if( GetProfiler().ConnectionId() != m_connectionId ) return;
|
||||||
|
#endif
|
||||||
|
TracyQueuePrepare( QueueType::ZoneEnd );
|
||||||
|
MemWrite( &item->zoneEnd.time, Profiler::GetTime() );
|
||||||
|
TracyQueueCommit( zoneEndThread );
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void Text( const char* txt, size_t size )
|
||||||
|
{
|
||||||
|
assert( size < (std::numeric_limits<uint16_t>::max)() );
|
||||||
|
if( !m_active ) return;
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if( GetProfiler().ConnectionId() != m_connectionId ) return;
|
||||||
|
#endif
|
||||||
|
auto ptr = (char*)tracy_malloc( size );
|
||||||
|
memcpy( ptr, txt, size );
|
||||||
|
TracyQueuePrepare( QueueType::ZoneText );
|
||||||
|
MemWrite( &item->zoneTextFat.text, (uint64_t)ptr );
|
||||||
|
MemWrite( &item->zoneTextFat.size, (uint16_t)size );
|
||||||
|
TracyQueueCommit( zoneTextFatThread );
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void Name( const char* txt, size_t size )
|
||||||
|
{
|
||||||
|
assert( size < (std::numeric_limits<uint16_t>::max)() );
|
||||||
|
if( !m_active ) return;
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if( GetProfiler().ConnectionId() != m_connectionId ) return;
|
||||||
|
#endif
|
||||||
|
auto ptr = (char*)tracy_malloc( size );
|
||||||
|
memcpy( ptr, txt, size );
|
||||||
|
TracyQueuePrepare( QueueType::ZoneName );
|
||||||
|
MemWrite( &item->zoneTextFat.text, (uint64_t)ptr );
|
||||||
|
MemWrite( &item->zoneTextFat.size, (uint16_t)size );
|
||||||
|
TracyQueueCommit( zoneTextFatThread );
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void Color( uint32_t color )
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if( GetProfiler().ConnectionId() != m_connectionId ) return;
|
||||||
|
#endif
|
||||||
|
TracyQueuePrepare( QueueType::ZoneColor );
|
||||||
|
MemWrite( &item->zoneColor.b, uint8_t( ( color ) & 0xFF ) );
|
||||||
|
MemWrite( &item->zoneColor.g, uint8_t( ( color >> 8 ) & 0xFF ) );
|
||||||
|
MemWrite( &item->zoneColor.r, uint8_t( ( color >> 16 ) & 0xFF ) );
|
||||||
|
TracyQueueCommit( zoneColorThread );
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void Value( uint64_t value )
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if( GetProfiler().ConnectionId() != m_connectionId ) return;
|
||||||
|
#endif
|
||||||
|
TracyQueuePrepare( QueueType::ZoneValue );
|
||||||
|
MemWrite( &item->zoneValue.value, value );
|
||||||
|
TracyQueueCommit( zoneValueThread );
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline bool IsActive() const { return m_active; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const bool m_active;
|
||||||
|
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
uint64_t m_connectionId = 0;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
41
externals/tracy/public/client/TracyStringHelpers.hpp
vendored
Normal file
41
externals/tracy/public/client/TracyStringHelpers.hpp
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#ifndef __TRACYSTRINGHELPERS_HPP__
|
||||||
|
#define __TRACYSTRINGHELPERS_HPP__
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../common/TracyAlloc.hpp"
|
||||||
|
#include "../common/TracyForceInline.hpp"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
static tracy_force_inline char* CopyString( const char* src, size_t sz )
|
||||||
|
{
|
||||||
|
auto dst = (char*)tracy_malloc( sz + 1 );
|
||||||
|
memcpy( dst, src, sz );
|
||||||
|
dst[sz] = '\0';
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static tracy_force_inline char* CopyString( const char* src )
|
||||||
|
{
|
||||||
|
return CopyString( src, strlen( src ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
static tracy_force_inline char* CopyStringFast( const char* src, size_t sz )
|
||||||
|
{
|
||||||
|
auto dst = (char*)tracy_malloc_fast( sz + 1 );
|
||||||
|
memcpy( dst, src, sz );
|
||||||
|
dst[sz] = '\0';
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static tracy_force_inline char* CopyStringFast( const char* src )
|
||||||
|
{
|
||||||
|
return CopyStringFast( src, strlen( src ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
164
externals/tracy/public/client/TracySysPower.cpp
vendored
Normal file
164
externals/tracy/public/client/TracySysPower.cpp
vendored
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
#include "TracySysPower.hpp"
|
||||||
|
|
||||||
|
#ifdef TRACY_HAS_SYSPOWER
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <chrono>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "TracyDebug.hpp"
|
||||||
|
#include "TracyProfiler.hpp"
|
||||||
|
#include "../common/TracyAlloc.hpp"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
SysPower::SysPower()
|
||||||
|
: m_domains( 4 )
|
||||||
|
, m_lastTime( 0 )
|
||||||
|
{
|
||||||
|
ScanDirectory( "/sys/devices/virtual/powercap/intel-rapl", -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
SysPower::~SysPower()
|
||||||
|
{
|
||||||
|
for( auto& v : m_domains )
|
||||||
|
{
|
||||||
|
fclose( v.handle );
|
||||||
|
// Do not release v.name, as it may be still needed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysPower::Tick()
|
||||||
|
{
|
||||||
|
auto t = std::chrono::high_resolution_clock::now().time_since_epoch().count();
|
||||||
|
if( t - m_lastTime > 10000000 ) // 10 ms
|
||||||
|
{
|
||||||
|
m_lastTime = t;
|
||||||
|
for( auto& v : m_domains )
|
||||||
|
{
|
||||||
|
char tmp[32];
|
||||||
|
if( fread( tmp, 1, 32, v.handle ) > 0 )
|
||||||
|
{
|
||||||
|
rewind( v.handle );
|
||||||
|
auto p = (uint64_t)atoll( tmp );
|
||||||
|
uint64_t delta;
|
||||||
|
if( p >= v.value )
|
||||||
|
{
|
||||||
|
delta = p - v.value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delta = v.overflow - v.value + p;
|
||||||
|
}
|
||||||
|
v.value = p;
|
||||||
|
|
||||||
|
TracyLfqPrepare( QueueType::SysPowerReport );
|
||||||
|
MemWrite( &item->sysPower.time, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->sysPower.delta, delta );
|
||||||
|
MemWrite( &item->sysPower.name, (uint64_t)v.name );
|
||||||
|
TracyLfqCommit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysPower::ScanDirectory( const char* path, int parent )
|
||||||
|
{
|
||||||
|
DIR* dir = opendir( path );
|
||||||
|
if( !dir ) return;
|
||||||
|
struct dirent* ent;
|
||||||
|
uint64_t maxRange = 0;
|
||||||
|
char* name = nullptr;
|
||||||
|
FILE* handle = nullptr;
|
||||||
|
while( ( ent = readdir( dir ) ) )
|
||||||
|
{
|
||||||
|
if( ent->d_type == DT_REG )
|
||||||
|
{
|
||||||
|
if( strcmp( ent->d_name, "max_energy_range_uj" ) == 0 )
|
||||||
|
{
|
||||||
|
char tmp[PATH_MAX];
|
||||||
|
snprintf( tmp, PATH_MAX, "%s/max_energy_range_uj", path );
|
||||||
|
FILE* f = fopen( tmp, "r" );
|
||||||
|
if( f )
|
||||||
|
{
|
||||||
|
void(fscanf( f, "%" PRIu64, &maxRange ));
|
||||||
|
fclose( f );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( strcmp( ent->d_name, "name" ) == 0 )
|
||||||
|
{
|
||||||
|
char tmp[PATH_MAX];
|
||||||
|
snprintf( tmp, PATH_MAX, "%s/name", path );
|
||||||
|
FILE* f = fopen( tmp, "r" );
|
||||||
|
if( f )
|
||||||
|
{
|
||||||
|
char ntmp[128];
|
||||||
|
if( fgets( ntmp, 128, f ) )
|
||||||
|
{
|
||||||
|
// Last character is newline, skip it
|
||||||
|
const auto sz = strlen( ntmp ) - 1;
|
||||||
|
if( parent < 0 )
|
||||||
|
{
|
||||||
|
name = (char*)tracy_malloc( sz + 1 );
|
||||||
|
memcpy( name, ntmp, sz );
|
||||||
|
name[sz] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto p = m_domains[parent];
|
||||||
|
const auto psz = strlen( p.name );
|
||||||
|
name = (char*)tracy_malloc( psz + sz + 2 );
|
||||||
|
memcpy( name, p.name, psz );
|
||||||
|
name[psz] = ':';
|
||||||
|
memcpy( name+psz+1, ntmp, sz );
|
||||||
|
name[psz+sz+1] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose( f );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( strcmp( ent->d_name, "energy_uj" ) == 0 )
|
||||||
|
{
|
||||||
|
char tmp[PATH_MAX];
|
||||||
|
snprintf( tmp, PATH_MAX, "%s/energy_uj", path );
|
||||||
|
handle = fopen( tmp, "r" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( name && handle && maxRange > 0 ) break;
|
||||||
|
}
|
||||||
|
if( name && handle && maxRange > 0 )
|
||||||
|
{
|
||||||
|
parent = (int)m_domains.size();
|
||||||
|
Domain* domain = m_domains.push_next();
|
||||||
|
domain->value = 0;
|
||||||
|
domain->overflow = maxRange;
|
||||||
|
domain->handle = handle;
|
||||||
|
domain->name = name;
|
||||||
|
TracyDebug( "Power domain id %i, %s found at %s\n", parent, name, path );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( name ) tracy_free( name );
|
||||||
|
if( handle ) fclose( handle );
|
||||||
|
}
|
||||||
|
|
||||||
|
rewinddir( dir );
|
||||||
|
while( ( ent = readdir( dir ) ) )
|
||||||
|
{
|
||||||
|
if( ent->d_type == DT_DIR && strncmp( ent->d_name, "intel-rapl:", 11 ) == 0 )
|
||||||
|
{
|
||||||
|
char tmp[PATH_MAX];
|
||||||
|
snprintf( tmp, PATH_MAX, "%s/%s", path, ent->d_name );
|
||||||
|
ScanDirectory( tmp, parent );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir( dir );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
44
externals/tracy/public/client/TracySysPower.hpp
vendored
Normal file
44
externals/tracy/public/client/TracySysPower.hpp
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#ifndef __TRACYSYSPOWER_HPP__
|
||||||
|
#define __TRACYSYSPOWER_HPP__
|
||||||
|
|
||||||
|
#if defined __linux__
|
||||||
|
# define TRACY_HAS_SYSPOWER
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TRACY_HAS_SYSPOWER
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "TracyFastVector.hpp"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
class SysPower
|
||||||
|
{
|
||||||
|
struct Domain
|
||||||
|
{
|
||||||
|
uint64_t value;
|
||||||
|
uint64_t overflow;
|
||||||
|
FILE* handle;
|
||||||
|
const char* name;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
SysPower();
|
||||||
|
~SysPower();
|
||||||
|
|
||||||
|
void Tick();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ScanDirectory( const char* path, int parent );
|
||||||
|
|
||||||
|
FastVector<Domain> m_domains;
|
||||||
|
uint64_t m_lastTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
108
externals/tracy/public/client/TracySysTime.cpp
vendored
Normal file
108
externals/tracy/public/client/TracySysTime.cpp
vendored
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#include "TracySysTime.hpp"
|
||||||
|
|
||||||
|
#ifdef TRACY_HAS_SYSTIME
|
||||||
|
|
||||||
|
# if defined _WIN32
|
||||||
|
# include <windows.h>
|
||||||
|
# elif defined __linux__
|
||||||
|
# include <stdio.h>
|
||||||
|
# include <inttypes.h>
|
||||||
|
# elif defined __APPLE__
|
||||||
|
# include <mach/mach_host.h>
|
||||||
|
# include <mach/host_info.h>
|
||||||
|
# elif defined BSD
|
||||||
|
# include <sys/types.h>
|
||||||
|
# include <sys/sysctl.h>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
# if defined _WIN32
|
||||||
|
|
||||||
|
static inline uint64_t ConvertTime( const FILETIME& t )
|
||||||
|
{
|
||||||
|
return ( uint64_t( t.dwHighDateTime ) << 32 ) | uint64_t( t.dwLowDateTime );
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysTime::ReadTimes()
|
||||||
|
{
|
||||||
|
FILETIME idleTime;
|
||||||
|
FILETIME kernelTime;
|
||||||
|
FILETIME userTime;
|
||||||
|
|
||||||
|
GetSystemTimes( &idleTime, &kernelTime, &userTime );
|
||||||
|
|
||||||
|
idle = ConvertTime( idleTime );
|
||||||
|
const auto kernel = ConvertTime( kernelTime );
|
||||||
|
const auto user = ConvertTime( userTime );
|
||||||
|
used = kernel + user;
|
||||||
|
}
|
||||||
|
|
||||||
|
# elif defined __linux__
|
||||||
|
|
||||||
|
void SysTime::ReadTimes()
|
||||||
|
{
|
||||||
|
uint64_t user, nice, system;
|
||||||
|
FILE* f = fopen( "/proc/stat", "r" );
|
||||||
|
if( f )
|
||||||
|
{
|
||||||
|
int read = fscanf( f, "cpu %" PRIu64 " %" PRIu64 " %" PRIu64" %" PRIu64, &user, &nice, &system, &idle );
|
||||||
|
fclose( f );
|
||||||
|
if (read == 4)
|
||||||
|
{
|
||||||
|
used = user + nice + system;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# elif defined __APPLE__
|
||||||
|
|
||||||
|
void SysTime::ReadTimes()
|
||||||
|
{
|
||||||
|
host_cpu_load_info_data_t info;
|
||||||
|
mach_msg_type_number_t cnt = HOST_CPU_LOAD_INFO_COUNT;
|
||||||
|
host_statistics( mach_host_self(), HOST_CPU_LOAD_INFO, reinterpret_cast<host_info_t>( &info ), &cnt );
|
||||||
|
used = info.cpu_ticks[CPU_STATE_USER] + info.cpu_ticks[CPU_STATE_NICE] + info.cpu_ticks[CPU_STATE_SYSTEM];
|
||||||
|
idle = info.cpu_ticks[CPU_STATE_IDLE];
|
||||||
|
}
|
||||||
|
|
||||||
|
# elif defined BSD
|
||||||
|
|
||||||
|
void SysTime::ReadTimes()
|
||||||
|
{
|
||||||
|
u_long data[5];
|
||||||
|
size_t sz = sizeof( data );
|
||||||
|
sysctlbyname( "kern.cp_time", &data, &sz, nullptr, 0 );
|
||||||
|
used = data[0] + data[1] + data[2] + data[3];
|
||||||
|
idle = data[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SysTime::SysTime()
|
||||||
|
{
|
||||||
|
ReadTimes();
|
||||||
|
}
|
||||||
|
|
||||||
|
float SysTime::Get()
|
||||||
|
{
|
||||||
|
const auto oldUsed = used;
|
||||||
|
const auto oldIdle = idle;
|
||||||
|
|
||||||
|
ReadTimes();
|
||||||
|
|
||||||
|
const auto diffIdle = idle - oldIdle;
|
||||||
|
const auto diffUsed = used - oldUsed;
|
||||||
|
|
||||||
|
#if defined _WIN32
|
||||||
|
return diffUsed == 0 ? -1 : ( diffUsed - diffIdle ) * 100.f / diffUsed;
|
||||||
|
#elif defined __linux__ || defined __APPLE__ || defined BSD
|
||||||
|
const auto total = diffUsed + diffIdle;
|
||||||
|
return total == 0 ? -1 : diffUsed * 100.f / total;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
36
externals/tracy/public/client/TracySysTime.hpp
vendored
Normal file
36
externals/tracy/public/client/TracySysTime.hpp
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#ifndef __TRACYSYSTIME_HPP__
|
||||||
|
#define __TRACYSYSTIME_HPP__
|
||||||
|
|
||||||
|
#if defined _WIN32 || defined __linux__ || defined __APPLE__
|
||||||
|
# define TRACY_HAS_SYSTIME
|
||||||
|
#else
|
||||||
|
# include <sys/param.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSD
|
||||||
|
# define TRACY_HAS_SYSTIME
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TRACY_HAS_SYSTIME
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
class SysTime
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SysTime();
|
||||||
|
float Get();
|
||||||
|
|
||||||
|
void ReadTimes();
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint64_t idle, used;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
1602
externals/tracy/public/client/TracySysTrace.cpp
vendored
Normal file
1602
externals/tracy/public/client/TracySysTrace.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
28
externals/tracy/public/client/TracySysTrace.hpp
vendored
Normal file
28
externals/tracy/public/client/TracySysTrace.hpp
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef __TRACYSYSTRACE_HPP__
|
||||||
|
#define __TRACYSYSTRACE_HPP__
|
||||||
|
|
||||||
|
#if !defined TRACY_NO_SYSTEM_TRACING && ( defined _WIN32 || defined __linux__ )
|
||||||
|
# include "../common/TracyUwp.hpp"
|
||||||
|
# ifndef TRACY_UWP
|
||||||
|
# define TRACY_HAS_SYSTEM_TRACING
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TRACY_HAS_SYSTEM_TRACING
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
bool SysTraceStart( int64_t& samplingPeriod );
|
||||||
|
void SysTraceStop();
|
||||||
|
void SysTraceWorker( void* ptr );
|
||||||
|
|
||||||
|
void SysTraceGetExternalName( uint64_t thread, const char*& threadName, const char*& name );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
90
externals/tracy/public/client/TracyThread.hpp
vendored
Normal file
90
externals/tracy/public/client/TracyThread.hpp
vendored
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#ifndef __TRACYTHREAD_HPP__
|
||||||
|
#define __TRACYTHREAD_HPP__
|
||||||
|
|
||||||
|
#if defined _WIN32
|
||||||
|
# include <windows.h>
|
||||||
|
#else
|
||||||
|
# include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TRACY_MANUAL_LIFETIME
|
||||||
|
# include "tracy_rpmalloc.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef TRACY_MANUAL_LIFETIME
|
||||||
|
extern thread_local bool RpThreadInitDone;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class ThreadExitHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~ThreadExitHandler()
|
||||||
|
{
|
||||||
|
#ifdef TRACY_MANUAL_LIFETIME
|
||||||
|
rpmalloc_thread_finalize( 1 );
|
||||||
|
RpThreadInitDone = false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined _WIN32
|
||||||
|
|
||||||
|
class Thread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Thread( void(*func)( void* ptr ), void* ptr )
|
||||||
|
: m_func( func )
|
||||||
|
, m_ptr( ptr )
|
||||||
|
, m_hnd( CreateThread( nullptr, 0, Launch, this, 0, nullptr ) )
|
||||||
|
{}
|
||||||
|
|
||||||
|
~Thread()
|
||||||
|
{
|
||||||
|
WaitForSingleObject( m_hnd, INFINITE );
|
||||||
|
CloseHandle( m_hnd );
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE Handle() const { return m_hnd; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static DWORD WINAPI Launch( void* ptr ) { ((Thread*)ptr)->m_func( ((Thread*)ptr)->m_ptr ); return 0; }
|
||||||
|
|
||||||
|
void(*m_func)( void* ptr );
|
||||||
|
void* m_ptr;
|
||||||
|
HANDLE m_hnd;
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
class Thread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Thread( void(*func)( void* ptr ), void* ptr )
|
||||||
|
: m_func( func )
|
||||||
|
, m_ptr( ptr )
|
||||||
|
{
|
||||||
|
pthread_create( &m_thread, nullptr, Launch, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
~Thread()
|
||||||
|
{
|
||||||
|
pthread_join( m_thread, nullptr );
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_t Handle() const { return m_thread; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void* Launch( void* ptr ) { ((Thread*)ptr)->m_func( ((Thread*)ptr)->m_ptr ); return nullptr; }
|
||||||
|
void(*m_func)( void* ptr );
|
||||||
|
void* m_ptr;
|
||||||
|
pthread_t m_thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
148
externals/tracy/public/client/tracy_SPSCQueue.h
vendored
Normal file
148
externals/tracy/public/client/tracy_SPSCQueue.h
vendored
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2020 Erik Rigtorp <erik@rigtorp.se>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <type_traits> // std::enable_if, std::is_*_constructible
|
||||||
|
|
||||||
|
#include "../common/TracyAlloc.hpp"
|
||||||
|
|
||||||
|
#if defined (_MSC_VER)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4324)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace tracy {
|
||||||
|
|
||||||
|
template <typename T> class SPSCQueue {
|
||||||
|
public:
|
||||||
|
explicit SPSCQueue(const size_t capacity)
|
||||||
|
: capacity_(capacity) {
|
||||||
|
capacity_++; // Needs one slack element
|
||||||
|
slots_ = (T*)tracy_malloc(sizeof(T) * (capacity_ + 2 * kPadding));
|
||||||
|
|
||||||
|
static_assert(alignof(SPSCQueue<T>) == kCacheLineSize, "");
|
||||||
|
static_assert(sizeof(SPSCQueue<T>) >= 3 * kCacheLineSize, "");
|
||||||
|
assert(reinterpret_cast<char *>(&readIdx_) -
|
||||||
|
reinterpret_cast<char *>(&writeIdx_) >=
|
||||||
|
static_cast<std::ptrdiff_t>(kCacheLineSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
~SPSCQueue() {
|
||||||
|
while (front()) {
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
tracy_free(slots_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// non-copyable and non-movable
|
||||||
|
SPSCQueue(const SPSCQueue &) = delete;
|
||||||
|
SPSCQueue &operator=(const SPSCQueue &) = delete;
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
void emplace(Args &&...args) noexcept(
|
||||||
|
std::is_nothrow_constructible<T, Args &&...>::value) {
|
||||||
|
static_assert(std::is_constructible<T, Args &&...>::value,
|
||||||
|
"T must be constructible with Args&&...");
|
||||||
|
auto const writeIdx = writeIdx_.load(std::memory_order_relaxed);
|
||||||
|
auto nextWriteIdx = writeIdx + 1;
|
||||||
|
if (nextWriteIdx == capacity_) {
|
||||||
|
nextWriteIdx = 0;
|
||||||
|
}
|
||||||
|
while (nextWriteIdx == readIdxCache_) {
|
||||||
|
readIdxCache_ = readIdx_.load(std::memory_order_acquire);
|
||||||
|
}
|
||||||
|
new (&slots_[writeIdx + kPadding]) T(std::forward<Args>(args)...);
|
||||||
|
writeIdx_.store(nextWriteIdx, std::memory_order_release);
|
||||||
|
}
|
||||||
|
|
||||||
|
T *front() noexcept {
|
||||||
|
auto const readIdx = readIdx_.load(std::memory_order_relaxed);
|
||||||
|
if (readIdx == writeIdxCache_) {
|
||||||
|
writeIdxCache_ = writeIdx_.load(std::memory_order_acquire);
|
||||||
|
if (writeIdxCache_ == readIdx) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &slots_[readIdx + kPadding];
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop() noexcept {
|
||||||
|
static_assert(std::is_nothrow_destructible<T>::value,
|
||||||
|
"T must be nothrow destructible");
|
||||||
|
auto const readIdx = readIdx_.load(std::memory_order_relaxed);
|
||||||
|
assert(writeIdx_.load(std::memory_order_acquire) != readIdx);
|
||||||
|
slots_[readIdx + kPadding].~T();
|
||||||
|
auto nextReadIdx = readIdx + 1;
|
||||||
|
if (nextReadIdx == capacity_) {
|
||||||
|
nextReadIdx = 0;
|
||||||
|
}
|
||||||
|
readIdx_.store(nextReadIdx, std::memory_order_release);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const noexcept {
|
||||||
|
std::ptrdiff_t diff = writeIdx_.load(std::memory_order_acquire) -
|
||||||
|
readIdx_.load(std::memory_order_acquire);
|
||||||
|
if (diff < 0) {
|
||||||
|
diff += capacity_;
|
||||||
|
}
|
||||||
|
return static_cast<size_t>(diff);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() const noexcept {
|
||||||
|
return writeIdx_.load(std::memory_order_acquire) ==
|
||||||
|
readIdx_.load(std::memory_order_acquire);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t capacity() const noexcept { return capacity_ - 1; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr size_t kCacheLineSize = 64;
|
||||||
|
|
||||||
|
// Padding to avoid false sharing between slots_ and adjacent allocations
|
||||||
|
static constexpr size_t kPadding = (kCacheLineSize - 1) / sizeof(T) + 1;
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t capacity_;
|
||||||
|
T *slots_;
|
||||||
|
|
||||||
|
// Align to cache line size in order to avoid false sharing
|
||||||
|
// readIdxCache_ and writeIdxCache_ is used to reduce the amount of cache
|
||||||
|
// coherency traffic
|
||||||
|
alignas(kCacheLineSize) std::atomic<size_t> writeIdx_ = {0};
|
||||||
|
alignas(kCacheLineSize) size_t readIdxCache_ = 0;
|
||||||
|
alignas(kCacheLineSize) std::atomic<size_t> readIdx_ = {0};
|
||||||
|
alignas(kCacheLineSize) size_t writeIdxCache_ = 0;
|
||||||
|
|
||||||
|
// Padding to avoid adjacent allocations to share cache line with
|
||||||
|
// writeIdxCache_
|
||||||
|
char padding_[kCacheLineSize - sizeof(SPSCQueue<T>::writeIdxCache_)];
|
||||||
|
};
|
||||||
|
} // namespace rigtorp
|
||||||
|
|
||||||
|
#if defined (_MSC_VER)
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
1441
externals/tracy/public/client/tracy_concurrentqueue.h
vendored
Normal file
1441
externals/tracy/public/client/tracy_concurrentqueue.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3518
externals/tracy/public/client/tracy_rpmalloc.cpp
vendored
Normal file
3518
externals/tracy/public/client/tracy_rpmalloc.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
363
externals/tracy/public/client/tracy_rpmalloc.hpp
vendored
Normal file
363
externals/tracy/public/client/tracy_rpmalloc.hpp
vendored
Normal file
@ -0,0 +1,363 @@
|
|||||||
|
/* rpmalloc.h - Memory allocator - Public Domain - 2016 Mattias Jansson
|
||||||
|
*
|
||||||
|
* This library provides a cross-platform lock free thread caching malloc implementation in C11.
|
||||||
|
* The latest source code is always available at
|
||||||
|
*
|
||||||
|
* https://github.com/mjansson/rpmalloc
|
||||||
|
*
|
||||||
|
* This library is put in the public domain; you can redistribute it and/or modify it without any restrictions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "../common/TracyApi.h"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
|
# define RPMALLOC_EXPORT __attribute__((visibility("default")))
|
||||||
|
# define RPMALLOC_ALLOCATOR
|
||||||
|
# if (defined(__clang_major__) && (__clang_major__ < 4)) || (defined(__GNUC__) && defined(ENABLE_PRELOAD) && ENABLE_PRELOAD)
|
||||||
|
# define RPMALLOC_ATTRIB_MALLOC
|
||||||
|
# define RPMALLOC_ATTRIB_ALLOC_SIZE(size)
|
||||||
|
# define RPMALLOC_ATTRIB_ALLOC_SIZE2(count, size)
|
||||||
|
# else
|
||||||
|
# define RPMALLOC_ATTRIB_MALLOC __attribute__((__malloc__))
|
||||||
|
# define RPMALLOC_ATTRIB_ALLOC_SIZE(size) __attribute__((alloc_size(size)))
|
||||||
|
# define RPMALLOC_ATTRIB_ALLOC_SIZE2(count, size) __attribute__((alloc_size(count, size)))
|
||||||
|
# endif
|
||||||
|
# define RPMALLOC_CDECL
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
# define RPMALLOC_EXPORT
|
||||||
|
# define RPMALLOC_ALLOCATOR __declspec(allocator) __declspec(restrict)
|
||||||
|
# define RPMALLOC_ATTRIB_MALLOC
|
||||||
|
# define RPMALLOC_ATTRIB_ALLOC_SIZE(size)
|
||||||
|
# define RPMALLOC_ATTRIB_ALLOC_SIZE2(count,size)
|
||||||
|
# define RPMALLOC_CDECL __cdecl
|
||||||
|
#else
|
||||||
|
# define RPMALLOC_EXPORT
|
||||||
|
# define RPMALLOC_ALLOCATOR
|
||||||
|
# define RPMALLOC_ATTRIB_MALLOC
|
||||||
|
# define RPMALLOC_ATTRIB_ALLOC_SIZE(size)
|
||||||
|
# define RPMALLOC_ATTRIB_ALLOC_SIZE2(count,size)
|
||||||
|
# define RPMALLOC_CDECL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//! Define RPMALLOC_CONFIGURABLE to enable configuring sizes. Will introduce
|
||||||
|
// a very small overhead due to some size calculations not being compile time constants
|
||||||
|
#ifndef RPMALLOC_CONFIGURABLE
|
||||||
|
#define RPMALLOC_CONFIGURABLE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//! Define RPMALLOC_FIRST_CLASS_HEAPS to enable heap based API (rpmalloc_heap_* functions).
|
||||||
|
// Will introduce a very small overhead to track fully allocated spans in heaps
|
||||||
|
#ifndef RPMALLOC_FIRST_CLASS_HEAPS
|
||||||
|
#define RPMALLOC_FIRST_CLASS_HEAPS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//! Flag to rpaligned_realloc to not preserve content in reallocation
|
||||||
|
#define RPMALLOC_NO_PRESERVE 1
|
||||||
|
//! Flag to rpaligned_realloc to fail and return null pointer if grow cannot be done in-place,
|
||||||
|
// in which case the original pointer is still valid (just like a call to realloc which failes to allocate
|
||||||
|
// a new block).
|
||||||
|
#define RPMALLOC_GROW_OR_FAIL 2
|
||||||
|
|
||||||
|
typedef struct rpmalloc_global_statistics_t {
|
||||||
|
//! Current amount of virtual memory mapped, all of which might not have been committed (only if ENABLE_STATISTICS=1)
|
||||||
|
size_t mapped;
|
||||||
|
//! Peak amount of virtual memory mapped, all of which might not have been committed (only if ENABLE_STATISTICS=1)
|
||||||
|
size_t mapped_peak;
|
||||||
|
//! Current amount of memory in global caches for small and medium sizes (<32KiB)
|
||||||
|
size_t cached;
|
||||||
|
//! Current amount of memory allocated in huge allocations, i.e larger than LARGE_SIZE_LIMIT which is 2MiB by default (only if ENABLE_STATISTICS=1)
|
||||||
|
size_t huge_alloc;
|
||||||
|
//! Peak amount of memory allocated in huge allocations, i.e larger than LARGE_SIZE_LIMIT which is 2MiB by default (only if ENABLE_STATISTICS=1)
|
||||||
|
size_t huge_alloc_peak;
|
||||||
|
//! Total amount of memory mapped since initialization (only if ENABLE_STATISTICS=1)
|
||||||
|
size_t mapped_total;
|
||||||
|
//! Total amount of memory unmapped since initialization (only if ENABLE_STATISTICS=1)
|
||||||
|
size_t unmapped_total;
|
||||||
|
} rpmalloc_global_statistics_t;
|
||||||
|
|
||||||
|
typedef struct rpmalloc_thread_statistics_t {
|
||||||
|
//! Current number of bytes available in thread size class caches for small and medium sizes (<32KiB)
|
||||||
|
size_t sizecache;
|
||||||
|
//! Current number of bytes available in thread span caches for small and medium sizes (<32KiB)
|
||||||
|
size_t spancache;
|
||||||
|
//! Total number of bytes transitioned from thread cache to global cache (only if ENABLE_STATISTICS=1)
|
||||||
|
size_t thread_to_global;
|
||||||
|
//! Total number of bytes transitioned from global cache to thread cache (only if ENABLE_STATISTICS=1)
|
||||||
|
size_t global_to_thread;
|
||||||
|
//! Per span count statistics (only if ENABLE_STATISTICS=1)
|
||||||
|
struct {
|
||||||
|
//! Currently used number of spans
|
||||||
|
size_t current;
|
||||||
|
//! High water mark of spans used
|
||||||
|
size_t peak;
|
||||||
|
//! Number of spans transitioned to global cache
|
||||||
|
size_t to_global;
|
||||||
|
//! Number of spans transitioned from global cache
|
||||||
|
size_t from_global;
|
||||||
|
//! Number of spans transitioned to thread cache
|
||||||
|
size_t to_cache;
|
||||||
|
//! Number of spans transitioned from thread cache
|
||||||
|
size_t from_cache;
|
||||||
|
//! Number of spans transitioned to reserved state
|
||||||
|
size_t to_reserved;
|
||||||
|
//! Number of spans transitioned from reserved state
|
||||||
|
size_t from_reserved;
|
||||||
|
//! Number of raw memory map calls (not hitting the reserve spans but resulting in actual OS mmap calls)
|
||||||
|
size_t map_calls;
|
||||||
|
} span_use[64];
|
||||||
|
//! Per size class statistics (only if ENABLE_STATISTICS=1)
|
||||||
|
struct {
|
||||||
|
//! Current number of allocations
|
||||||
|
size_t alloc_current;
|
||||||
|
//! Peak number of allocations
|
||||||
|
size_t alloc_peak;
|
||||||
|
//! Total number of allocations
|
||||||
|
size_t alloc_total;
|
||||||
|
//! Total number of frees
|
||||||
|
size_t free_total;
|
||||||
|
//! Number of spans transitioned to cache
|
||||||
|
size_t spans_to_cache;
|
||||||
|
//! Number of spans transitioned from cache
|
||||||
|
size_t spans_from_cache;
|
||||||
|
//! Number of spans transitioned from reserved state
|
||||||
|
size_t spans_from_reserved;
|
||||||
|
//! Number of raw memory map calls (not hitting the reserve spans but resulting in actual OS mmap calls)
|
||||||
|
size_t map_calls;
|
||||||
|
} size_use[128];
|
||||||
|
} rpmalloc_thread_statistics_t;
|
||||||
|
|
||||||
|
typedef struct rpmalloc_config_t {
|
||||||
|
//! Map memory pages for the given number of bytes. The returned address MUST be
|
||||||
|
// aligned to the rpmalloc span size, which will always be a power of two.
|
||||||
|
// Optionally the function can store an alignment offset in the offset variable
|
||||||
|
// in case it performs alignment and the returned pointer is offset from the
|
||||||
|
// actual start of the memory region due to this alignment. The alignment offset
|
||||||
|
// will be passed to the memory unmap function. The alignment offset MUST NOT be
|
||||||
|
// larger than 65535 (storable in an uint16_t), if it is you must use natural
|
||||||
|
// alignment to shift it into 16 bits. If you set a memory_map function, you
|
||||||
|
// must also set a memory_unmap function or else the default implementation will
|
||||||
|
// be used for both. This function must be thread safe, it can be called by
|
||||||
|
// multiple threads simultaneously.
|
||||||
|
void* (*memory_map)(size_t size, size_t* offset);
|
||||||
|
//! Unmap the memory pages starting at address and spanning the given number of bytes.
|
||||||
|
// If release is set to non-zero, the unmap is for an entire span range as returned by
|
||||||
|
// a previous call to memory_map and that the entire range should be released. The
|
||||||
|
// release argument holds the size of the entire span range. If release is set to 0,
|
||||||
|
// the unmap is a partial decommit of a subset of the mapped memory range.
|
||||||
|
// If you set a memory_unmap function, you must also set a memory_map function or
|
||||||
|
// else the default implementation will be used for both. This function must be thread
|
||||||
|
// safe, it can be called by multiple threads simultaneously.
|
||||||
|
void (*memory_unmap)(void* address, size_t size, size_t offset, size_t release);
|
||||||
|
//! Called when an assert fails, if asserts are enabled. Will use the standard assert()
|
||||||
|
// if this is not set.
|
||||||
|
void (*error_callback)(const char* message);
|
||||||
|
//! Called when a call to map memory pages fails (out of memory). If this callback is
|
||||||
|
// not set or returns zero the library will return a null pointer in the allocation
|
||||||
|
// call. If this callback returns non-zero the map call will be retried. The argument
|
||||||
|
// passed is the number of bytes that was requested in the map call. Only used if
|
||||||
|
// the default system memory map function is used (memory_map callback is not set).
|
||||||
|
int (*map_fail_callback)(size_t size);
|
||||||
|
//! Size of memory pages. The page size MUST be a power of two. All memory mapping
|
||||||
|
// requests to memory_map will be made with size set to a multiple of the page size.
|
||||||
|
// Used if RPMALLOC_CONFIGURABLE is defined to 1, otherwise system page size is used.
|
||||||
|
size_t page_size;
|
||||||
|
//! Size of a span of memory blocks. MUST be a power of two, and in [4096,262144]
|
||||||
|
// range (unless 0 - set to 0 to use the default span size). Used if RPMALLOC_CONFIGURABLE
|
||||||
|
// is defined to 1.
|
||||||
|
size_t span_size;
|
||||||
|
//! Number of spans to map at each request to map new virtual memory blocks. This can
|
||||||
|
// be used to minimize the system call overhead at the cost of virtual memory address
|
||||||
|
// space. The extra mapped pages will not be written until actually used, so physical
|
||||||
|
// committed memory should not be affected in the default implementation. Will be
|
||||||
|
// aligned to a multiple of spans that match memory page size in case of huge pages.
|
||||||
|
size_t span_map_count;
|
||||||
|
//! Enable use of large/huge pages. If this flag is set to non-zero and page size is
|
||||||
|
// zero, the allocator will try to enable huge pages and auto detect the configuration.
|
||||||
|
// If this is set to non-zero and page_size is also non-zero, the allocator will
|
||||||
|
// assume huge pages have been configured and enabled prior to initializing the
|
||||||
|
// allocator.
|
||||||
|
// For Windows, see https://docs.microsoft.com/en-us/windows/desktop/memory/large-page-support
|
||||||
|
// For Linux, see https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt
|
||||||
|
int enable_huge_pages;
|
||||||
|
//! Respectively allocated pages and huge allocated pages names for systems
|
||||||
|
// supporting it to be able to distinguish among anonymous regions.
|
||||||
|
const char *page_name;
|
||||||
|
const char *huge_page_name;
|
||||||
|
} rpmalloc_config_t;
|
||||||
|
|
||||||
|
//! Initialize allocator with default configuration
|
||||||
|
TRACY_API int
|
||||||
|
rpmalloc_initialize(void);
|
||||||
|
|
||||||
|
//! Initialize allocator with given configuration
|
||||||
|
RPMALLOC_EXPORT int
|
||||||
|
rpmalloc_initialize_config(const rpmalloc_config_t* config);
|
||||||
|
|
||||||
|
//! Get allocator configuration
|
||||||
|
RPMALLOC_EXPORT const rpmalloc_config_t*
|
||||||
|
rpmalloc_config(void);
|
||||||
|
|
||||||
|
//! Finalize allocator
|
||||||
|
TRACY_API void
|
||||||
|
rpmalloc_finalize(void);
|
||||||
|
|
||||||
|
//! Initialize allocator for calling thread
|
||||||
|
TRACY_API void
|
||||||
|
rpmalloc_thread_initialize(void);
|
||||||
|
|
||||||
|
//! Finalize allocator for calling thread
|
||||||
|
TRACY_API void
|
||||||
|
rpmalloc_thread_finalize(int release_caches);
|
||||||
|
|
||||||
|
//! Perform deferred deallocations pending for the calling thread heap
|
||||||
|
RPMALLOC_EXPORT void
|
||||||
|
rpmalloc_thread_collect(void);
|
||||||
|
|
||||||
|
//! Query if allocator is initialized for calling thread
|
||||||
|
RPMALLOC_EXPORT int
|
||||||
|
rpmalloc_is_thread_initialized(void);
|
||||||
|
|
||||||
|
//! Get per-thread statistics
|
||||||
|
RPMALLOC_EXPORT void
|
||||||
|
rpmalloc_thread_statistics(rpmalloc_thread_statistics_t* stats);
|
||||||
|
|
||||||
|
//! Get global statistics
|
||||||
|
RPMALLOC_EXPORT void
|
||||||
|
rpmalloc_global_statistics(rpmalloc_global_statistics_t* stats);
|
||||||
|
|
||||||
|
//! Dump all statistics in human readable format to file (should be a FILE*)
|
||||||
|
RPMALLOC_EXPORT void
|
||||||
|
rpmalloc_dump_statistics(void* file);
|
||||||
|
|
||||||
|
//! Allocate a memory block of at least the given size
|
||||||
|
TRACY_API RPMALLOC_ALLOCATOR void*
|
||||||
|
rpmalloc(size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(1);
|
||||||
|
|
||||||
|
//! Free the given memory block
|
||||||
|
TRACY_API void
|
||||||
|
rpfree(void* ptr);
|
||||||
|
|
||||||
|
//! Allocate a memory block of at least the given size and zero initialize it
|
||||||
|
RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
|
||||||
|
rpcalloc(size_t num, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE2(1, 2);
|
||||||
|
|
||||||
|
//! Reallocate the given block to at least the given size
|
||||||
|
TRACY_API RPMALLOC_ALLOCATOR void*
|
||||||
|
rprealloc(void* ptr, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(2);
|
||||||
|
|
||||||
|
//! Reallocate the given block to at least the given size and alignment,
|
||||||
|
// with optional control flags (see RPMALLOC_NO_PRESERVE).
|
||||||
|
// Alignment must be a power of two and a multiple of sizeof(void*),
|
||||||
|
// and should ideally be less than memory page size. A caveat of rpmalloc
|
||||||
|
// internals is that this must also be strictly less than the span size (default 64KiB)
|
||||||
|
RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
|
||||||
|
rpaligned_realloc(void* ptr, size_t alignment, size_t size, size_t oldsize, unsigned int flags) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(3);
|
||||||
|
|
||||||
|
//! Allocate a memory block of at least the given size and alignment.
|
||||||
|
// Alignment must be a power of two and a multiple of sizeof(void*),
|
||||||
|
// and should ideally be less than memory page size. A caveat of rpmalloc
|
||||||
|
// internals is that this must also be strictly less than the span size (default 64KiB)
|
||||||
|
RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
|
||||||
|
rpaligned_alloc(size_t alignment, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(2);
|
||||||
|
|
||||||
|
//! Allocate a memory block of at least the given size and alignment, and zero initialize it.
|
||||||
|
// Alignment must be a power of two and a multiple of sizeof(void*),
|
||||||
|
// and should ideally be less than memory page size. A caveat of rpmalloc
|
||||||
|
// internals is that this must also be strictly less than the span size (default 64KiB)
|
||||||
|
RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
|
||||||
|
rpaligned_calloc(size_t alignment, size_t num, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE2(2, 3);
|
||||||
|
|
||||||
|
//! Allocate a memory block of at least the given size and alignment.
|
||||||
|
// Alignment must be a power of two and a multiple of sizeof(void*),
|
||||||
|
// and should ideally be less than memory page size. A caveat of rpmalloc
|
||||||
|
// internals is that this must also be strictly less than the span size (default 64KiB)
|
||||||
|
RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
|
||||||
|
rpmemalign(size_t alignment, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(2);
|
||||||
|
|
||||||
|
//! Allocate a memory block of at least the given size and alignment.
|
||||||
|
// Alignment must be a power of two and a multiple of sizeof(void*),
|
||||||
|
// and should ideally be less than memory page size. A caveat of rpmalloc
|
||||||
|
// internals is that this must also be strictly less than the span size (default 64KiB)
|
||||||
|
RPMALLOC_EXPORT int
|
||||||
|
rpposix_memalign(void** memptr, size_t alignment, size_t size);
|
||||||
|
|
||||||
|
//! Query the usable size of the given memory block (from given pointer to the end of block)
|
||||||
|
RPMALLOC_EXPORT size_t
|
||||||
|
rpmalloc_usable_size(void* ptr);
|
||||||
|
|
||||||
|
#if RPMALLOC_FIRST_CLASS_HEAPS
|
||||||
|
|
||||||
|
//! Heap type
|
||||||
|
typedef struct heap_t rpmalloc_heap_t;
|
||||||
|
|
||||||
|
//! Acquire a new heap. Will reuse existing released heaps or allocate memory for a new heap
|
||||||
|
// if none available. Heap API is implemented with the strict assumption that only one single
|
||||||
|
// thread will call heap functions for a given heap at any given time, no functions are thread safe.
|
||||||
|
RPMALLOC_EXPORT rpmalloc_heap_t*
|
||||||
|
rpmalloc_heap_acquire(void);
|
||||||
|
|
||||||
|
//! Release a heap (does NOT free the memory allocated by the heap, use rpmalloc_heap_free_all before destroying the heap).
|
||||||
|
// Releasing a heap will enable it to be reused by other threads. Safe to pass a null pointer.
|
||||||
|
RPMALLOC_EXPORT void
|
||||||
|
rpmalloc_heap_release(rpmalloc_heap_t* heap);
|
||||||
|
|
||||||
|
//! Allocate a memory block of at least the given size using the given heap.
|
||||||
|
RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
|
||||||
|
rpmalloc_heap_alloc(rpmalloc_heap_t* heap, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(2);
|
||||||
|
|
||||||
|
//! Allocate a memory block of at least the given size using the given heap. The returned
|
||||||
|
// block will have the requested alignment. Alignment must be a power of two and a multiple of sizeof(void*),
|
||||||
|
// and should ideally be less than memory page size. A caveat of rpmalloc
|
||||||
|
// internals is that this must also be strictly less than the span size (default 64KiB).
|
||||||
|
RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
|
||||||
|
rpmalloc_heap_aligned_alloc(rpmalloc_heap_t* heap, size_t alignment, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(3);
|
||||||
|
|
||||||
|
//! Allocate a memory block of at least the given size using the given heap and zero initialize it.
|
||||||
|
RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
|
||||||
|
rpmalloc_heap_calloc(rpmalloc_heap_t* heap, size_t num, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE2(2, 3);
|
||||||
|
|
||||||
|
//! Allocate a memory block of at least the given size using the given heap and zero initialize it. The returned
|
||||||
|
// block will have the requested alignment. Alignment must either be zero, or a power of two and a multiple of sizeof(void*),
|
||||||
|
// and should ideally be less than memory page size. A caveat of rpmalloc
|
||||||
|
// internals is that this must also be strictly less than the span size (default 64KiB).
|
||||||
|
RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
|
||||||
|
rpmalloc_heap_aligned_calloc(rpmalloc_heap_t* heap, size_t alignment, size_t num, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE2(2, 3);
|
||||||
|
|
||||||
|
//! Reallocate the given block to at least the given size. The memory block MUST be allocated
|
||||||
|
// by the same heap given to this function.
|
||||||
|
RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
|
||||||
|
rpmalloc_heap_realloc(rpmalloc_heap_t* heap, void* ptr, size_t size, unsigned int flags) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(3);
|
||||||
|
|
||||||
|
//! Reallocate the given block to at least the given size. The memory block MUST be allocated
|
||||||
|
// by the same heap given to this function. The returned block will have the requested alignment.
|
||||||
|
// Alignment must be either zero, or a power of two and a multiple of sizeof(void*), and should ideally be
|
||||||
|
// less than memory page size. A caveat of rpmalloc internals is that this must also be strictly less than
|
||||||
|
// the span size (default 64KiB).
|
||||||
|
RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
|
||||||
|
rpmalloc_heap_aligned_realloc(rpmalloc_heap_t* heap, void* ptr, size_t alignment, size_t size, unsigned int flags) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(4);
|
||||||
|
|
||||||
|
//! Free the given memory block from the given heap. The memory block MUST be allocated
|
||||||
|
// by the same heap given to this function.
|
||||||
|
RPMALLOC_EXPORT void
|
||||||
|
rpmalloc_heap_free(rpmalloc_heap_t* heap, void* ptr);
|
||||||
|
|
||||||
|
//! Free all memory allocated by the heap
|
||||||
|
RPMALLOC_EXPORT void
|
||||||
|
rpmalloc_heap_free_all(rpmalloc_heap_t* heap);
|
||||||
|
|
||||||
|
//! Set the given heap as the current heap for the calling thread. A heap MUST only be current heap
|
||||||
|
// for a single thread, a heap can never be shared between multiple threads. The previous
|
||||||
|
// current heap for the calling thread is released to be reused by other threads.
|
||||||
|
RPMALLOC_EXPORT void
|
||||||
|
rpmalloc_heap_thread_set_current(rpmalloc_heap_t* heap);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
27
externals/tracy/public/common/TracyAlign.hpp
vendored
Normal file
27
externals/tracy/public/common/TracyAlign.hpp
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef __TRACYALIGN_HPP__
|
||||||
|
#define __TRACYALIGN_HPP__
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "TracyForceInline.hpp"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
tracy_force_inline T MemRead( const void* ptr )
|
||||||
|
{
|
||||||
|
T val;
|
||||||
|
memcpy( &val, ptr, sizeof( T ) );
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
tracy_force_inline void MemWrite( void* ptr, T val )
|
||||||
|
{
|
||||||
|
memcpy( ptr, &val, sizeof( T ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
72
externals/tracy/public/common/TracyAlloc.hpp
vendored
Normal file
72
externals/tracy/public/common/TracyAlloc.hpp
vendored
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#ifndef __TRACYALLOC_HPP__
|
||||||
|
#define __TRACYALLOC_HPP__
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#if defined TRACY_ENABLE && !defined __EMSCRIPTEN__
|
||||||
|
# include "TracyApi.h"
|
||||||
|
# include "TracyForceInline.hpp"
|
||||||
|
# include "../client/tracy_rpmalloc.hpp"
|
||||||
|
# define TRACY_USE_RPMALLOC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef TRACY_USE_RPMALLOC
|
||||||
|
TRACY_API void InitRpmalloc();
|
||||||
|
#else
|
||||||
|
static inline void InitRpmalloc() {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline void* tracy_malloc( size_t size )
|
||||||
|
{
|
||||||
|
#ifdef TRACY_USE_RPMALLOC
|
||||||
|
InitRpmalloc();
|
||||||
|
return rpmalloc( size );
|
||||||
|
#else
|
||||||
|
return malloc( size );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void* tracy_malloc_fast( size_t size )
|
||||||
|
{
|
||||||
|
#ifdef TRACY_USE_RPMALLOC
|
||||||
|
return rpmalloc( size );
|
||||||
|
#else
|
||||||
|
return malloc( size );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void tracy_free( void* ptr )
|
||||||
|
{
|
||||||
|
#ifdef TRACY_USE_RPMALLOC
|
||||||
|
InitRpmalloc();
|
||||||
|
rpfree( ptr );
|
||||||
|
#else
|
||||||
|
free( ptr );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void tracy_free_fast( void* ptr )
|
||||||
|
{
|
||||||
|
#ifdef TRACY_USE_RPMALLOC
|
||||||
|
rpfree( ptr );
|
||||||
|
#else
|
||||||
|
free( ptr );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void* tracy_realloc( void* ptr, size_t size )
|
||||||
|
{
|
||||||
|
#ifdef TRACY_USE_RPMALLOC
|
||||||
|
InitRpmalloc();
|
||||||
|
return rprealloc( ptr, size );
|
||||||
|
#else
|
||||||
|
return realloc( ptr, size );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
16
externals/tracy/public/common/TracyApi.h
vendored
Normal file
16
externals/tracy/public/common/TracyApi.h
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef __TRACYAPI_H__
|
||||||
|
#define __TRACYAPI_H__
|
||||||
|
|
||||||
|
#if defined _WIN32
|
||||||
|
# if defined TRACY_EXPORTS
|
||||||
|
# define TRACY_API __declspec(dllexport)
|
||||||
|
# elif defined TRACY_IMPORTS
|
||||||
|
# define TRACY_API __declspec(dllimport)
|
||||||
|
# else
|
||||||
|
# define TRACY_API
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define TRACY_API __attribute__((visibility("default")))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __TRACYAPI_H__
|
690
externals/tracy/public/common/TracyColor.hpp
vendored
Normal file
690
externals/tracy/public/common/TracyColor.hpp
vendored
Normal file
@ -0,0 +1,690 @@
|
|||||||
|
#ifndef __TRACYCOLOR_HPP__
|
||||||
|
#define __TRACYCOLOR_HPP__
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
struct Color
|
||||||
|
{
|
||||||
|
enum ColorType
|
||||||
|
{
|
||||||
|
Snow = 0xfffafa,
|
||||||
|
GhostWhite = 0xf8f8ff,
|
||||||
|
WhiteSmoke = 0xf5f5f5,
|
||||||
|
Gainsboro = 0xdcdcdc,
|
||||||
|
FloralWhite = 0xfffaf0,
|
||||||
|
OldLace = 0xfdf5e6,
|
||||||
|
Linen = 0xfaf0e6,
|
||||||
|
AntiqueWhite = 0xfaebd7,
|
||||||
|
PapayaWhip = 0xffefd5,
|
||||||
|
BlanchedAlmond = 0xffebcd,
|
||||||
|
Bisque = 0xffe4c4,
|
||||||
|
PeachPuff = 0xffdab9,
|
||||||
|
NavajoWhite = 0xffdead,
|
||||||
|
Moccasin = 0xffe4b5,
|
||||||
|
Cornsilk = 0xfff8dc,
|
||||||
|
Ivory = 0xfffff0,
|
||||||
|
LemonChiffon = 0xfffacd,
|
||||||
|
Seashell = 0xfff5ee,
|
||||||
|
Honeydew = 0xf0fff0,
|
||||||
|
MintCream = 0xf5fffa,
|
||||||
|
Azure = 0xf0ffff,
|
||||||
|
AliceBlue = 0xf0f8ff,
|
||||||
|
Lavender = 0xe6e6fa,
|
||||||
|
LavenderBlush = 0xfff0f5,
|
||||||
|
MistyRose = 0xffe4e1,
|
||||||
|
White = 0xffffff,
|
||||||
|
Black = 0x000000,
|
||||||
|
DarkSlateGray = 0x2f4f4f,
|
||||||
|
DarkSlateGrey = 0x2f4f4f,
|
||||||
|
DimGray = 0x696969,
|
||||||
|
DimGrey = 0x696969,
|
||||||
|
SlateGray = 0x708090,
|
||||||
|
SlateGrey = 0x708090,
|
||||||
|
LightSlateGray = 0x778899,
|
||||||
|
LightSlateGrey = 0x778899,
|
||||||
|
Gray = 0xbebebe,
|
||||||
|
Grey = 0xbebebe,
|
||||||
|
X11Gray = 0xbebebe,
|
||||||
|
X11Grey = 0xbebebe,
|
||||||
|
WebGray = 0x808080,
|
||||||
|
WebGrey = 0x808080,
|
||||||
|
LightGrey = 0xd3d3d3,
|
||||||
|
LightGray = 0xd3d3d3,
|
||||||
|
MidnightBlue = 0x191970,
|
||||||
|
Navy = 0x000080,
|
||||||
|
NavyBlue = 0x000080,
|
||||||
|
CornflowerBlue = 0x6495ed,
|
||||||
|
DarkSlateBlue = 0x483d8b,
|
||||||
|
SlateBlue = 0x6a5acd,
|
||||||
|
MediumSlateBlue = 0x7b68ee,
|
||||||
|
LightSlateBlue = 0x8470ff,
|
||||||
|
MediumBlue = 0x0000cd,
|
||||||
|
RoyalBlue = 0x4169e1,
|
||||||
|
Blue = 0x0000ff,
|
||||||
|
DodgerBlue = 0x1e90ff,
|
||||||
|
DeepSkyBlue = 0x00bfff,
|
||||||
|
SkyBlue = 0x87ceeb,
|
||||||
|
LightSkyBlue = 0x87cefa,
|
||||||
|
SteelBlue = 0x4682b4,
|
||||||
|
LightSteelBlue = 0xb0c4de,
|
||||||
|
LightBlue = 0xadd8e6,
|
||||||
|
PowderBlue = 0xb0e0e6,
|
||||||
|
PaleTurquoise = 0xafeeee,
|
||||||
|
DarkTurquoise = 0x00ced1,
|
||||||
|
MediumTurquoise = 0x48d1cc,
|
||||||
|
Turquoise = 0x40e0d0,
|
||||||
|
Cyan = 0x00ffff,
|
||||||
|
Aqua = 0x00ffff,
|
||||||
|
LightCyan = 0xe0ffff,
|
||||||
|
CadetBlue = 0x5f9ea0,
|
||||||
|
MediumAquamarine = 0x66cdaa,
|
||||||
|
Aquamarine = 0x7fffd4,
|
||||||
|
DarkGreen = 0x006400,
|
||||||
|
DarkOliveGreen = 0x556b2f,
|
||||||
|
DarkSeaGreen = 0x8fbc8f,
|
||||||
|
SeaGreen = 0x2e8b57,
|
||||||
|
MediumSeaGreen = 0x3cb371,
|
||||||
|
LightSeaGreen = 0x20b2aa,
|
||||||
|
PaleGreen = 0x98fb98,
|
||||||
|
SpringGreen = 0x00ff7f,
|
||||||
|
LawnGreen = 0x7cfc00,
|
||||||
|
Green = 0x00ff00,
|
||||||
|
Lime = 0x00ff00,
|
||||||
|
X11Green = 0x00ff00,
|
||||||
|
WebGreen = 0x008000,
|
||||||
|
Chartreuse = 0x7fff00,
|
||||||
|
MediumSpringGreen = 0x00fa9a,
|
||||||
|
GreenYellow = 0xadff2f,
|
||||||
|
LimeGreen = 0x32cd32,
|
||||||
|
YellowGreen = 0x9acd32,
|
||||||
|
ForestGreen = 0x228b22,
|
||||||
|
OliveDrab = 0x6b8e23,
|
||||||
|
DarkKhaki = 0xbdb76b,
|
||||||
|
Khaki = 0xf0e68c,
|
||||||
|
PaleGoldenrod = 0xeee8aa,
|
||||||
|
LightGoldenrodYellow = 0xfafad2,
|
||||||
|
LightYellow = 0xffffe0,
|
||||||
|
Yellow = 0xffff00,
|
||||||
|
Gold = 0xffd700,
|
||||||
|
LightGoldenrod = 0xeedd82,
|
||||||
|
Goldenrod = 0xdaa520,
|
||||||
|
DarkGoldenrod = 0xb8860b,
|
||||||
|
RosyBrown = 0xbc8f8f,
|
||||||
|
IndianRed = 0xcd5c5c,
|
||||||
|
SaddleBrown = 0x8b4513,
|
||||||
|
Sienna = 0xa0522d,
|
||||||
|
Peru = 0xcd853f,
|
||||||
|
Burlywood = 0xdeb887,
|
||||||
|
Beige = 0xf5f5dc,
|
||||||
|
Wheat = 0xf5deb3,
|
||||||
|
SandyBrown = 0xf4a460,
|
||||||
|
Tan = 0xd2b48c,
|
||||||
|
Chocolate = 0xd2691e,
|
||||||
|
Firebrick = 0xb22222,
|
||||||
|
Brown = 0xa52a2a,
|
||||||
|
DarkSalmon = 0xe9967a,
|
||||||
|
Salmon = 0xfa8072,
|
||||||
|
LightSalmon = 0xffa07a,
|
||||||
|
Orange = 0xffa500,
|
||||||
|
DarkOrange = 0xff8c00,
|
||||||
|
Coral = 0xff7f50,
|
||||||
|
LightCoral = 0xf08080,
|
||||||
|
Tomato = 0xff6347,
|
||||||
|
OrangeRed = 0xff4500,
|
||||||
|
Red = 0xff0000,
|
||||||
|
HotPink = 0xff69b4,
|
||||||
|
DeepPink = 0xff1493,
|
||||||
|
Pink = 0xffc0cb,
|
||||||
|
LightPink = 0xffb6c1,
|
||||||
|
PaleVioletRed = 0xdb7093,
|
||||||
|
Maroon = 0xb03060,
|
||||||
|
X11Maroon = 0xb03060,
|
||||||
|
WebMaroon = 0x800000,
|
||||||
|
MediumVioletRed = 0xc71585,
|
||||||
|
VioletRed = 0xd02090,
|
||||||
|
Magenta = 0xff00ff,
|
||||||
|
Fuchsia = 0xff00ff,
|
||||||
|
Violet = 0xee82ee,
|
||||||
|
Plum = 0xdda0dd,
|
||||||
|
Orchid = 0xda70d6,
|
||||||
|
MediumOrchid = 0xba55d3,
|
||||||
|
DarkOrchid = 0x9932cc,
|
||||||
|
DarkViolet = 0x9400d3,
|
||||||
|
BlueViolet = 0x8a2be2,
|
||||||
|
Purple = 0xa020f0,
|
||||||
|
X11Purple = 0xa020f0,
|
||||||
|
WebPurple = 0x800080,
|
||||||
|
MediumPurple = 0x9370db,
|
||||||
|
Thistle = 0xd8bfd8,
|
||||||
|
Snow1 = 0xfffafa,
|
||||||
|
Snow2 = 0xeee9e9,
|
||||||
|
Snow3 = 0xcdc9c9,
|
||||||
|
Snow4 = 0x8b8989,
|
||||||
|
Seashell1 = 0xfff5ee,
|
||||||
|
Seashell2 = 0xeee5de,
|
||||||
|
Seashell3 = 0xcdc5bf,
|
||||||
|
Seashell4 = 0x8b8682,
|
||||||
|
AntiqueWhite1 = 0xffefdb,
|
||||||
|
AntiqueWhite2 = 0xeedfcc,
|
||||||
|
AntiqueWhite3 = 0xcdc0b0,
|
||||||
|
AntiqueWhite4 = 0x8b8378,
|
||||||
|
Bisque1 = 0xffe4c4,
|
||||||
|
Bisque2 = 0xeed5b7,
|
||||||
|
Bisque3 = 0xcdb79e,
|
||||||
|
Bisque4 = 0x8b7d6b,
|
||||||
|
PeachPuff1 = 0xffdab9,
|
||||||
|
PeachPuff2 = 0xeecbad,
|
||||||
|
PeachPuff3 = 0xcdaf95,
|
||||||
|
PeachPuff4 = 0x8b7765,
|
||||||
|
NavajoWhite1 = 0xffdead,
|
||||||
|
NavajoWhite2 = 0xeecfa1,
|
||||||
|
NavajoWhite3 = 0xcdb38b,
|
||||||
|
NavajoWhite4 = 0x8b795e,
|
||||||
|
LemonChiffon1 = 0xfffacd,
|
||||||
|
LemonChiffon2 = 0xeee9bf,
|
||||||
|
LemonChiffon3 = 0xcdc9a5,
|
||||||
|
LemonChiffon4 = 0x8b8970,
|
||||||
|
Cornsilk1 = 0xfff8dc,
|
||||||
|
Cornsilk2 = 0xeee8cd,
|
||||||
|
Cornsilk3 = 0xcdc8b1,
|
||||||
|
Cornsilk4 = 0x8b8878,
|
||||||
|
Ivory1 = 0xfffff0,
|
||||||
|
Ivory2 = 0xeeeee0,
|
||||||
|
Ivory3 = 0xcdcdc1,
|
||||||
|
Ivory4 = 0x8b8b83,
|
||||||
|
Honeydew1 = 0xf0fff0,
|
||||||
|
Honeydew2 = 0xe0eee0,
|
||||||
|
Honeydew3 = 0xc1cdc1,
|
||||||
|
Honeydew4 = 0x838b83,
|
||||||
|
LavenderBlush1 = 0xfff0f5,
|
||||||
|
LavenderBlush2 = 0xeee0e5,
|
||||||
|
LavenderBlush3 = 0xcdc1c5,
|
||||||
|
LavenderBlush4 = 0x8b8386,
|
||||||
|
MistyRose1 = 0xffe4e1,
|
||||||
|
MistyRose2 = 0xeed5d2,
|
||||||
|
MistyRose3 = 0xcdb7b5,
|
||||||
|
MistyRose4 = 0x8b7d7b,
|
||||||
|
Azure1 = 0xf0ffff,
|
||||||
|
Azure2 = 0xe0eeee,
|
||||||
|
Azure3 = 0xc1cdcd,
|
||||||
|
Azure4 = 0x838b8b,
|
||||||
|
SlateBlue1 = 0x836fff,
|
||||||
|
SlateBlue2 = 0x7a67ee,
|
||||||
|
SlateBlue3 = 0x6959cd,
|
||||||
|
SlateBlue4 = 0x473c8b,
|
||||||
|
RoyalBlue1 = 0x4876ff,
|
||||||
|
RoyalBlue2 = 0x436eee,
|
||||||
|
RoyalBlue3 = 0x3a5fcd,
|
||||||
|
RoyalBlue4 = 0x27408b,
|
||||||
|
Blue1 = 0x0000ff,
|
||||||
|
Blue2 = 0x0000ee,
|
||||||
|
Blue3 = 0x0000cd,
|
||||||
|
Blue4 = 0x00008b,
|
||||||
|
DodgerBlue1 = 0x1e90ff,
|
||||||
|
DodgerBlue2 = 0x1c86ee,
|
||||||
|
DodgerBlue3 = 0x1874cd,
|
||||||
|
DodgerBlue4 = 0x104e8b,
|
||||||
|
SteelBlue1 = 0x63b8ff,
|
||||||
|
SteelBlue2 = 0x5cacee,
|
||||||
|
SteelBlue3 = 0x4f94cd,
|
||||||
|
SteelBlue4 = 0x36648b,
|
||||||
|
DeepSkyBlue1 = 0x00bfff,
|
||||||
|
DeepSkyBlue2 = 0x00b2ee,
|
||||||
|
DeepSkyBlue3 = 0x009acd,
|
||||||
|
DeepSkyBlue4 = 0x00688b,
|
||||||
|
SkyBlue1 = 0x87ceff,
|
||||||
|
SkyBlue2 = 0x7ec0ee,
|
||||||
|
SkyBlue3 = 0x6ca6cd,
|
||||||
|
SkyBlue4 = 0x4a708b,
|
||||||
|
LightSkyBlue1 = 0xb0e2ff,
|
||||||
|
LightSkyBlue2 = 0xa4d3ee,
|
||||||
|
LightSkyBlue3 = 0x8db6cd,
|
||||||
|
LightSkyBlue4 = 0x607b8b,
|
||||||
|
SlateGray1 = 0xc6e2ff,
|
||||||
|
SlateGray2 = 0xb9d3ee,
|
||||||
|
SlateGray3 = 0x9fb6cd,
|
||||||
|
SlateGray4 = 0x6c7b8b,
|
||||||
|
LightSteelBlue1 = 0xcae1ff,
|
||||||
|
LightSteelBlue2 = 0xbcd2ee,
|
||||||
|
LightSteelBlue3 = 0xa2b5cd,
|
||||||
|
LightSteelBlue4 = 0x6e7b8b,
|
||||||
|
LightBlue1 = 0xbfefff,
|
||||||
|
LightBlue2 = 0xb2dfee,
|
||||||
|
LightBlue3 = 0x9ac0cd,
|
||||||
|
LightBlue4 = 0x68838b,
|
||||||
|
LightCyan1 = 0xe0ffff,
|
||||||
|
LightCyan2 = 0xd1eeee,
|
||||||
|
LightCyan3 = 0xb4cdcd,
|
||||||
|
LightCyan4 = 0x7a8b8b,
|
||||||
|
PaleTurquoise1 = 0xbbffff,
|
||||||
|
PaleTurquoise2 = 0xaeeeee,
|
||||||
|
PaleTurquoise3 = 0x96cdcd,
|
||||||
|
PaleTurquoise4 = 0x668b8b,
|
||||||
|
CadetBlue1 = 0x98f5ff,
|
||||||
|
CadetBlue2 = 0x8ee5ee,
|
||||||
|
CadetBlue3 = 0x7ac5cd,
|
||||||
|
CadetBlue4 = 0x53868b,
|
||||||
|
Turquoise1 = 0x00f5ff,
|
||||||
|
Turquoise2 = 0x00e5ee,
|
||||||
|
Turquoise3 = 0x00c5cd,
|
||||||
|
Turquoise4 = 0x00868b,
|
||||||
|
Cyan1 = 0x00ffff,
|
||||||
|
Cyan2 = 0x00eeee,
|
||||||
|
Cyan3 = 0x00cdcd,
|
||||||
|
Cyan4 = 0x008b8b,
|
||||||
|
DarkSlateGray1 = 0x97ffff,
|
||||||
|
DarkSlateGray2 = 0x8deeee,
|
||||||
|
DarkSlateGray3 = 0x79cdcd,
|
||||||
|
DarkSlateGray4 = 0x528b8b,
|
||||||
|
Aquamarine1 = 0x7fffd4,
|
||||||
|
Aquamarine2 = 0x76eec6,
|
||||||
|
Aquamarine3 = 0x66cdaa,
|
||||||
|
Aquamarine4 = 0x458b74,
|
||||||
|
DarkSeaGreen1 = 0xc1ffc1,
|
||||||
|
DarkSeaGreen2 = 0xb4eeb4,
|
||||||
|
DarkSeaGreen3 = 0x9bcd9b,
|
||||||
|
DarkSeaGreen4 = 0x698b69,
|
||||||
|
SeaGreen1 = 0x54ff9f,
|
||||||
|
SeaGreen2 = 0x4eee94,
|
||||||
|
SeaGreen3 = 0x43cd80,
|
||||||
|
SeaGreen4 = 0x2e8b57,
|
||||||
|
PaleGreen1 = 0x9aff9a,
|
||||||
|
PaleGreen2 = 0x90ee90,
|
||||||
|
PaleGreen3 = 0x7ccd7c,
|
||||||
|
PaleGreen4 = 0x548b54,
|
||||||
|
SpringGreen1 = 0x00ff7f,
|
||||||
|
SpringGreen2 = 0x00ee76,
|
||||||
|
SpringGreen3 = 0x00cd66,
|
||||||
|
SpringGreen4 = 0x008b45,
|
||||||
|
Green1 = 0x00ff00,
|
||||||
|
Green2 = 0x00ee00,
|
||||||
|
Green3 = 0x00cd00,
|
||||||
|
Green4 = 0x008b00,
|
||||||
|
Chartreuse1 = 0x7fff00,
|
||||||
|
Chartreuse2 = 0x76ee00,
|
||||||
|
Chartreuse3 = 0x66cd00,
|
||||||
|
Chartreuse4 = 0x458b00,
|
||||||
|
OliveDrab1 = 0xc0ff3e,
|
||||||
|
OliveDrab2 = 0xb3ee3a,
|
||||||
|
OliveDrab3 = 0x9acd32,
|
||||||
|
OliveDrab4 = 0x698b22,
|
||||||
|
DarkOliveGreen1 = 0xcaff70,
|
||||||
|
DarkOliveGreen2 = 0xbcee68,
|
||||||
|
DarkOliveGreen3 = 0xa2cd5a,
|
||||||
|
DarkOliveGreen4 = 0x6e8b3d,
|
||||||
|
Khaki1 = 0xfff68f,
|
||||||
|
Khaki2 = 0xeee685,
|
||||||
|
Khaki3 = 0xcdc673,
|
||||||
|
Khaki4 = 0x8b864e,
|
||||||
|
LightGoldenrod1 = 0xffec8b,
|
||||||
|
LightGoldenrod2 = 0xeedc82,
|
||||||
|
LightGoldenrod3 = 0xcdbe70,
|
||||||
|
LightGoldenrod4 = 0x8b814c,
|
||||||
|
LightYellow1 = 0xffffe0,
|
||||||
|
LightYellow2 = 0xeeeed1,
|
||||||
|
LightYellow3 = 0xcdcdb4,
|
||||||
|
LightYellow4 = 0x8b8b7a,
|
||||||
|
Yellow1 = 0xffff00,
|
||||||
|
Yellow2 = 0xeeee00,
|
||||||
|
Yellow3 = 0xcdcd00,
|
||||||
|
Yellow4 = 0x8b8b00,
|
||||||
|
Gold1 = 0xffd700,
|
||||||
|
Gold2 = 0xeec900,
|
||||||
|
Gold3 = 0xcdad00,
|
||||||
|
Gold4 = 0x8b7500,
|
||||||
|
Goldenrod1 = 0xffc125,
|
||||||
|
Goldenrod2 = 0xeeb422,
|
||||||
|
Goldenrod3 = 0xcd9b1d,
|
||||||
|
Goldenrod4 = 0x8b6914,
|
||||||
|
DarkGoldenrod1 = 0xffb90f,
|
||||||
|
DarkGoldenrod2 = 0xeead0e,
|
||||||
|
DarkGoldenrod3 = 0xcd950c,
|
||||||
|
DarkGoldenrod4 = 0x8b6508,
|
||||||
|
RosyBrown1 = 0xffc1c1,
|
||||||
|
RosyBrown2 = 0xeeb4b4,
|
||||||
|
RosyBrown3 = 0xcd9b9b,
|
||||||
|
RosyBrown4 = 0x8b6969,
|
||||||
|
IndianRed1 = 0xff6a6a,
|
||||||
|
IndianRed2 = 0xee6363,
|
||||||
|
IndianRed3 = 0xcd5555,
|
||||||
|
IndianRed4 = 0x8b3a3a,
|
||||||
|
Sienna1 = 0xff8247,
|
||||||
|
Sienna2 = 0xee7942,
|
||||||
|
Sienna3 = 0xcd6839,
|
||||||
|
Sienna4 = 0x8b4726,
|
||||||
|
Burlywood1 = 0xffd39b,
|
||||||
|
Burlywood2 = 0xeec591,
|
||||||
|
Burlywood3 = 0xcdaa7d,
|
||||||
|
Burlywood4 = 0x8b7355,
|
||||||
|
Wheat1 = 0xffe7ba,
|
||||||
|
Wheat2 = 0xeed8ae,
|
||||||
|
Wheat3 = 0xcdba96,
|
||||||
|
Wheat4 = 0x8b7e66,
|
||||||
|
Tan1 = 0xffa54f,
|
||||||
|
Tan2 = 0xee9a49,
|
||||||
|
Tan3 = 0xcd853f,
|
||||||
|
Tan4 = 0x8b5a2b,
|
||||||
|
Chocolate1 = 0xff7f24,
|
||||||
|
Chocolate2 = 0xee7621,
|
||||||
|
Chocolate3 = 0xcd661d,
|
||||||
|
Chocolate4 = 0x8b4513,
|
||||||
|
Firebrick1 = 0xff3030,
|
||||||
|
Firebrick2 = 0xee2c2c,
|
||||||
|
Firebrick3 = 0xcd2626,
|
||||||
|
Firebrick4 = 0x8b1a1a,
|
||||||
|
Brown1 = 0xff4040,
|
||||||
|
Brown2 = 0xee3b3b,
|
||||||
|
Brown3 = 0xcd3333,
|
||||||
|
Brown4 = 0x8b2323,
|
||||||
|
Salmon1 = 0xff8c69,
|
||||||
|
Salmon2 = 0xee8262,
|
||||||
|
Salmon3 = 0xcd7054,
|
||||||
|
Salmon4 = 0x8b4c39,
|
||||||
|
LightSalmon1 = 0xffa07a,
|
||||||
|
LightSalmon2 = 0xee9572,
|
||||||
|
LightSalmon3 = 0xcd8162,
|
||||||
|
LightSalmon4 = 0x8b5742,
|
||||||
|
Orange1 = 0xffa500,
|
||||||
|
Orange2 = 0xee9a00,
|
||||||
|
Orange3 = 0xcd8500,
|
||||||
|
Orange4 = 0x8b5a00,
|
||||||
|
DarkOrange1 = 0xff7f00,
|
||||||
|
DarkOrange2 = 0xee7600,
|
||||||
|
DarkOrange3 = 0xcd6600,
|
||||||
|
DarkOrange4 = 0x8b4500,
|
||||||
|
Coral1 = 0xff7256,
|
||||||
|
Coral2 = 0xee6a50,
|
||||||
|
Coral3 = 0xcd5b45,
|
||||||
|
Coral4 = 0x8b3e2f,
|
||||||
|
Tomato1 = 0xff6347,
|
||||||
|
Tomato2 = 0xee5c42,
|
||||||
|
Tomato3 = 0xcd4f39,
|
||||||
|
Tomato4 = 0x8b3626,
|
||||||
|
OrangeRed1 = 0xff4500,
|
||||||
|
OrangeRed2 = 0xee4000,
|
||||||
|
OrangeRed3 = 0xcd3700,
|
||||||
|
OrangeRed4 = 0x8b2500,
|
||||||
|
Red1 = 0xff0000,
|
||||||
|
Red2 = 0xee0000,
|
||||||
|
Red3 = 0xcd0000,
|
||||||
|
Red4 = 0x8b0000,
|
||||||
|
DeepPink1 = 0xff1493,
|
||||||
|
DeepPink2 = 0xee1289,
|
||||||
|
DeepPink3 = 0xcd1076,
|
||||||
|
DeepPink4 = 0x8b0a50,
|
||||||
|
HotPink1 = 0xff6eb4,
|
||||||
|
HotPink2 = 0xee6aa7,
|
||||||
|
HotPink3 = 0xcd6090,
|
||||||
|
HotPink4 = 0x8b3a62,
|
||||||
|
Pink1 = 0xffb5c5,
|
||||||
|
Pink2 = 0xeea9b8,
|
||||||
|
Pink3 = 0xcd919e,
|
||||||
|
Pink4 = 0x8b636c,
|
||||||
|
LightPink1 = 0xffaeb9,
|
||||||
|
LightPink2 = 0xeea2ad,
|
||||||
|
LightPink3 = 0xcd8c95,
|
||||||
|
LightPink4 = 0x8b5f65,
|
||||||
|
PaleVioletRed1 = 0xff82ab,
|
||||||
|
PaleVioletRed2 = 0xee799f,
|
||||||
|
PaleVioletRed3 = 0xcd6889,
|
||||||
|
PaleVioletRed4 = 0x8b475d,
|
||||||
|
Maroon1 = 0xff34b3,
|
||||||
|
Maroon2 = 0xee30a7,
|
||||||
|
Maroon3 = 0xcd2990,
|
||||||
|
Maroon4 = 0x8b1c62,
|
||||||
|
VioletRed1 = 0xff3e96,
|
||||||
|
VioletRed2 = 0xee3a8c,
|
||||||
|
VioletRed3 = 0xcd3278,
|
||||||
|
VioletRed4 = 0x8b2252,
|
||||||
|
Magenta1 = 0xff00ff,
|
||||||
|
Magenta2 = 0xee00ee,
|
||||||
|
Magenta3 = 0xcd00cd,
|
||||||
|
Magenta4 = 0x8b008b,
|
||||||
|
Orchid1 = 0xff83fa,
|
||||||
|
Orchid2 = 0xee7ae9,
|
||||||
|
Orchid3 = 0xcd69c9,
|
||||||
|
Orchid4 = 0x8b4789,
|
||||||
|
Plum1 = 0xffbbff,
|
||||||
|
Plum2 = 0xeeaeee,
|
||||||
|
Plum3 = 0xcd96cd,
|
||||||
|
Plum4 = 0x8b668b,
|
||||||
|
MediumOrchid1 = 0xe066ff,
|
||||||
|
MediumOrchid2 = 0xd15fee,
|
||||||
|
MediumOrchid3 = 0xb452cd,
|
||||||
|
MediumOrchid4 = 0x7a378b,
|
||||||
|
DarkOrchid1 = 0xbf3eff,
|
||||||
|
DarkOrchid2 = 0xb23aee,
|
||||||
|
DarkOrchid3 = 0x9a32cd,
|
||||||
|
DarkOrchid4 = 0x68228b,
|
||||||
|
Purple1 = 0x9b30ff,
|
||||||
|
Purple2 = 0x912cee,
|
||||||
|
Purple3 = 0x7d26cd,
|
||||||
|
Purple4 = 0x551a8b,
|
||||||
|
MediumPurple1 = 0xab82ff,
|
||||||
|
MediumPurple2 = 0x9f79ee,
|
||||||
|
MediumPurple3 = 0x8968cd,
|
||||||
|
MediumPurple4 = 0x5d478b,
|
||||||
|
Thistle1 = 0xffe1ff,
|
||||||
|
Thistle2 = 0xeed2ee,
|
||||||
|
Thistle3 = 0xcdb5cd,
|
||||||
|
Thistle4 = 0x8b7b8b,
|
||||||
|
Gray0 = 0x000000,
|
||||||
|
Grey0 = 0x000000,
|
||||||
|
Gray1 = 0x030303,
|
||||||
|
Grey1 = 0x030303,
|
||||||
|
Gray2 = 0x050505,
|
||||||
|
Grey2 = 0x050505,
|
||||||
|
Gray3 = 0x080808,
|
||||||
|
Grey3 = 0x080808,
|
||||||
|
Gray4 = 0x0a0a0a,
|
||||||
|
Grey4 = 0x0a0a0a,
|
||||||
|
Gray5 = 0x0d0d0d,
|
||||||
|
Grey5 = 0x0d0d0d,
|
||||||
|
Gray6 = 0x0f0f0f,
|
||||||
|
Grey6 = 0x0f0f0f,
|
||||||
|
Gray7 = 0x121212,
|
||||||
|
Grey7 = 0x121212,
|
||||||
|
Gray8 = 0x141414,
|
||||||
|
Grey8 = 0x141414,
|
||||||
|
Gray9 = 0x171717,
|
||||||
|
Grey9 = 0x171717,
|
||||||
|
Gray10 = 0x1a1a1a,
|
||||||
|
Grey10 = 0x1a1a1a,
|
||||||
|
Gray11 = 0x1c1c1c,
|
||||||
|
Grey11 = 0x1c1c1c,
|
||||||
|
Gray12 = 0x1f1f1f,
|
||||||
|
Grey12 = 0x1f1f1f,
|
||||||
|
Gray13 = 0x212121,
|
||||||
|
Grey13 = 0x212121,
|
||||||
|
Gray14 = 0x242424,
|
||||||
|
Grey14 = 0x242424,
|
||||||
|
Gray15 = 0x262626,
|
||||||
|
Grey15 = 0x262626,
|
||||||
|
Gray16 = 0x292929,
|
||||||
|
Grey16 = 0x292929,
|
||||||
|
Gray17 = 0x2b2b2b,
|
||||||
|
Grey17 = 0x2b2b2b,
|
||||||
|
Gray18 = 0x2e2e2e,
|
||||||
|
Grey18 = 0x2e2e2e,
|
||||||
|
Gray19 = 0x303030,
|
||||||
|
Grey19 = 0x303030,
|
||||||
|
Gray20 = 0x333333,
|
||||||
|
Grey20 = 0x333333,
|
||||||
|
Gray21 = 0x363636,
|
||||||
|
Grey21 = 0x363636,
|
||||||
|
Gray22 = 0x383838,
|
||||||
|
Grey22 = 0x383838,
|
||||||
|
Gray23 = 0x3b3b3b,
|
||||||
|
Grey23 = 0x3b3b3b,
|
||||||
|
Gray24 = 0x3d3d3d,
|
||||||
|
Grey24 = 0x3d3d3d,
|
||||||
|
Gray25 = 0x404040,
|
||||||
|
Grey25 = 0x404040,
|
||||||
|
Gray26 = 0x424242,
|
||||||
|
Grey26 = 0x424242,
|
||||||
|
Gray27 = 0x454545,
|
||||||
|
Grey27 = 0x454545,
|
||||||
|
Gray28 = 0x474747,
|
||||||
|
Grey28 = 0x474747,
|
||||||
|
Gray29 = 0x4a4a4a,
|
||||||
|
Grey29 = 0x4a4a4a,
|
||||||
|
Gray30 = 0x4d4d4d,
|
||||||
|
Grey30 = 0x4d4d4d,
|
||||||
|
Gray31 = 0x4f4f4f,
|
||||||
|
Grey31 = 0x4f4f4f,
|
||||||
|
Gray32 = 0x525252,
|
||||||
|
Grey32 = 0x525252,
|
||||||
|
Gray33 = 0x545454,
|
||||||
|
Grey33 = 0x545454,
|
||||||
|
Gray34 = 0x575757,
|
||||||
|
Grey34 = 0x575757,
|
||||||
|
Gray35 = 0x595959,
|
||||||
|
Grey35 = 0x595959,
|
||||||
|
Gray36 = 0x5c5c5c,
|
||||||
|
Grey36 = 0x5c5c5c,
|
||||||
|
Gray37 = 0x5e5e5e,
|
||||||
|
Grey37 = 0x5e5e5e,
|
||||||
|
Gray38 = 0x616161,
|
||||||
|
Grey38 = 0x616161,
|
||||||
|
Gray39 = 0x636363,
|
||||||
|
Grey39 = 0x636363,
|
||||||
|
Gray40 = 0x666666,
|
||||||
|
Grey40 = 0x666666,
|
||||||
|
Gray41 = 0x696969,
|
||||||
|
Grey41 = 0x696969,
|
||||||
|
Gray42 = 0x6b6b6b,
|
||||||
|
Grey42 = 0x6b6b6b,
|
||||||
|
Gray43 = 0x6e6e6e,
|
||||||
|
Grey43 = 0x6e6e6e,
|
||||||
|
Gray44 = 0x707070,
|
||||||
|
Grey44 = 0x707070,
|
||||||
|
Gray45 = 0x737373,
|
||||||
|
Grey45 = 0x737373,
|
||||||
|
Gray46 = 0x757575,
|
||||||
|
Grey46 = 0x757575,
|
||||||
|
Gray47 = 0x787878,
|
||||||
|
Grey47 = 0x787878,
|
||||||
|
Gray48 = 0x7a7a7a,
|
||||||
|
Grey48 = 0x7a7a7a,
|
||||||
|
Gray49 = 0x7d7d7d,
|
||||||
|
Grey49 = 0x7d7d7d,
|
||||||
|
Gray50 = 0x7f7f7f,
|
||||||
|
Grey50 = 0x7f7f7f,
|
||||||
|
Gray51 = 0x828282,
|
||||||
|
Grey51 = 0x828282,
|
||||||
|
Gray52 = 0x858585,
|
||||||
|
Grey52 = 0x858585,
|
||||||
|
Gray53 = 0x878787,
|
||||||
|
Grey53 = 0x878787,
|
||||||
|
Gray54 = 0x8a8a8a,
|
||||||
|
Grey54 = 0x8a8a8a,
|
||||||
|
Gray55 = 0x8c8c8c,
|
||||||
|
Grey55 = 0x8c8c8c,
|
||||||
|
Gray56 = 0x8f8f8f,
|
||||||
|
Grey56 = 0x8f8f8f,
|
||||||
|
Gray57 = 0x919191,
|
||||||
|
Grey57 = 0x919191,
|
||||||
|
Gray58 = 0x949494,
|
||||||
|
Grey58 = 0x949494,
|
||||||
|
Gray59 = 0x969696,
|
||||||
|
Grey59 = 0x969696,
|
||||||
|
Gray60 = 0x999999,
|
||||||
|
Grey60 = 0x999999,
|
||||||
|
Gray61 = 0x9c9c9c,
|
||||||
|
Grey61 = 0x9c9c9c,
|
||||||
|
Gray62 = 0x9e9e9e,
|
||||||
|
Grey62 = 0x9e9e9e,
|
||||||
|
Gray63 = 0xa1a1a1,
|
||||||
|
Grey63 = 0xa1a1a1,
|
||||||
|
Gray64 = 0xa3a3a3,
|
||||||
|
Grey64 = 0xa3a3a3,
|
||||||
|
Gray65 = 0xa6a6a6,
|
||||||
|
Grey65 = 0xa6a6a6,
|
||||||
|
Gray66 = 0xa8a8a8,
|
||||||
|
Grey66 = 0xa8a8a8,
|
||||||
|
Gray67 = 0xababab,
|
||||||
|
Grey67 = 0xababab,
|
||||||
|
Gray68 = 0xadadad,
|
||||||
|
Grey68 = 0xadadad,
|
||||||
|
Gray69 = 0xb0b0b0,
|
||||||
|
Grey69 = 0xb0b0b0,
|
||||||
|
Gray70 = 0xb3b3b3,
|
||||||
|
Grey70 = 0xb3b3b3,
|
||||||
|
Gray71 = 0xb5b5b5,
|
||||||
|
Grey71 = 0xb5b5b5,
|
||||||
|
Gray72 = 0xb8b8b8,
|
||||||
|
Grey72 = 0xb8b8b8,
|
||||||
|
Gray73 = 0xbababa,
|
||||||
|
Grey73 = 0xbababa,
|
||||||
|
Gray74 = 0xbdbdbd,
|
||||||
|
Grey74 = 0xbdbdbd,
|
||||||
|
Gray75 = 0xbfbfbf,
|
||||||
|
Grey75 = 0xbfbfbf,
|
||||||
|
Gray76 = 0xc2c2c2,
|
||||||
|
Grey76 = 0xc2c2c2,
|
||||||
|
Gray77 = 0xc4c4c4,
|
||||||
|
Grey77 = 0xc4c4c4,
|
||||||
|
Gray78 = 0xc7c7c7,
|
||||||
|
Grey78 = 0xc7c7c7,
|
||||||
|
Gray79 = 0xc9c9c9,
|
||||||
|
Grey79 = 0xc9c9c9,
|
||||||
|
Gray80 = 0xcccccc,
|
||||||
|
Grey80 = 0xcccccc,
|
||||||
|
Gray81 = 0xcfcfcf,
|
||||||
|
Grey81 = 0xcfcfcf,
|
||||||
|
Gray82 = 0xd1d1d1,
|
||||||
|
Grey82 = 0xd1d1d1,
|
||||||
|
Gray83 = 0xd4d4d4,
|
||||||
|
Grey83 = 0xd4d4d4,
|
||||||
|
Gray84 = 0xd6d6d6,
|
||||||
|
Grey84 = 0xd6d6d6,
|
||||||
|
Gray85 = 0xd9d9d9,
|
||||||
|
Grey85 = 0xd9d9d9,
|
||||||
|
Gray86 = 0xdbdbdb,
|
||||||
|
Grey86 = 0xdbdbdb,
|
||||||
|
Gray87 = 0xdedede,
|
||||||
|
Grey87 = 0xdedede,
|
||||||
|
Gray88 = 0xe0e0e0,
|
||||||
|
Grey88 = 0xe0e0e0,
|
||||||
|
Gray89 = 0xe3e3e3,
|
||||||
|
Grey89 = 0xe3e3e3,
|
||||||
|
Gray90 = 0xe5e5e5,
|
||||||
|
Grey90 = 0xe5e5e5,
|
||||||
|
Gray91 = 0xe8e8e8,
|
||||||
|
Grey91 = 0xe8e8e8,
|
||||||
|
Gray92 = 0xebebeb,
|
||||||
|
Grey92 = 0xebebeb,
|
||||||
|
Gray93 = 0xededed,
|
||||||
|
Grey93 = 0xededed,
|
||||||
|
Gray94 = 0xf0f0f0,
|
||||||
|
Grey94 = 0xf0f0f0,
|
||||||
|
Gray95 = 0xf2f2f2,
|
||||||
|
Grey95 = 0xf2f2f2,
|
||||||
|
Gray96 = 0xf5f5f5,
|
||||||
|
Grey96 = 0xf5f5f5,
|
||||||
|
Gray97 = 0xf7f7f7,
|
||||||
|
Grey97 = 0xf7f7f7,
|
||||||
|
Gray98 = 0xfafafa,
|
||||||
|
Grey98 = 0xfafafa,
|
||||||
|
Gray99 = 0xfcfcfc,
|
||||||
|
Grey99 = 0xfcfcfc,
|
||||||
|
Gray100 = 0xffffff,
|
||||||
|
Grey100 = 0xffffff,
|
||||||
|
DarkGrey = 0xa9a9a9,
|
||||||
|
DarkGray = 0xa9a9a9,
|
||||||
|
DarkBlue = 0x00008b,
|
||||||
|
DarkCyan = 0x008b8b,
|
||||||
|
DarkMagenta = 0x8b008b,
|
||||||
|
DarkRed = 0x8b0000,
|
||||||
|
LightGreen = 0x90ee90,
|
||||||
|
Crimson = 0xdc143c,
|
||||||
|
Indigo = 0x4b0082,
|
||||||
|
Olive = 0x808000,
|
||||||
|
RebeccaPurple = 0x663399,
|
||||||
|
Silver = 0xc0c0c0,
|
||||||
|
Teal = 0x008080,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
20
externals/tracy/public/common/TracyForceInline.hpp
vendored
Normal file
20
externals/tracy/public/common/TracyForceInline.hpp
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef __TRACYFORCEINLINE_HPP__
|
||||||
|
#define __TRACYFORCEINLINE_HPP__
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
# define tracy_force_inline __attribute__((always_inline)) inline
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
# define tracy_force_inline __forceinline
|
||||||
|
#else
|
||||||
|
# define tracy_force_inline inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
# define tracy_no_inline __attribute__((noinline))
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
# define tracy_no_inline __declspec(noinline)
|
||||||
|
#else
|
||||||
|
# define tracy_no_inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
24
externals/tracy/public/common/TracyMutex.hpp
vendored
Normal file
24
externals/tracy/public/common/TracyMutex.hpp
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef __TRACYMUTEX_HPP__
|
||||||
|
#define __TRACYMUTEX_HPP__
|
||||||
|
|
||||||
|
#if defined _MSC_VER
|
||||||
|
|
||||||
|
# include <shared_mutex>
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
using TracyMutex = std::shared_mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
using TracyMutex = std::mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
169
externals/tracy/public/common/TracyProtocol.hpp
vendored
Normal file
169
externals/tracy/public/common/TracyProtocol.hpp
vendored
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
#ifndef __TRACYPROTOCOL_HPP__
|
||||||
|
#define __TRACYPROTOCOL_HPP__
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr unsigned Lz4CompressBound( unsigned isize ) { return isize + ( isize / 255 ) + 16; }
|
||||||
|
|
||||||
|
enum : uint32_t { ProtocolVersion = 65 };
|
||||||
|
enum : uint16_t { BroadcastVersion = 3 };
|
||||||
|
|
||||||
|
using lz4sz_t = uint32_t;
|
||||||
|
|
||||||
|
enum { TargetFrameSize = 256 * 1024 };
|
||||||
|
enum { LZ4Size = Lz4CompressBound( TargetFrameSize ) };
|
||||||
|
static_assert( LZ4Size <= (std::numeric_limits<lz4sz_t>::max)(), "LZ4Size greater than lz4sz_t" );
|
||||||
|
static_assert( TargetFrameSize * 2 >= 64 * 1024, "Not enough space for LZ4 stream buffer" );
|
||||||
|
|
||||||
|
enum { HandshakeShibbolethSize = 8 };
|
||||||
|
static const char HandshakeShibboleth[HandshakeShibbolethSize] = { 'T', 'r', 'a', 'c', 'y', 'P', 'r', 'f' };
|
||||||
|
|
||||||
|
enum HandshakeStatus : uint8_t
|
||||||
|
{
|
||||||
|
HandshakePending,
|
||||||
|
HandshakeWelcome,
|
||||||
|
HandshakeProtocolMismatch,
|
||||||
|
HandshakeNotAvailable,
|
||||||
|
HandshakeDropped
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { WelcomeMessageProgramNameSize = 64 };
|
||||||
|
enum { WelcomeMessageHostInfoSize = 1024 };
|
||||||
|
|
||||||
|
#pragma pack( push, 1 )
|
||||||
|
|
||||||
|
// Must increase left query space after handling!
|
||||||
|
enum ServerQuery : uint8_t
|
||||||
|
{
|
||||||
|
ServerQueryTerminate,
|
||||||
|
ServerQueryString,
|
||||||
|
ServerQueryThreadString,
|
||||||
|
ServerQuerySourceLocation,
|
||||||
|
ServerQueryPlotName,
|
||||||
|
ServerQueryFrameName,
|
||||||
|
ServerQueryParameter,
|
||||||
|
ServerQueryFiberName,
|
||||||
|
// Items above are high priority. Split order must be preserved. See IsQueryPrio().
|
||||||
|
ServerQueryDisconnect,
|
||||||
|
ServerQueryCallstackFrame,
|
||||||
|
ServerQueryExternalName,
|
||||||
|
ServerQuerySymbol,
|
||||||
|
ServerQuerySymbolCode,
|
||||||
|
ServerQuerySourceCode,
|
||||||
|
ServerQueryDataTransfer,
|
||||||
|
ServerQueryDataTransferPart
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ServerQueryPacket
|
||||||
|
{
|
||||||
|
ServerQuery type;
|
||||||
|
uint64_t ptr;
|
||||||
|
uint32_t extra;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { ServerQueryPacketSize = sizeof( ServerQueryPacket ) };
|
||||||
|
|
||||||
|
|
||||||
|
enum CpuArchitecture : uint8_t
|
||||||
|
{
|
||||||
|
CpuArchUnknown,
|
||||||
|
CpuArchX86,
|
||||||
|
CpuArchX64,
|
||||||
|
CpuArchArm32,
|
||||||
|
CpuArchArm64
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct WelcomeFlag
|
||||||
|
{
|
||||||
|
enum _t : uint8_t
|
||||||
|
{
|
||||||
|
OnDemand = 1 << 0,
|
||||||
|
IsApple = 1 << 1,
|
||||||
|
CodeTransfer = 1 << 2,
|
||||||
|
CombineSamples = 1 << 3,
|
||||||
|
IdentifySamples = 1 << 4,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WelcomeMessage
|
||||||
|
{
|
||||||
|
double timerMul;
|
||||||
|
int64_t initBegin;
|
||||||
|
int64_t initEnd;
|
||||||
|
uint64_t delay;
|
||||||
|
uint64_t resolution;
|
||||||
|
uint64_t epoch;
|
||||||
|
uint64_t exectime;
|
||||||
|
uint64_t pid;
|
||||||
|
int64_t samplingPeriod;
|
||||||
|
uint8_t flags;
|
||||||
|
uint8_t cpuArch;
|
||||||
|
char cpuManufacturer[12];
|
||||||
|
uint32_t cpuId;
|
||||||
|
char programName[WelcomeMessageProgramNameSize];
|
||||||
|
char hostInfo[WelcomeMessageHostInfoSize];
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { WelcomeMessageSize = sizeof( WelcomeMessage ) };
|
||||||
|
|
||||||
|
|
||||||
|
struct OnDemandPayloadMessage
|
||||||
|
{
|
||||||
|
uint64_t frames;
|
||||||
|
uint64_t currentTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { OnDemandPayloadMessageSize = sizeof( OnDemandPayloadMessage ) };
|
||||||
|
|
||||||
|
|
||||||
|
struct BroadcastMessage
|
||||||
|
{
|
||||||
|
uint16_t broadcastVersion;
|
||||||
|
uint16_t listenPort;
|
||||||
|
uint32_t protocolVersion;
|
||||||
|
uint64_t pid;
|
||||||
|
int32_t activeTime; // in seconds
|
||||||
|
char programName[WelcomeMessageProgramNameSize];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BroadcastMessage_v2
|
||||||
|
{
|
||||||
|
uint16_t broadcastVersion;
|
||||||
|
uint16_t listenPort;
|
||||||
|
uint32_t protocolVersion;
|
||||||
|
int32_t activeTime;
|
||||||
|
char programName[WelcomeMessageProgramNameSize];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BroadcastMessage_v1
|
||||||
|
{
|
||||||
|
uint32_t broadcastVersion;
|
||||||
|
uint32_t protocolVersion;
|
||||||
|
uint32_t listenPort;
|
||||||
|
uint32_t activeTime;
|
||||||
|
char programName[WelcomeMessageProgramNameSize];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BroadcastMessage_v0
|
||||||
|
{
|
||||||
|
uint32_t broadcastVersion;
|
||||||
|
uint32_t protocolVersion;
|
||||||
|
uint32_t activeTime;
|
||||||
|
char programName[WelcomeMessageProgramNameSize];
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { BroadcastMessageSize = sizeof( BroadcastMessage ) };
|
||||||
|
enum { BroadcastMessageSize_v2 = sizeof( BroadcastMessage_v2 ) };
|
||||||
|
enum { BroadcastMessageSize_v1 = sizeof( BroadcastMessage_v1 ) };
|
||||||
|
enum { BroadcastMessageSize_v0 = sizeof( BroadcastMessage_v0 ) };
|
||||||
|
|
||||||
|
#pragma pack( pop )
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
894
externals/tracy/public/common/TracyQueue.hpp
vendored
Normal file
894
externals/tracy/public/common/TracyQueue.hpp
vendored
Normal file
@ -0,0 +1,894 @@
|
|||||||
|
#ifndef __TRACYQUEUE_HPP__
|
||||||
|
#define __TRACYQUEUE_HPP__
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
enum class QueueType : uint8_t
|
||||||
|
{
|
||||||
|
ZoneText,
|
||||||
|
ZoneName,
|
||||||
|
Message,
|
||||||
|
MessageColor,
|
||||||
|
MessageCallstack,
|
||||||
|
MessageColorCallstack,
|
||||||
|
MessageAppInfo,
|
||||||
|
ZoneBeginAllocSrcLoc,
|
||||||
|
ZoneBeginAllocSrcLocCallstack,
|
||||||
|
CallstackSerial,
|
||||||
|
Callstack,
|
||||||
|
CallstackAlloc,
|
||||||
|
CallstackSample,
|
||||||
|
CallstackSampleContextSwitch,
|
||||||
|
FrameImage,
|
||||||
|
ZoneBegin,
|
||||||
|
ZoneBeginCallstack,
|
||||||
|
ZoneEnd,
|
||||||
|
LockWait,
|
||||||
|
LockObtain,
|
||||||
|
LockRelease,
|
||||||
|
LockSharedWait,
|
||||||
|
LockSharedObtain,
|
||||||
|
LockSharedRelease,
|
||||||
|
LockName,
|
||||||
|
MemAlloc,
|
||||||
|
MemAllocNamed,
|
||||||
|
MemFree,
|
||||||
|
MemFreeNamed,
|
||||||
|
MemAllocCallstack,
|
||||||
|
MemAllocCallstackNamed,
|
||||||
|
MemFreeCallstack,
|
||||||
|
MemFreeCallstackNamed,
|
||||||
|
GpuZoneBegin,
|
||||||
|
GpuZoneBeginCallstack,
|
||||||
|
GpuZoneBeginAllocSrcLoc,
|
||||||
|
GpuZoneBeginAllocSrcLocCallstack,
|
||||||
|
GpuZoneEnd,
|
||||||
|
GpuZoneBeginSerial,
|
||||||
|
GpuZoneBeginCallstackSerial,
|
||||||
|
GpuZoneBeginAllocSrcLocSerial,
|
||||||
|
GpuZoneBeginAllocSrcLocCallstackSerial,
|
||||||
|
GpuZoneEndSerial,
|
||||||
|
PlotDataInt,
|
||||||
|
PlotDataFloat,
|
||||||
|
PlotDataDouble,
|
||||||
|
ContextSwitch,
|
||||||
|
ThreadWakeup,
|
||||||
|
GpuTime,
|
||||||
|
GpuContextName,
|
||||||
|
CallstackFrameSize,
|
||||||
|
SymbolInformation,
|
||||||
|
ExternalNameMetadata,
|
||||||
|
SymbolCodeMetadata,
|
||||||
|
SourceCodeMetadata,
|
||||||
|
FiberEnter,
|
||||||
|
FiberLeave,
|
||||||
|
Terminate,
|
||||||
|
KeepAlive,
|
||||||
|
ThreadContext,
|
||||||
|
GpuCalibration,
|
||||||
|
GpuTimeSync,
|
||||||
|
Crash,
|
||||||
|
CrashReport,
|
||||||
|
ZoneValidation,
|
||||||
|
ZoneColor,
|
||||||
|
ZoneValue,
|
||||||
|
FrameMarkMsg,
|
||||||
|
FrameMarkMsgStart,
|
||||||
|
FrameMarkMsgEnd,
|
||||||
|
FrameVsync,
|
||||||
|
SourceLocation,
|
||||||
|
LockAnnounce,
|
||||||
|
LockTerminate,
|
||||||
|
LockMark,
|
||||||
|
MessageLiteral,
|
||||||
|
MessageLiteralColor,
|
||||||
|
MessageLiteralCallstack,
|
||||||
|
MessageLiteralColorCallstack,
|
||||||
|
GpuNewContext,
|
||||||
|
CallstackFrame,
|
||||||
|
SysTimeReport,
|
||||||
|
SysPowerReport,
|
||||||
|
TidToPid,
|
||||||
|
HwSampleCpuCycle,
|
||||||
|
HwSampleInstructionRetired,
|
||||||
|
HwSampleCacheReference,
|
||||||
|
HwSampleCacheMiss,
|
||||||
|
HwSampleBranchRetired,
|
||||||
|
HwSampleBranchMiss,
|
||||||
|
PlotConfig,
|
||||||
|
ParamSetup,
|
||||||
|
AckServerQueryNoop,
|
||||||
|
AckSourceCodeNotAvailable,
|
||||||
|
AckSymbolCodeNotAvailable,
|
||||||
|
CpuTopology,
|
||||||
|
SingleStringData,
|
||||||
|
SecondStringData,
|
||||||
|
MemNamePayload,
|
||||||
|
StringData,
|
||||||
|
ThreadName,
|
||||||
|
PlotName,
|
||||||
|
SourceLocationPayload,
|
||||||
|
CallstackPayload,
|
||||||
|
CallstackAllocPayload,
|
||||||
|
FrameName,
|
||||||
|
FrameImageData,
|
||||||
|
ExternalName,
|
||||||
|
ExternalThreadName,
|
||||||
|
SymbolCode,
|
||||||
|
SourceCode,
|
||||||
|
FiberName,
|
||||||
|
NUM_TYPES
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma pack( push, 1 )
|
||||||
|
|
||||||
|
struct QueueThreadContext
|
||||||
|
{
|
||||||
|
uint32_t thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueZoneBeginLean
|
||||||
|
{
|
||||||
|
int64_t time;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueZoneBegin : public QueueZoneBeginLean
|
||||||
|
{
|
||||||
|
uint64_t srcloc; // ptr
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueZoneBeginThread : public QueueZoneBegin
|
||||||
|
{
|
||||||
|
uint32_t thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueZoneEnd
|
||||||
|
{
|
||||||
|
int64_t time;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueZoneEndThread : public QueueZoneEnd
|
||||||
|
{
|
||||||
|
uint32_t thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueZoneValidation
|
||||||
|
{
|
||||||
|
uint32_t id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueZoneValidationThread : public QueueZoneValidation
|
||||||
|
{
|
||||||
|
uint32_t thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueZoneColor
|
||||||
|
{
|
||||||
|
uint8_t b;
|
||||||
|
uint8_t g;
|
||||||
|
uint8_t r;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueZoneColorThread : public QueueZoneColor
|
||||||
|
{
|
||||||
|
uint32_t thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueZoneValue
|
||||||
|
{
|
||||||
|
uint64_t value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueZoneValueThread : public QueueZoneValue
|
||||||
|
{
|
||||||
|
uint32_t thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueStringTransfer
|
||||||
|
{
|
||||||
|
uint64_t ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueFrameMark
|
||||||
|
{
|
||||||
|
int64_t time;
|
||||||
|
uint64_t name; // ptr
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueFrameVsync
|
||||||
|
{
|
||||||
|
int64_t time;
|
||||||
|
uint32_t id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueFrameImage
|
||||||
|
{
|
||||||
|
uint32_t frame;
|
||||||
|
uint16_t w;
|
||||||
|
uint16_t h;
|
||||||
|
uint8_t flip;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueFrameImageFat : public QueueFrameImage
|
||||||
|
{
|
||||||
|
uint64_t image; // ptr
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueSourceLocation
|
||||||
|
{
|
||||||
|
uint64_t name;
|
||||||
|
uint64_t function; // ptr
|
||||||
|
uint64_t file; // ptr
|
||||||
|
uint32_t line;
|
||||||
|
uint8_t b;
|
||||||
|
uint8_t g;
|
||||||
|
uint8_t r;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueZoneTextFat
|
||||||
|
{
|
||||||
|
uint64_t text; // ptr
|
||||||
|
uint16_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueZoneTextFatThread : public QueueZoneTextFat
|
||||||
|
{
|
||||||
|
uint32_t thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class LockType : uint8_t
|
||||||
|
{
|
||||||
|
Lockable,
|
||||||
|
SharedLockable
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueLockAnnounce
|
||||||
|
{
|
||||||
|
uint32_t id;
|
||||||
|
int64_t time;
|
||||||
|
uint64_t lckloc; // ptr
|
||||||
|
LockType type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueFiberEnter
|
||||||
|
{
|
||||||
|
int64_t time;
|
||||||
|
uint64_t fiber; // ptr
|
||||||
|
uint32_t thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueFiberLeave
|
||||||
|
{
|
||||||
|
int64_t time;
|
||||||
|
uint32_t thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueLockTerminate
|
||||||
|
{
|
||||||
|
uint32_t id;
|
||||||
|
int64_t time;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueLockWait
|
||||||
|
{
|
||||||
|
uint32_t thread;
|
||||||
|
uint32_t id;
|
||||||
|
int64_t time;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueLockObtain
|
||||||
|
{
|
||||||
|
uint32_t thread;
|
||||||
|
uint32_t id;
|
||||||
|
int64_t time;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueLockRelease
|
||||||
|
{
|
||||||
|
uint32_t id;
|
||||||
|
int64_t time;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueLockReleaseShared : public QueueLockRelease
|
||||||
|
{
|
||||||
|
uint32_t thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueLockMark
|
||||||
|
{
|
||||||
|
uint32_t thread;
|
||||||
|
uint32_t id;
|
||||||
|
uint64_t srcloc; // ptr
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueLockName
|
||||||
|
{
|
||||||
|
uint32_t id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueLockNameFat : public QueueLockName
|
||||||
|
{
|
||||||
|
uint64_t name; // ptr
|
||||||
|
uint16_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueuePlotDataBase
|
||||||
|
{
|
||||||
|
uint64_t name; // ptr
|
||||||
|
int64_t time;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueuePlotDataInt : public QueuePlotDataBase
|
||||||
|
{
|
||||||
|
int64_t val;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueuePlotDataFloat : public QueuePlotDataBase
|
||||||
|
{
|
||||||
|
float val;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueuePlotDataDouble : public QueuePlotDataBase
|
||||||
|
{
|
||||||
|
double val;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueMessage
|
||||||
|
{
|
||||||
|
int64_t time;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueMessageColor : public QueueMessage
|
||||||
|
{
|
||||||
|
uint8_t b;
|
||||||
|
uint8_t g;
|
||||||
|
uint8_t r;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueMessageLiteral : public QueueMessage
|
||||||
|
{
|
||||||
|
uint64_t text; // ptr
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueMessageLiteralThread : public QueueMessageLiteral
|
||||||
|
{
|
||||||
|
uint32_t thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueMessageColorLiteral : public QueueMessageColor
|
||||||
|
{
|
||||||
|
uint64_t text; // ptr
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueMessageColorLiteralThread : public QueueMessageColorLiteral
|
||||||
|
{
|
||||||
|
uint32_t thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueMessageFat : public QueueMessage
|
||||||
|
{
|
||||||
|
uint64_t text; // ptr
|
||||||
|
uint16_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueMessageFatThread : public QueueMessageFat
|
||||||
|
{
|
||||||
|
uint32_t thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueMessageColorFat : public QueueMessageColor
|
||||||
|
{
|
||||||
|
uint64_t text; // ptr
|
||||||
|
uint16_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueMessageColorFatThread : public QueueMessageColorFat
|
||||||
|
{
|
||||||
|
uint32_t thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Don't change order, only add new entries at the end, this is also used on trace dumps!
|
||||||
|
enum class GpuContextType : uint8_t
|
||||||
|
{
|
||||||
|
Invalid,
|
||||||
|
OpenGl,
|
||||||
|
Vulkan,
|
||||||
|
OpenCL,
|
||||||
|
Direct3D12,
|
||||||
|
Direct3D11
|
||||||
|
};
|
||||||
|
|
||||||
|
enum GpuContextFlags : uint8_t
|
||||||
|
{
|
||||||
|
GpuContextCalibration = 1 << 0
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueGpuNewContext
|
||||||
|
{
|
||||||
|
int64_t cpuTime;
|
||||||
|
int64_t gpuTime;
|
||||||
|
uint32_t thread;
|
||||||
|
float period;
|
||||||
|
uint8_t context;
|
||||||
|
GpuContextFlags flags;
|
||||||
|
GpuContextType type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueGpuZoneBeginLean
|
||||||
|
{
|
||||||
|
int64_t cpuTime;
|
||||||
|
uint32_t thread;
|
||||||
|
uint16_t queryId;
|
||||||
|
uint8_t context;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueGpuZoneBegin : public QueueGpuZoneBeginLean
|
||||||
|
{
|
||||||
|
uint64_t srcloc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueGpuZoneEnd
|
||||||
|
{
|
||||||
|
int64_t cpuTime;
|
||||||
|
uint32_t thread;
|
||||||
|
uint16_t queryId;
|
||||||
|
uint8_t context;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueGpuTime
|
||||||
|
{
|
||||||
|
int64_t gpuTime;
|
||||||
|
uint16_t queryId;
|
||||||
|
uint8_t context;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueGpuCalibration
|
||||||
|
{
|
||||||
|
int64_t gpuTime;
|
||||||
|
int64_t cpuTime;
|
||||||
|
int64_t cpuDelta;
|
||||||
|
uint8_t context;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueGpuTimeSync
|
||||||
|
{
|
||||||
|
int64_t gpuTime;
|
||||||
|
int64_t cpuTime;
|
||||||
|
uint8_t context;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueGpuContextName
|
||||||
|
{
|
||||||
|
uint8_t context;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueGpuContextNameFat : public QueueGpuContextName
|
||||||
|
{
|
||||||
|
uint64_t ptr;
|
||||||
|
uint16_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueMemNamePayload
|
||||||
|
{
|
||||||
|
uint64_t name;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueMemAlloc
|
||||||
|
{
|
||||||
|
int64_t time;
|
||||||
|
uint32_t thread;
|
||||||
|
uint64_t ptr;
|
||||||
|
char size[6];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueMemFree
|
||||||
|
{
|
||||||
|
int64_t time;
|
||||||
|
uint32_t thread;
|
||||||
|
uint64_t ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueCallstackFat
|
||||||
|
{
|
||||||
|
uint64_t ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueCallstackFatThread : public QueueCallstackFat
|
||||||
|
{
|
||||||
|
uint32_t thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueCallstackAllocFat
|
||||||
|
{
|
||||||
|
uint64_t ptr;
|
||||||
|
uint64_t nativePtr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueCallstackAllocFatThread : public QueueCallstackAllocFat
|
||||||
|
{
|
||||||
|
uint32_t thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueCallstackSample
|
||||||
|
{
|
||||||
|
int64_t time;
|
||||||
|
uint32_t thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueCallstackSampleFat : public QueueCallstackSample
|
||||||
|
{
|
||||||
|
uint64_t ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueCallstackFrameSize
|
||||||
|
{
|
||||||
|
uint64_t ptr;
|
||||||
|
uint8_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueCallstackFrameSizeFat : public QueueCallstackFrameSize
|
||||||
|
{
|
||||||
|
uint64_t data;
|
||||||
|
uint64_t imageName;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueCallstackFrame
|
||||||
|
{
|
||||||
|
uint32_t line;
|
||||||
|
uint64_t symAddr;
|
||||||
|
uint32_t symLen;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueSymbolInformation
|
||||||
|
{
|
||||||
|
uint32_t line;
|
||||||
|
uint64_t symAddr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueSymbolInformationFat : public QueueSymbolInformation
|
||||||
|
{
|
||||||
|
uint64_t fileString;
|
||||||
|
uint8_t needFree;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueCrashReport
|
||||||
|
{
|
||||||
|
int64_t time;
|
||||||
|
uint64_t text; // ptr
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueCrashReportThread
|
||||||
|
{
|
||||||
|
uint32_t thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueSysTime
|
||||||
|
{
|
||||||
|
int64_t time;
|
||||||
|
float sysTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueSysPower
|
||||||
|
{
|
||||||
|
int64_t time;
|
||||||
|
uint64_t delta;
|
||||||
|
uint64_t name; // ptr
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueContextSwitch
|
||||||
|
{
|
||||||
|
int64_t time;
|
||||||
|
uint32_t oldThread;
|
||||||
|
uint32_t newThread;
|
||||||
|
uint8_t cpu;
|
||||||
|
uint8_t reason;
|
||||||
|
uint8_t state;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueThreadWakeup
|
||||||
|
{
|
||||||
|
int64_t time;
|
||||||
|
uint32_t thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueTidToPid
|
||||||
|
{
|
||||||
|
uint64_t tid;
|
||||||
|
uint64_t pid;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueHwSample
|
||||||
|
{
|
||||||
|
uint64_t ip;
|
||||||
|
int64_t time;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class PlotFormatType : uint8_t
|
||||||
|
{
|
||||||
|
Number,
|
||||||
|
Memory,
|
||||||
|
Percentage
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueuePlotConfig
|
||||||
|
{
|
||||||
|
uint64_t name; // ptr
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t step;
|
||||||
|
uint8_t fill;
|
||||||
|
uint32_t color;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueParamSetup
|
||||||
|
{
|
||||||
|
uint32_t idx;
|
||||||
|
uint64_t name; // ptr
|
||||||
|
uint8_t isBool;
|
||||||
|
int32_t val;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueSourceCodeNotAvailable
|
||||||
|
{
|
||||||
|
uint32_t id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueCpuTopology
|
||||||
|
{
|
||||||
|
uint32_t package;
|
||||||
|
uint32_t core;
|
||||||
|
uint32_t thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueExternalNameMetadata
|
||||||
|
{
|
||||||
|
uint64_t thread;
|
||||||
|
uint64_t name;
|
||||||
|
uint64_t threadName;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueSymbolCodeMetadata
|
||||||
|
{
|
||||||
|
uint64_t symbol;
|
||||||
|
uint64_t ptr;
|
||||||
|
uint32_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueSourceCodeMetadata
|
||||||
|
{
|
||||||
|
uint64_t ptr;
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueHeader
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
QueueType type;
|
||||||
|
uint8_t idx;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QueueItem
|
||||||
|
{
|
||||||
|
QueueHeader hdr;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
QueueThreadContext threadCtx;
|
||||||
|
QueueZoneBegin zoneBegin;
|
||||||
|
QueueZoneBeginLean zoneBeginLean;
|
||||||
|
QueueZoneBeginThread zoneBeginThread;
|
||||||
|
QueueZoneEnd zoneEnd;
|
||||||
|
QueueZoneEndThread zoneEndThread;
|
||||||
|
QueueZoneValidation zoneValidation;
|
||||||
|
QueueZoneValidationThread zoneValidationThread;
|
||||||
|
QueueZoneColor zoneColor;
|
||||||
|
QueueZoneColorThread zoneColorThread;
|
||||||
|
QueueZoneValue zoneValue;
|
||||||
|
QueueZoneValueThread zoneValueThread;
|
||||||
|
QueueStringTransfer stringTransfer;
|
||||||
|
QueueFrameMark frameMark;
|
||||||
|
QueueFrameVsync frameVsync;
|
||||||
|
QueueFrameImage frameImage;
|
||||||
|
QueueFrameImageFat frameImageFat;
|
||||||
|
QueueSourceLocation srcloc;
|
||||||
|
QueueZoneTextFat zoneTextFat;
|
||||||
|
QueueZoneTextFatThread zoneTextFatThread;
|
||||||
|
QueueLockAnnounce lockAnnounce;
|
||||||
|
QueueLockTerminate lockTerminate;
|
||||||
|
QueueLockWait lockWait;
|
||||||
|
QueueLockObtain lockObtain;
|
||||||
|
QueueLockRelease lockRelease;
|
||||||
|
QueueLockReleaseShared lockReleaseShared;
|
||||||
|
QueueLockMark lockMark;
|
||||||
|
QueueLockName lockName;
|
||||||
|
QueueLockNameFat lockNameFat;
|
||||||
|
QueuePlotDataInt plotDataInt;
|
||||||
|
QueuePlotDataFloat plotDataFloat;
|
||||||
|
QueuePlotDataDouble plotDataDouble;
|
||||||
|
QueueMessage message;
|
||||||
|
QueueMessageColor messageColor;
|
||||||
|
QueueMessageLiteral messageLiteral;
|
||||||
|
QueueMessageLiteralThread messageLiteralThread;
|
||||||
|
QueueMessageColorLiteral messageColorLiteral;
|
||||||
|
QueueMessageColorLiteralThread messageColorLiteralThread;
|
||||||
|
QueueMessageFat messageFat;
|
||||||
|
QueueMessageFatThread messageFatThread;
|
||||||
|
QueueMessageColorFat messageColorFat;
|
||||||
|
QueueMessageColorFatThread messageColorFatThread;
|
||||||
|
QueueGpuNewContext gpuNewContext;
|
||||||
|
QueueGpuZoneBegin gpuZoneBegin;
|
||||||
|
QueueGpuZoneBeginLean gpuZoneBeginLean;
|
||||||
|
QueueGpuZoneEnd gpuZoneEnd;
|
||||||
|
QueueGpuTime gpuTime;
|
||||||
|
QueueGpuCalibration gpuCalibration;
|
||||||
|
QueueGpuTimeSync gpuTimeSync;
|
||||||
|
QueueGpuContextName gpuContextName;
|
||||||
|
QueueGpuContextNameFat gpuContextNameFat;
|
||||||
|
QueueMemAlloc memAlloc;
|
||||||
|
QueueMemFree memFree;
|
||||||
|
QueueMemNamePayload memName;
|
||||||
|
QueueCallstackFat callstackFat;
|
||||||
|
QueueCallstackFatThread callstackFatThread;
|
||||||
|
QueueCallstackAllocFat callstackAllocFat;
|
||||||
|
QueueCallstackAllocFatThread callstackAllocFatThread;
|
||||||
|
QueueCallstackSample callstackSample;
|
||||||
|
QueueCallstackSampleFat callstackSampleFat;
|
||||||
|
QueueCallstackFrameSize callstackFrameSize;
|
||||||
|
QueueCallstackFrameSizeFat callstackFrameSizeFat;
|
||||||
|
QueueCallstackFrame callstackFrame;
|
||||||
|
QueueSymbolInformation symbolInformation;
|
||||||
|
QueueSymbolInformationFat symbolInformationFat;
|
||||||
|
QueueCrashReport crashReport;
|
||||||
|
QueueCrashReportThread crashReportThread;
|
||||||
|
QueueSysTime sysTime;
|
||||||
|
QueueSysPower sysPower;
|
||||||
|
QueueContextSwitch contextSwitch;
|
||||||
|
QueueThreadWakeup threadWakeup;
|
||||||
|
QueueTidToPid tidToPid;
|
||||||
|
QueueHwSample hwSample;
|
||||||
|
QueuePlotConfig plotConfig;
|
||||||
|
QueueParamSetup paramSetup;
|
||||||
|
QueueCpuTopology cpuTopology;
|
||||||
|
QueueExternalNameMetadata externalNameMetadata;
|
||||||
|
QueueSymbolCodeMetadata symbolCodeMetadata;
|
||||||
|
QueueSourceCodeMetadata sourceCodeMetadata;
|
||||||
|
QueueSourceCodeNotAvailable sourceCodeNotAvailable;
|
||||||
|
QueueFiberEnter fiberEnter;
|
||||||
|
QueueFiberLeave fiberLeave;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
#pragma pack( pop )
|
||||||
|
|
||||||
|
|
||||||
|
enum { QueueItemSize = sizeof( QueueItem ) };
|
||||||
|
|
||||||
|
static constexpr size_t QueueDataSize[] = {
|
||||||
|
sizeof( QueueHeader ), // zone text
|
||||||
|
sizeof( QueueHeader ), // zone name
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueMessage ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueMessageColor ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueMessage ), // callstack
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueMessageColor ), // callstack
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueMessage ), // app info
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueZoneBeginLean ), // allocated source location
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueZoneBeginLean ), // allocated source location, callstack
|
||||||
|
sizeof( QueueHeader ), // callstack memory
|
||||||
|
sizeof( QueueHeader ), // callstack
|
||||||
|
sizeof( QueueHeader ), // callstack alloc
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueCallstackSample ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueCallstackSample ), // context switch
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueFrameImage ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueZoneBegin ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueZoneBegin ), // callstack
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueZoneEnd ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueLockWait ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueLockObtain ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueLockRelease ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueLockWait ), // shared
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueLockObtain ), // shared
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueLockReleaseShared ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueLockName ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueMemAlloc ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueMemAlloc ), // named
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueMemFree ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueMemFree ), // named
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueMemAlloc ), // callstack
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueMemAlloc ), // callstack, named
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueMemFree ), // callstack
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueMemFree ), // callstack, named
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueGpuZoneBegin ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueGpuZoneBegin ), // callstack
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueGpuZoneBeginLean ),// allocated source location
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueGpuZoneBeginLean ),// allocated source location, callstack
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueGpuZoneEnd ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueGpuZoneBegin ), // serial
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueGpuZoneBegin ), // serial, callstack
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueGpuZoneBeginLean ),// serial, allocated source location
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueGpuZoneBeginLean ),// serial, allocated source location, callstack
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueGpuZoneEnd ), // serial
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueuePlotDataInt ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueuePlotDataFloat ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueuePlotDataDouble ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueContextSwitch ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueThreadWakeup ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueGpuTime ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueGpuContextName ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueCallstackFrameSize ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueSymbolInformation ),
|
||||||
|
sizeof( QueueHeader ), // ExternalNameMetadata - not for wire transfer
|
||||||
|
sizeof( QueueHeader ), // SymbolCodeMetadata - not for wire transfer
|
||||||
|
sizeof( QueueHeader ), // SourceCodeMetadata - not for wire transfer
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueFiberEnter ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueFiberLeave ),
|
||||||
|
// above items must be first
|
||||||
|
sizeof( QueueHeader ), // terminate
|
||||||
|
sizeof( QueueHeader ), // keep alive
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueThreadContext ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueGpuCalibration ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueGpuTimeSync ),
|
||||||
|
sizeof( QueueHeader ), // crash
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueCrashReport ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueZoneValidation ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueZoneColor ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueZoneValue ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueFrameMark ), // continuous frames
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueFrameMark ), // start
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueFrameMark ), // end
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueFrameVsync ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueSourceLocation ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueLockAnnounce ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueLockTerminate ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueLockMark ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueMessageLiteral ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueMessageColorLiteral ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueMessageLiteral ), // callstack
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueMessageColorLiteral ), // callstack
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueGpuNewContext ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueCallstackFrame ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueSysTime ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueSysPower ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueTidToPid ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueHwSample ), // cpu cycle
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueHwSample ), // instruction retired
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueHwSample ), // cache reference
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueHwSample ), // cache miss
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueHwSample ), // branch retired
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueHwSample ), // branch miss
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueuePlotConfig ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueParamSetup ),
|
||||||
|
sizeof( QueueHeader ), // server query acknowledgement
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueSourceCodeNotAvailable ),
|
||||||
|
sizeof( QueueHeader ), // symbol code not available
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueCpuTopology ),
|
||||||
|
sizeof( QueueHeader ), // single string data
|
||||||
|
sizeof( QueueHeader ), // second string data
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueMemNamePayload ),
|
||||||
|
// keep all QueueStringTransfer below
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // string data
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // thread name
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // plot name
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // allocated source location payload
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // callstack payload
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // callstack alloc payload
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // frame name
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // frame image data
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // external name
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // external thread name
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // symbol code
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // source code
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // fiber name
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert( QueueItemSize == 32, "Queue item size not 32 bytes" );
|
||||||
|
static_assert( sizeof( QueueDataSize ) / sizeof( size_t ) == (uint8_t)QueueType::NUM_TYPES, "QueueDataSize mismatch" );
|
||||||
|
static_assert( sizeof( void* ) <= sizeof( uint64_t ), "Pointer size > 8 bytes" );
|
||||||
|
static_assert( sizeof( void* ) == sizeof( uintptr_t ), "Pointer size != uintptr_t" );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
749
externals/tracy/public/common/TracySocket.cpp
vendored
Normal file
749
externals/tracy/public/common/TracySocket.cpp
vendored
Normal file
@ -0,0 +1,749 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <new>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "TracyAlloc.hpp"
|
||||||
|
#include "TracySocket.hpp"
|
||||||
|
#include "TracySystem.hpp"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# ifndef NOMINMAX
|
||||||
|
# define NOMINMAX
|
||||||
|
# endif
|
||||||
|
# include <winsock2.h>
|
||||||
|
# include <ws2tcpip.h>
|
||||||
|
# ifdef _MSC_VER
|
||||||
|
# pragma warning(disable:4244)
|
||||||
|
# pragma warning(disable:4267)
|
||||||
|
# endif
|
||||||
|
# define poll WSAPoll
|
||||||
|
#else
|
||||||
|
# include <arpa/inet.h>
|
||||||
|
# include <sys/socket.h>
|
||||||
|
# include <sys/param.h>
|
||||||
|
# include <errno.h>
|
||||||
|
# include <fcntl.h>
|
||||||
|
# include <netinet/in.h>
|
||||||
|
# include <netdb.h>
|
||||||
|
# include <unistd.h>
|
||||||
|
# include <poll.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MSG_NOSIGNAL
|
||||||
|
# define MSG_NOSIGNAL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
typedef SOCKET socket_t;
|
||||||
|
#else
|
||||||
|
typedef int socket_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
struct __wsinit
|
||||||
|
{
|
||||||
|
__wsinit()
|
||||||
|
{
|
||||||
|
WSADATA wsaData;
|
||||||
|
if( WSAStartup( MAKEWORD( 2, 2 ), &wsaData ) != 0 )
|
||||||
|
{
|
||||||
|
fprintf( stderr, "Cannot init winsock.\n" );
|
||||||
|
exit( 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void InitWinSock()
|
||||||
|
{
|
||||||
|
static __wsinit init;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
enum { BufSize = 128 * 1024 };
|
||||||
|
|
||||||
|
Socket::Socket()
|
||||||
|
: m_buf( (char*)tracy_malloc( BufSize ) )
|
||||||
|
, m_bufPtr( nullptr )
|
||||||
|
, m_sock( -1 )
|
||||||
|
, m_bufLeft( 0 )
|
||||||
|
, m_ptr( nullptr )
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
InitWinSock();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
Socket::Socket( int sock )
|
||||||
|
: m_buf( (char*)tracy_malloc( BufSize ) )
|
||||||
|
, m_bufPtr( nullptr )
|
||||||
|
, m_sock( sock )
|
||||||
|
, m_bufLeft( 0 )
|
||||||
|
, m_ptr( nullptr )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Socket::~Socket()
|
||||||
|
{
|
||||||
|
tracy_free( m_buf );
|
||||||
|
if( m_sock.load( std::memory_order_relaxed ) != -1 )
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
if( m_ptr )
|
||||||
|
{
|
||||||
|
freeaddrinfo( m_res );
|
||||||
|
#ifdef _WIN32
|
||||||
|
closesocket( m_connSock );
|
||||||
|
#else
|
||||||
|
close( m_connSock );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Socket::Connect( const char* addr, uint16_t port )
|
||||||
|
{
|
||||||
|
assert( !IsValid() );
|
||||||
|
|
||||||
|
if( m_ptr )
|
||||||
|
{
|
||||||
|
const auto c = connect( m_connSock, m_ptr->ai_addr, m_ptr->ai_addrlen );
|
||||||
|
if( c == -1 )
|
||||||
|
{
|
||||||
|
#if defined _WIN32
|
||||||
|
const auto err = WSAGetLastError();
|
||||||
|
if( err == WSAEALREADY || err == WSAEINPROGRESS ) return false;
|
||||||
|
if( err != WSAEISCONN )
|
||||||
|
{
|
||||||
|
freeaddrinfo( m_res );
|
||||||
|
closesocket( m_connSock );
|
||||||
|
m_ptr = nullptr;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
const auto err = errno;
|
||||||
|
if( err == EALREADY || err == EINPROGRESS ) return false;
|
||||||
|
if( err != EISCONN )
|
||||||
|
{
|
||||||
|
freeaddrinfo( m_res );
|
||||||
|
close( m_connSock );
|
||||||
|
m_ptr = nullptr;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined _WIN32
|
||||||
|
u_long nonblocking = 0;
|
||||||
|
ioctlsocket( m_connSock, FIONBIO, &nonblocking );
|
||||||
|
#else
|
||||||
|
int flags = fcntl( m_connSock, F_GETFL, 0 );
|
||||||
|
fcntl( m_connSock, F_SETFL, flags & ~O_NONBLOCK );
|
||||||
|
#endif
|
||||||
|
m_sock.store( m_connSock, std::memory_order_relaxed );
|
||||||
|
freeaddrinfo( m_res );
|
||||||
|
m_ptr = nullptr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct addrinfo hints;
|
||||||
|
struct addrinfo *res, *ptr;
|
||||||
|
|
||||||
|
memset( &hints, 0, sizeof( hints ) );
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
|
||||||
|
char portbuf[32];
|
||||||
|
sprintf( portbuf, "%" PRIu16, port );
|
||||||
|
|
||||||
|
if( getaddrinfo( addr, portbuf, &hints, &res ) != 0 ) return false;
|
||||||
|
int sock = 0;
|
||||||
|
for( ptr = res; ptr; ptr = ptr->ai_next )
|
||||||
|
{
|
||||||
|
if( ( sock = socket( ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol ) ) == -1 ) continue;
|
||||||
|
#if defined __APPLE__
|
||||||
|
int val = 1;
|
||||||
|
setsockopt( sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof( val ) );
|
||||||
|
#endif
|
||||||
|
#if defined _WIN32
|
||||||
|
u_long nonblocking = 1;
|
||||||
|
ioctlsocket( sock, FIONBIO, &nonblocking );
|
||||||
|
#else
|
||||||
|
int flags = fcntl( sock, F_GETFL, 0 );
|
||||||
|
fcntl( sock, F_SETFL, flags | O_NONBLOCK );
|
||||||
|
#endif
|
||||||
|
if( connect( sock, ptr->ai_addr, ptr->ai_addrlen ) == 0 )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if defined _WIN32
|
||||||
|
const auto err = WSAGetLastError();
|
||||||
|
if( err != WSAEWOULDBLOCK )
|
||||||
|
{
|
||||||
|
closesocket( sock );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if( errno != EINPROGRESS )
|
||||||
|
{
|
||||||
|
close( sock );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
m_res = res;
|
||||||
|
m_ptr = ptr;
|
||||||
|
m_connSock = sock;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
freeaddrinfo( res );
|
||||||
|
if( !ptr ) return false;
|
||||||
|
|
||||||
|
#if defined _WIN32
|
||||||
|
u_long nonblocking = 0;
|
||||||
|
ioctlsocket( sock, FIONBIO, &nonblocking );
|
||||||
|
#else
|
||||||
|
int flags = fcntl( sock, F_GETFL, 0 );
|
||||||
|
fcntl( sock, F_SETFL, flags & ~O_NONBLOCK );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_sock.store( sock, std::memory_order_relaxed );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Socket::ConnectBlocking( const char* addr, uint16_t port )
|
||||||
|
{
|
||||||
|
assert( !IsValid() );
|
||||||
|
assert( !m_ptr );
|
||||||
|
|
||||||
|
struct addrinfo hints;
|
||||||
|
struct addrinfo *res, *ptr;
|
||||||
|
|
||||||
|
memset( &hints, 0, sizeof( hints ) );
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
|
||||||
|
char portbuf[32];
|
||||||
|
sprintf( portbuf, "%" PRIu16, port );
|
||||||
|
|
||||||
|
if( getaddrinfo( addr, portbuf, &hints, &res ) != 0 ) return false;
|
||||||
|
int sock = 0;
|
||||||
|
for( ptr = res; ptr; ptr = ptr->ai_next )
|
||||||
|
{
|
||||||
|
if( ( sock = socket( ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol ) ) == -1 ) continue;
|
||||||
|
#if defined __APPLE__
|
||||||
|
int val = 1;
|
||||||
|
setsockopt( sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof( val ) );
|
||||||
|
#endif
|
||||||
|
if( connect( sock, ptr->ai_addr, ptr->ai_addrlen ) == -1 )
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
closesocket( sock );
|
||||||
|
#else
|
||||||
|
close( sock );
|
||||||
|
#endif
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
freeaddrinfo( res );
|
||||||
|
if( !ptr ) return false;
|
||||||
|
|
||||||
|
m_sock.store( sock, std::memory_order_relaxed );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Socket::Close()
|
||||||
|
{
|
||||||
|
const auto sock = m_sock.load( std::memory_order_relaxed );
|
||||||
|
assert( sock != -1 );
|
||||||
|
#ifdef _WIN32
|
||||||
|
closesocket( sock );
|
||||||
|
#else
|
||||||
|
close( sock );
|
||||||
|
#endif
|
||||||
|
m_sock.store( -1, std::memory_order_relaxed );
|
||||||
|
}
|
||||||
|
|
||||||
|
int Socket::Send( const void* _buf, int len )
|
||||||
|
{
|
||||||
|
const auto sock = m_sock.load( std::memory_order_relaxed );
|
||||||
|
auto buf = (const char*)_buf;
|
||||||
|
assert( sock != -1 );
|
||||||
|
auto start = buf;
|
||||||
|
while( len > 0 )
|
||||||
|
{
|
||||||
|
auto ret = send( sock, buf, len, MSG_NOSIGNAL );
|
||||||
|
if( ret == -1 ) return -1;
|
||||||
|
len -= ret;
|
||||||
|
buf += ret;
|
||||||
|
}
|
||||||
|
return int( buf - start );
|
||||||
|
}
|
||||||
|
|
||||||
|
int Socket::GetSendBufSize()
|
||||||
|
{
|
||||||
|
const auto sock = m_sock.load( std::memory_order_relaxed );
|
||||||
|
int bufSize;
|
||||||
|
#if defined _WIN32
|
||||||
|
int sz = sizeof( bufSize );
|
||||||
|
getsockopt( sock, SOL_SOCKET, SO_SNDBUF, (char*)&bufSize, &sz );
|
||||||
|
#else
|
||||||
|
socklen_t sz = sizeof( bufSize );
|
||||||
|
getsockopt( sock, SOL_SOCKET, SO_SNDBUF, &bufSize, &sz );
|
||||||
|
#endif
|
||||||
|
return bufSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Socket::RecvBuffered( void* buf, int len, int timeout )
|
||||||
|
{
|
||||||
|
if( len <= m_bufLeft )
|
||||||
|
{
|
||||||
|
memcpy( buf, m_bufPtr, len );
|
||||||
|
m_bufPtr += len;
|
||||||
|
m_bufLeft -= len;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_bufLeft > 0 )
|
||||||
|
{
|
||||||
|
memcpy( buf, m_bufPtr, m_bufLeft );
|
||||||
|
const auto ret = m_bufLeft;
|
||||||
|
m_bufLeft = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( len >= BufSize ) return Recv( buf, len, timeout );
|
||||||
|
|
||||||
|
m_bufLeft = Recv( m_buf, BufSize, timeout );
|
||||||
|
if( m_bufLeft <= 0 ) return m_bufLeft;
|
||||||
|
|
||||||
|
const auto sz = len < m_bufLeft ? len : m_bufLeft;
|
||||||
|
memcpy( buf, m_buf, sz );
|
||||||
|
m_bufPtr = m_buf + sz;
|
||||||
|
m_bufLeft -= sz;
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Socket::Recv( void* _buf, int len, int timeout )
|
||||||
|
{
|
||||||
|
const auto sock = m_sock.load( std::memory_order_relaxed );
|
||||||
|
auto buf = (char*)_buf;
|
||||||
|
|
||||||
|
struct pollfd fd;
|
||||||
|
fd.fd = (socket_t)sock;
|
||||||
|
fd.events = POLLIN;
|
||||||
|
|
||||||
|
if( poll( &fd, 1, timeout ) > 0 )
|
||||||
|
{
|
||||||
|
return recv( sock, buf, len, 0 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Socket::ReadUpTo( void* _buf, int len )
|
||||||
|
{
|
||||||
|
const auto sock = m_sock.load( std::memory_order_relaxed );
|
||||||
|
auto buf = (char*)_buf;
|
||||||
|
|
||||||
|
int rd = 0;
|
||||||
|
while( len > 0 )
|
||||||
|
{
|
||||||
|
const auto res = recv( sock, buf, len, 0 );
|
||||||
|
if( res == 0 ) break;
|
||||||
|
if( res == -1 ) return -1;
|
||||||
|
len -= res;
|
||||||
|
rd += res;
|
||||||
|
buf += res;
|
||||||
|
}
|
||||||
|
return rd;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Socket::Read( void* buf, int len, int timeout )
|
||||||
|
{
|
||||||
|
auto cbuf = (char*)buf;
|
||||||
|
while( len > 0 )
|
||||||
|
{
|
||||||
|
if( !ReadImpl( cbuf, len, timeout ) ) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Socket::ReadImpl( char*& buf, int& len, int timeout )
|
||||||
|
{
|
||||||
|
const auto sz = RecvBuffered( buf, len, timeout );
|
||||||
|
switch( sz )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return false;
|
||||||
|
case -1:
|
||||||
|
#ifdef _WIN32
|
||||||
|
{
|
||||||
|
auto err = WSAGetLastError();
|
||||||
|
if( err == WSAECONNABORTED || err == WSAECONNRESET ) return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
len -= sz;
|
||||||
|
buf += sz;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Socket::ReadRaw( void* _buf, int len, int timeout )
|
||||||
|
{
|
||||||
|
auto buf = (char*)_buf;
|
||||||
|
while( len > 0 )
|
||||||
|
{
|
||||||
|
const auto sz = Recv( buf, len, timeout );
|
||||||
|
if( sz <= 0 ) return false;
|
||||||
|
len -= sz;
|
||||||
|
buf += sz;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Socket::HasData()
|
||||||
|
{
|
||||||
|
const auto sock = m_sock.load( std::memory_order_relaxed );
|
||||||
|
if( m_bufLeft > 0 ) return true;
|
||||||
|
|
||||||
|
struct pollfd fd;
|
||||||
|
fd.fd = (socket_t)sock;
|
||||||
|
fd.events = POLLIN;
|
||||||
|
|
||||||
|
return poll( &fd, 1, 0 ) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Socket::IsValid() const
|
||||||
|
{
|
||||||
|
return m_sock.load( std::memory_order_relaxed ) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ListenSocket::ListenSocket()
|
||||||
|
: m_sock( -1 )
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
InitWinSock();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ListenSocket::~ListenSocket()
|
||||||
|
{
|
||||||
|
if( m_sock != -1 ) Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int addrinfo_and_socket_for_family( uint16_t port, int ai_family, struct addrinfo** res )
|
||||||
|
{
|
||||||
|
struct addrinfo hints;
|
||||||
|
memset( &hints, 0, sizeof( hints ) );
|
||||||
|
hints.ai_family = ai_family;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
#ifndef TRACY_ONLY_LOCALHOST
|
||||||
|
const char* onlyLocalhost = GetEnvVar( "TRACY_ONLY_LOCALHOST" );
|
||||||
|
if( !onlyLocalhost || onlyLocalhost[0] != '1' )
|
||||||
|
{
|
||||||
|
hints.ai_flags = AI_PASSIVE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
char portbuf[32];
|
||||||
|
sprintf( portbuf, "%" PRIu16, port );
|
||||||
|
if( getaddrinfo( nullptr, portbuf, &hints, res ) != 0 ) return -1;
|
||||||
|
int sock = socket( (*res)->ai_family, (*res)->ai_socktype, (*res)->ai_protocol );
|
||||||
|
if (sock == -1) freeaddrinfo( *res );
|
||||||
|
return sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ListenSocket::Listen( uint16_t port, int backlog )
|
||||||
|
{
|
||||||
|
assert( m_sock == -1 );
|
||||||
|
|
||||||
|
struct addrinfo* res = nullptr;
|
||||||
|
|
||||||
|
#if !defined TRACY_ONLY_IPV4 && !defined TRACY_ONLY_LOCALHOST
|
||||||
|
const char* onlyIPv4 = GetEnvVar( "TRACY_ONLY_IPV4" );
|
||||||
|
if( !onlyIPv4 || onlyIPv4[0] != '1' )
|
||||||
|
{
|
||||||
|
m_sock = addrinfo_and_socket_for_family( port, AF_INET6, &res );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (m_sock == -1)
|
||||||
|
{
|
||||||
|
// IPV6 protocol may not be available/is disabled. Try to create a socket
|
||||||
|
// with the IPV4 protocol
|
||||||
|
m_sock = addrinfo_and_socket_for_family( port, AF_INET, &res );
|
||||||
|
if( m_sock == -1 ) return false;
|
||||||
|
}
|
||||||
|
#if defined _WIN32
|
||||||
|
unsigned long val = 0;
|
||||||
|
setsockopt( m_sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&val, sizeof( val ) );
|
||||||
|
#elif defined BSD
|
||||||
|
int val = 0;
|
||||||
|
setsockopt( m_sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&val, sizeof( val ) );
|
||||||
|
val = 1;
|
||||||
|
setsockopt( m_sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof( val ) );
|
||||||
|
#else
|
||||||
|
int val = 1;
|
||||||
|
setsockopt( m_sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof( val ) );
|
||||||
|
#endif
|
||||||
|
if( bind( m_sock, res->ai_addr, res->ai_addrlen ) == -1 ) { freeaddrinfo( res ); Close(); return false; }
|
||||||
|
if( listen( m_sock, backlog ) == -1 ) { freeaddrinfo( res ); Close(); return false; }
|
||||||
|
freeaddrinfo( res );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Socket* ListenSocket::Accept()
|
||||||
|
{
|
||||||
|
struct sockaddr_storage remote;
|
||||||
|
socklen_t sz = sizeof( remote );
|
||||||
|
|
||||||
|
struct pollfd fd;
|
||||||
|
fd.fd = (socket_t)m_sock;
|
||||||
|
fd.events = POLLIN;
|
||||||
|
|
||||||
|
if( poll( &fd, 1, 10 ) > 0 )
|
||||||
|
{
|
||||||
|
int sock = accept( m_sock, (sockaddr*)&remote, &sz);
|
||||||
|
if( sock == -1 ) return nullptr;
|
||||||
|
|
||||||
|
#if defined __APPLE__
|
||||||
|
int val = 1;
|
||||||
|
setsockopt( sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof( val ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto ptr = (Socket*)tracy_malloc( sizeof( Socket ) );
|
||||||
|
new(ptr) Socket( sock );
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListenSocket::Close()
|
||||||
|
{
|
||||||
|
assert( m_sock != -1 );
|
||||||
|
#ifdef _WIN32
|
||||||
|
closesocket( m_sock );
|
||||||
|
#else
|
||||||
|
close( m_sock );
|
||||||
|
#endif
|
||||||
|
m_sock = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
UdpBroadcast::UdpBroadcast()
|
||||||
|
: m_sock( -1 )
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
InitWinSock();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
UdpBroadcast::~UdpBroadcast()
|
||||||
|
{
|
||||||
|
if( m_sock != -1 ) Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UdpBroadcast::Open( const char* addr, uint16_t port )
|
||||||
|
{
|
||||||
|
assert( m_sock == -1 );
|
||||||
|
|
||||||
|
struct addrinfo hints;
|
||||||
|
struct addrinfo *res, *ptr;
|
||||||
|
|
||||||
|
memset( &hints, 0, sizeof( hints ) );
|
||||||
|
hints.ai_family = AF_INET;
|
||||||
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
|
|
||||||
|
char portbuf[32];
|
||||||
|
sprintf( portbuf, "%" PRIu16, port );
|
||||||
|
|
||||||
|
if( getaddrinfo( addr, portbuf, &hints, &res ) != 0 ) return false;
|
||||||
|
int sock = 0;
|
||||||
|
for( ptr = res; ptr; ptr = ptr->ai_next )
|
||||||
|
{
|
||||||
|
if( ( sock = socket( ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol ) ) == -1 ) continue;
|
||||||
|
#if defined __APPLE__
|
||||||
|
int val = 1;
|
||||||
|
setsockopt( sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof( val ) );
|
||||||
|
#endif
|
||||||
|
#if defined _WIN32
|
||||||
|
unsigned long broadcast = 1;
|
||||||
|
if( setsockopt( sock, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof( broadcast ) ) == -1 )
|
||||||
|
#else
|
||||||
|
int broadcast = 1;
|
||||||
|
if( setsockopt( sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof( broadcast ) ) == -1 )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
closesocket( sock );
|
||||||
|
#else
|
||||||
|
close( sock );
|
||||||
|
#endif
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
freeaddrinfo( res );
|
||||||
|
if( !ptr ) return false;
|
||||||
|
|
||||||
|
m_sock = sock;
|
||||||
|
inet_pton( AF_INET, addr, &m_addr );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UdpBroadcast::Close()
|
||||||
|
{
|
||||||
|
assert( m_sock != -1 );
|
||||||
|
#ifdef _WIN32
|
||||||
|
closesocket( m_sock );
|
||||||
|
#else
|
||||||
|
close( m_sock );
|
||||||
|
#endif
|
||||||
|
m_sock = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int UdpBroadcast::Send( uint16_t port, const void* data, int len )
|
||||||
|
{
|
||||||
|
assert( m_sock != -1 );
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = htons( port );
|
||||||
|
addr.sin_addr.s_addr = m_addr;
|
||||||
|
return sendto( m_sock, (const char*)data, len, MSG_NOSIGNAL, (sockaddr*)&addr, sizeof( addr ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
IpAddress::IpAddress()
|
||||||
|
: m_number( 0 )
|
||||||
|
{
|
||||||
|
*m_text = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
IpAddress::~IpAddress()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void IpAddress::Set( const struct sockaddr& addr )
|
||||||
|
{
|
||||||
|
#if defined _WIN32 && ( !defined NTDDI_WIN10 || NTDDI_VERSION < NTDDI_WIN10 )
|
||||||
|
struct sockaddr_in tmp;
|
||||||
|
memcpy( &tmp, &addr, sizeof( tmp ) );
|
||||||
|
auto ai = &tmp;
|
||||||
|
#else
|
||||||
|
auto ai = (const struct sockaddr_in*)&addr;
|
||||||
|
#endif
|
||||||
|
inet_ntop( AF_INET, &ai->sin_addr, m_text, 17 );
|
||||||
|
m_number = ai->sin_addr.s_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
UdpListen::UdpListen()
|
||||||
|
: m_sock( -1 )
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
InitWinSock();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
UdpListen::~UdpListen()
|
||||||
|
{
|
||||||
|
if( m_sock != -1 ) Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UdpListen::Listen( uint16_t port )
|
||||||
|
{
|
||||||
|
assert( m_sock == -1 );
|
||||||
|
|
||||||
|
int sock;
|
||||||
|
if( ( sock = socket( AF_INET, SOCK_DGRAM, 0 ) ) == -1 ) return false;
|
||||||
|
|
||||||
|
#if defined __APPLE__
|
||||||
|
int val = 1;
|
||||||
|
setsockopt( sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof( val ) );
|
||||||
|
#endif
|
||||||
|
#if defined _WIN32
|
||||||
|
unsigned long reuse = 1;
|
||||||
|
setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof( reuse ) );
|
||||||
|
#else
|
||||||
|
int reuse = 1;
|
||||||
|
setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof( reuse ) );
|
||||||
|
#endif
|
||||||
|
#if defined _WIN32
|
||||||
|
unsigned long broadcast = 1;
|
||||||
|
if( setsockopt( sock, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof( broadcast ) ) == -1 )
|
||||||
|
#else
|
||||||
|
int broadcast = 1;
|
||||||
|
if( setsockopt( sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof( broadcast ) ) == -1 )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
closesocket( sock );
|
||||||
|
#else
|
||||||
|
close( sock );
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = htons( port );
|
||||||
|
addr.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
|
||||||
|
if( bind( sock, (sockaddr*)&addr, sizeof( addr ) ) == -1 )
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
closesocket( sock );
|
||||||
|
#else
|
||||||
|
close( sock );
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_sock = sock;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UdpListen::Close()
|
||||||
|
{
|
||||||
|
assert( m_sock != -1 );
|
||||||
|
#ifdef _WIN32
|
||||||
|
closesocket( m_sock );
|
||||||
|
#else
|
||||||
|
close( m_sock );
|
||||||
|
#endif
|
||||||
|
m_sock = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* UdpListen::Read( size_t& len, IpAddress& addr, int timeout )
|
||||||
|
{
|
||||||
|
static char buf[2048];
|
||||||
|
|
||||||
|
struct pollfd fd;
|
||||||
|
fd.fd = (socket_t)m_sock;
|
||||||
|
fd.events = POLLIN;
|
||||||
|
if( poll( &fd, 1, timeout ) <= 0 ) return nullptr;
|
||||||
|
|
||||||
|
sockaddr sa;
|
||||||
|
socklen_t salen = sizeof( struct sockaddr );
|
||||||
|
len = (size_t)recvfrom( m_sock, buf, 2048, 0, &sa, &salen );
|
||||||
|
addr.Set( sa );
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
155
externals/tracy/public/common/TracySocket.hpp
vendored
Normal file
155
externals/tracy/public/common/TracySocket.hpp
vendored
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
#ifndef __TRACYSOCKET_HPP__
|
||||||
|
#define __TRACYSOCKET_HPP__
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct addrinfo;
|
||||||
|
struct sockaddr;
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
void InitWinSock();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class Socket
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Socket();
|
||||||
|
Socket( int sock );
|
||||||
|
~Socket();
|
||||||
|
|
||||||
|
bool Connect( const char* addr, uint16_t port );
|
||||||
|
bool ConnectBlocking( const char* addr, uint16_t port );
|
||||||
|
void Close();
|
||||||
|
|
||||||
|
int Send( const void* buf, int len );
|
||||||
|
int GetSendBufSize();
|
||||||
|
|
||||||
|
int ReadUpTo( void* buf, int len );
|
||||||
|
bool Read( void* buf, int len, int timeout );
|
||||||
|
|
||||||
|
template<typename ShouldExit>
|
||||||
|
bool Read( void* buf, int len, int timeout, ShouldExit exitCb )
|
||||||
|
{
|
||||||
|
auto cbuf = (char*)buf;
|
||||||
|
while( len > 0 )
|
||||||
|
{
|
||||||
|
if( exitCb() ) return false;
|
||||||
|
if( !ReadImpl( cbuf, len, timeout ) ) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadRaw( void* buf, int len, int timeout );
|
||||||
|
bool HasData();
|
||||||
|
bool IsValid() const;
|
||||||
|
|
||||||
|
Socket( const Socket& ) = delete;
|
||||||
|
Socket( Socket&& ) = delete;
|
||||||
|
Socket& operator=( const Socket& ) = delete;
|
||||||
|
Socket& operator=( Socket&& ) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int RecvBuffered( void* buf, int len, int timeout );
|
||||||
|
int Recv( void* buf, int len, int timeout );
|
||||||
|
|
||||||
|
bool ReadImpl( char*& buf, int& len, int timeout );
|
||||||
|
|
||||||
|
char* m_buf;
|
||||||
|
char* m_bufPtr;
|
||||||
|
std::atomic<int> m_sock;
|
||||||
|
int m_bufLeft;
|
||||||
|
|
||||||
|
struct addrinfo *m_res;
|
||||||
|
struct addrinfo *m_ptr;
|
||||||
|
int m_connSock;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ListenSocket
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ListenSocket();
|
||||||
|
~ListenSocket();
|
||||||
|
|
||||||
|
bool Listen( uint16_t port, int backlog );
|
||||||
|
Socket* Accept();
|
||||||
|
void Close();
|
||||||
|
|
||||||
|
ListenSocket( const ListenSocket& ) = delete;
|
||||||
|
ListenSocket( ListenSocket&& ) = delete;
|
||||||
|
ListenSocket& operator=( const ListenSocket& ) = delete;
|
||||||
|
ListenSocket& operator=( ListenSocket&& ) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_sock;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UdpBroadcast
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UdpBroadcast();
|
||||||
|
~UdpBroadcast();
|
||||||
|
|
||||||
|
bool Open( const char* addr, uint16_t port );
|
||||||
|
void Close();
|
||||||
|
|
||||||
|
int Send( uint16_t port, const void* data, int len );
|
||||||
|
|
||||||
|
UdpBroadcast( const UdpBroadcast& ) = delete;
|
||||||
|
UdpBroadcast( UdpBroadcast&& ) = delete;
|
||||||
|
UdpBroadcast& operator=( const UdpBroadcast& ) = delete;
|
||||||
|
UdpBroadcast& operator=( UdpBroadcast&& ) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_sock;
|
||||||
|
uint32_t m_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IpAddress
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IpAddress();
|
||||||
|
~IpAddress();
|
||||||
|
|
||||||
|
void Set( const struct sockaddr& addr );
|
||||||
|
|
||||||
|
uint32_t GetNumber() const { return m_number; }
|
||||||
|
const char* GetText() const { return m_text; }
|
||||||
|
|
||||||
|
IpAddress( const IpAddress& ) = delete;
|
||||||
|
IpAddress( IpAddress&& ) = delete;
|
||||||
|
IpAddress& operator=( const IpAddress& ) = delete;
|
||||||
|
IpAddress& operator=( IpAddress&& ) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_number;
|
||||||
|
char m_text[17];
|
||||||
|
};
|
||||||
|
|
||||||
|
class UdpListen
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UdpListen();
|
||||||
|
~UdpListen();
|
||||||
|
|
||||||
|
bool Listen( uint16_t port );
|
||||||
|
void Close();
|
||||||
|
|
||||||
|
const char* Read( size_t& len, IpAddress& addr, int timeout );
|
||||||
|
|
||||||
|
UdpListen( const UdpListen& ) = delete;
|
||||||
|
UdpListen( UdpListen&& ) = delete;
|
||||||
|
UdpListen& operator=( const UdpListen& ) = delete;
|
||||||
|
UdpListen& operator=( UdpListen&& ) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_sock;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
122
externals/tracy/public/common/TracyStackFrames.cpp
vendored
Normal file
122
externals/tracy/public/common/TracyStackFrames.cpp
vendored
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#include "TracyStackFrames.hpp"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
const char* s_tracyStackFrames_[] = {
|
||||||
|
"tracy::Callstack",
|
||||||
|
"tracy::Callstack(int)",
|
||||||
|
"tracy::GpuCtxScope::{ctor}",
|
||||||
|
"tracy::Profiler::SendCallstack",
|
||||||
|
"tracy::Profiler::SendCallstack(int)",
|
||||||
|
"tracy::Profiler::SendCallstack(int, unsigned long)",
|
||||||
|
"tracy::Profiler::MemAllocCallstack",
|
||||||
|
"tracy::Profiler::MemAllocCallstack(void const*, unsigned long, int)",
|
||||||
|
"tracy::Profiler::MemFreeCallstack",
|
||||||
|
"tracy::Profiler::MemFreeCallstack(void const*, int)",
|
||||||
|
"tracy::ScopedZone::{ctor}",
|
||||||
|
"tracy::ScopedZone::ScopedZone(tracy::SourceLocationData const*, int, bool)",
|
||||||
|
"tracy::Profiler::Message",
|
||||||
|
nullptr
|
||||||
|
};
|
||||||
|
|
||||||
|
const char** s_tracyStackFrames = s_tracyStackFrames_;
|
||||||
|
|
||||||
|
const StringMatch s_tracySkipSubframes_[] = {
|
||||||
|
{ "/include/arm_neon.h", 19 },
|
||||||
|
{ "/include/adxintrin.h", 20 },
|
||||||
|
{ "/include/ammintrin.h", 20 },
|
||||||
|
{ "/include/amxbf16intrin.h", 24 },
|
||||||
|
{ "/include/amxint8intrin.h", 24 },
|
||||||
|
{ "/include/amxtileintrin.h", 24 },
|
||||||
|
{ "/include/avx2intrin.h", 21 },
|
||||||
|
{ "/include/avx5124fmapsintrin.h", 29 },
|
||||||
|
{ "/include/avx5124vnniwintrin.h", 29 },
|
||||||
|
{ "/include/avx512bf16intrin.h", 27 },
|
||||||
|
{ "/include/avx512bf16vlintrin.h", 29 },
|
||||||
|
{ "/include/avx512bitalgintrin.h", 29 },
|
||||||
|
{ "/include/avx512bwintrin.h", 25 },
|
||||||
|
{ "/include/avx512cdintrin.h", 25 },
|
||||||
|
{ "/include/avx512dqintrin.h", 25 },
|
||||||
|
{ "/include/avx512erintrin.h", 25 },
|
||||||
|
{ "/include/avx512fintrin.h", 24 },
|
||||||
|
{ "/include/avx512ifmaintrin.h", 27 },
|
||||||
|
{ "/include/avx512ifmavlintrin.h", 29 },
|
||||||
|
{ "/include/avx512pfintrin.h", 25 },
|
||||||
|
{ "/include/avx512vbmi2intrin.h", 28 },
|
||||||
|
{ "/include/avx512vbmi2vlintrin.h", 30 },
|
||||||
|
{ "/include/avx512vbmiintrin.h", 27 },
|
||||||
|
{ "/include/avx512vbmivlintrin.h", 29 },
|
||||||
|
{ "/include/avx512vlbwintrin.h", 27 },
|
||||||
|
{ "/include/avx512vldqintrin.h", 27 },
|
||||||
|
{ "/include/avx512vlintrin.h", 25 },
|
||||||
|
{ "/include/avx512vnniintrin.h", 27 },
|
||||||
|
{ "/include/avx512vnnivlintrin.h", 29 },
|
||||||
|
{ "/include/avx512vp2intersectintrin.h", 35 },
|
||||||
|
{ "/include/avx512vp2intersectvlintrin.h", 37 },
|
||||||
|
{ "/include/avx512vpopcntdqintrin.h", 32 },
|
||||||
|
{ "/include/avx512vpopcntdqvlintrin.h", 34 },
|
||||||
|
{ "/include/avxintrin.h", 20 },
|
||||||
|
{ "/include/avxvnniintrin.h", 24 },
|
||||||
|
{ "/include/bmi2intrin.h", 21 },
|
||||||
|
{ "/include/bmiintrin.h", 20 },
|
||||||
|
{ "/include/bmmintrin.h", 20 },
|
||||||
|
{ "/include/cetintrin.h", 20 },
|
||||||
|
{ "/include/cldemoteintrin.h", 25 },
|
||||||
|
{ "/include/clflushoptintrin.h", 27 },
|
||||||
|
{ "/include/clwbintrin.h", 21 },
|
||||||
|
{ "/include/clzerointrin.h", 23 },
|
||||||
|
{ "/include/emmintrin.h", 20 },
|
||||||
|
{ "/include/enqcmdintrin.h", 23 },
|
||||||
|
{ "/include/f16cintrin.h", 21 },
|
||||||
|
{ "/include/fma4intrin.h", 21 },
|
||||||
|
{ "/include/fmaintrin.h", 20 },
|
||||||
|
{ "/include/fxsrintrin.h", 21 },
|
||||||
|
{ "/include/gfniintrin.h", 21 },
|
||||||
|
{ "/include/hresetintrin.h", 23 },
|
||||||
|
{ "/include/ia32intrin.h", 21 },
|
||||||
|
{ "/include/immintrin.h", 20 },
|
||||||
|
{ "/include/keylockerintrin.h", 26 },
|
||||||
|
{ "/include/lwpintrin.h", 20 },
|
||||||
|
{ "/include/lzcntintrin.h", 22 },
|
||||||
|
{ "/include/mmintrin.h", 19 },
|
||||||
|
{ "/include/movdirintrin.h", 23 },
|
||||||
|
{ "/include/mwaitxintrin.h", 23 },
|
||||||
|
{ "/include/nmmintrin.h", 20 },
|
||||||
|
{ "/include/pconfigintrin.h", 24 },
|
||||||
|
{ "/include/pkuintrin.h", 20 },
|
||||||
|
{ "/include/pmmintrin.h", 20 },
|
||||||
|
{ "/include/popcntintrin.h", 23 },
|
||||||
|
{ "/include/prfchwintrin.h", 23 },
|
||||||
|
{ "/include/rdseedintrin.h", 23 },
|
||||||
|
{ "/include/rtmintrin.h", 20 },
|
||||||
|
{ "/include/serializeintrin.h", 26 },
|
||||||
|
{ "/include/sgxintrin.h", 20 },
|
||||||
|
{ "/include/shaintrin.h", 20 },
|
||||||
|
{ "/include/smmintrin.h", 20 },
|
||||||
|
{ "/include/tbmintrin.h", 20 },
|
||||||
|
{ "/include/tmmintrin.h", 20 },
|
||||||
|
{ "/include/tsxldtrkintrin.h", 25 },
|
||||||
|
{ "/include/uintrintrin.h", 22 },
|
||||||
|
{ "/include/vaesintrin.h", 21 },
|
||||||
|
{ "/include/vpclmulqdqintrin.h", 27 },
|
||||||
|
{ "/include/waitpkgintrin.h", 24 },
|
||||||
|
{ "/include/wbnoinvdintrin.h", 25 },
|
||||||
|
{ "/include/wmmintrin.h", 20 },
|
||||||
|
{ "/include/x86gprintrin.h", 23 },
|
||||||
|
{ "/include/x86intrin.h", 20 },
|
||||||
|
{ "/include/xmmintrin.h", 20 },
|
||||||
|
{ "/include/xopintrin.h", 20 },
|
||||||
|
{ "/include/xsavecintrin.h", 23 },
|
||||||
|
{ "/include/xsaveintrin.h", 22 },
|
||||||
|
{ "/include/xsaveoptintrin.h", 25 },
|
||||||
|
{ "/include/xsavesintrin.h", 23 },
|
||||||
|
{ "/include/xtestintrin.h", 22 },
|
||||||
|
{ "/bits/atomic_base.h", 19 },
|
||||||
|
{ "/atomic", 7 },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
const StringMatch* s_tracySkipSubframes = s_tracySkipSubframes_;
|
||||||
|
|
||||||
|
}
|
22
externals/tracy/public/common/TracyStackFrames.hpp
vendored
Normal file
22
externals/tracy/public/common/TracyStackFrames.hpp
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef __TRACYSTACKFRAMES_HPP__
|
||||||
|
#define __TRACYSTACKFRAMES_HPP__
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
struct StringMatch
|
||||||
|
{
|
||||||
|
const char* str;
|
||||||
|
size_t len;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const char** s_tracyStackFrames;
|
||||||
|
extern const StringMatch* s_tracySkipSubframes;
|
||||||
|
|
||||||
|
static constexpr int s_tracySkipSubframesMinLen = 7;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
331
externals/tracy/public/common/TracySystem.cpp
vendored
Normal file
331
externals/tracy/public/common/TracySystem.cpp
vendored
Normal file
@ -0,0 +1,331 @@
|
|||||||
|
#ifdef _MSC_VER
|
||||||
|
# pragma warning(disable:4996)
|
||||||
|
#endif
|
||||||
|
#if defined _WIN32
|
||||||
|
# ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
# define WIN32_LEAN_AND_MEAN
|
||||||
|
# endif
|
||||||
|
# ifndef NOMINMAX
|
||||||
|
# define NOMINMAX
|
||||||
|
# endif
|
||||||
|
# include <windows.h>
|
||||||
|
# include <malloc.h>
|
||||||
|
# include "TracyUwp.hpp"
|
||||||
|
#else
|
||||||
|
# include <pthread.h>
|
||||||
|
# include <string.h>
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
# ifdef __ANDROID__
|
||||||
|
# include <sys/types.h>
|
||||||
|
# else
|
||||||
|
# include <sys/syscall.h>
|
||||||
|
# endif
|
||||||
|
# include <fcntl.h>
|
||||||
|
#elif defined __FreeBSD__
|
||||||
|
# include <sys/thr.h>
|
||||||
|
#elif defined __NetBSD__ || defined __DragonFly__
|
||||||
|
# include <sys/lwp.h>
|
||||||
|
#elif defined __QNX__
|
||||||
|
# include <process.h>
|
||||||
|
# include <sys/neutrino.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
# define __STDC_FORMAT_MACROS
|
||||||
|
#endif
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "TracySystem.hpp"
|
||||||
|
|
||||||
|
#if defined _WIN32
|
||||||
|
extern "C" typedef HRESULT (WINAPI *t_SetThreadDescription)( HANDLE, PCWSTR );
|
||||||
|
extern "C" typedef HRESULT (WINAPI *t_GetThreadDescription)( HANDLE, PWSTR* );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TRACY_ENABLE
|
||||||
|
# include <atomic>
|
||||||
|
# include "TracyAlloc.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
TRACY_API uint32_t GetThreadHandleImpl()
|
||||||
|
{
|
||||||
|
#if defined _WIN32
|
||||||
|
static_assert( sizeof( decltype( GetCurrentThreadId() ) ) <= sizeof( uint32_t ), "Thread handle too big to fit in protocol" );
|
||||||
|
return uint32_t( GetCurrentThreadId() );
|
||||||
|
#elif defined __APPLE__
|
||||||
|
uint64_t id;
|
||||||
|
pthread_threadid_np( pthread_self(), &id );
|
||||||
|
return uint32_t( id );
|
||||||
|
#elif defined __ANDROID__
|
||||||
|
return (uint32_t)gettid();
|
||||||
|
#elif defined __linux__
|
||||||
|
return (uint32_t)syscall( SYS_gettid );
|
||||||
|
#elif defined __FreeBSD__
|
||||||
|
long id;
|
||||||
|
thr_self( &id );
|
||||||
|
return id;
|
||||||
|
#elif defined __NetBSD__
|
||||||
|
return _lwp_self();
|
||||||
|
#elif defined __DragonFly__
|
||||||
|
return lwp_gettid();
|
||||||
|
#elif defined __OpenBSD__
|
||||||
|
return getthrid();
|
||||||
|
#elif defined __QNX__
|
||||||
|
return (uint32_t) gettid();
|
||||||
|
#elif defined __EMSCRIPTEN__
|
||||||
|
// Not supported, but let it compile.
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
// To add support for a platform, retrieve and return the kernel thread identifier here.
|
||||||
|
//
|
||||||
|
// Note that pthread_t (as for example returned by pthread_self()) is *not* a kernel
|
||||||
|
// thread identifier. It is a pointer to a library-allocated data structure instead.
|
||||||
|
// Such pointers will be reused heavily, making the pthread_t non-unique. Additionally
|
||||||
|
// a 64-bit pointer cannot be reliably truncated to 32 bits.
|
||||||
|
#error "Unsupported platform!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TRACY_ENABLE
|
||||||
|
struct ThreadNameData
|
||||||
|
{
|
||||||
|
uint32_t id;
|
||||||
|
const char* name;
|
||||||
|
ThreadNameData* next;
|
||||||
|
};
|
||||||
|
std::atomic<ThreadNameData*>& GetThreadNameData();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# pragma pack( push, 8 )
|
||||||
|
struct THREADNAME_INFO
|
||||||
|
{
|
||||||
|
DWORD dwType;
|
||||||
|
LPCSTR szName;
|
||||||
|
DWORD dwThreadID;
|
||||||
|
DWORD dwFlags;
|
||||||
|
};
|
||||||
|
# pragma pack( pop )
|
||||||
|
|
||||||
|
void ThreadNameMsvcMagic( const THREADNAME_INFO& info )
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
|
||||||
|
}
|
||||||
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TRACY_API void SetThreadName( const char* name )
|
||||||
|
{
|
||||||
|
#if defined _WIN32
|
||||||
|
# ifdef TRACY_UWP
|
||||||
|
static auto _SetThreadDescription = &::SetThreadDescription;
|
||||||
|
# else
|
||||||
|
static auto _SetThreadDescription = (t_SetThreadDescription)GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "SetThreadDescription" );
|
||||||
|
# endif
|
||||||
|
if( _SetThreadDescription )
|
||||||
|
{
|
||||||
|
wchar_t buf[256];
|
||||||
|
mbstowcs( buf, name, 256 );
|
||||||
|
_SetThreadDescription( GetCurrentThread(), buf );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
# if defined _MSC_VER
|
||||||
|
THREADNAME_INFO info;
|
||||||
|
info.dwType = 0x1000;
|
||||||
|
info.szName = name;
|
||||||
|
info.dwThreadID = GetCurrentThreadId();
|
||||||
|
info.dwFlags = 0;
|
||||||
|
ThreadNameMsvcMagic( info );
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
#elif defined _GNU_SOURCE && !defined __EMSCRIPTEN__
|
||||||
|
{
|
||||||
|
const auto sz = strlen( name );
|
||||||
|
if( sz <= 15 )
|
||||||
|
{
|
||||||
|
#if defined __APPLE__
|
||||||
|
pthread_setname_np( name );
|
||||||
|
#else
|
||||||
|
pthread_setname_np( pthread_self(), name );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char buf[16];
|
||||||
|
memcpy( buf, name, 15 );
|
||||||
|
buf[15] = '\0';
|
||||||
|
#if defined __APPLE__
|
||||||
|
pthread_setname_np( buf );
|
||||||
|
#else
|
||||||
|
pthread_setname_np( pthread_self(), buf );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif defined __QNX__
|
||||||
|
{
|
||||||
|
const auto sz = strlen( name );
|
||||||
|
if( sz <= _NTO_THREAD_NAME_MAX )
|
||||||
|
{
|
||||||
|
pthread_setname_np( pthread_self(), name );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char buf[_NTO_THREAD_NAME_MAX + 1];
|
||||||
|
memcpy( buf, name, _NTO_THREAD_NAME_MAX );
|
||||||
|
buf[_NTO_THREAD_NAME_MAX] = '\0';
|
||||||
|
pthread_setname_np( pthread_self(), buf );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#ifdef TRACY_ENABLE
|
||||||
|
{
|
||||||
|
const auto sz = strlen( name );
|
||||||
|
char* buf = (char*)tracy_malloc( sz+1 );
|
||||||
|
memcpy( buf, name, sz );
|
||||||
|
buf[sz] = '\0';
|
||||||
|
auto data = (ThreadNameData*)tracy_malloc_fast( sizeof( ThreadNameData ) );
|
||||||
|
data->id = detail::GetThreadHandleImpl();
|
||||||
|
data->name = buf;
|
||||||
|
data->next = GetThreadNameData().load( std::memory_order_relaxed );
|
||||||
|
while( !GetThreadNameData().compare_exchange_weak( data->next, data, std::memory_order_release, std::memory_order_relaxed ) ) {}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACY_API const char* GetThreadName( uint32_t id )
|
||||||
|
{
|
||||||
|
static char buf[256];
|
||||||
|
#ifdef TRACY_ENABLE
|
||||||
|
auto ptr = GetThreadNameData().load( std::memory_order_relaxed );
|
||||||
|
while( ptr )
|
||||||
|
{
|
||||||
|
if( ptr->id == id )
|
||||||
|
{
|
||||||
|
return ptr->name;
|
||||||
|
}
|
||||||
|
ptr = ptr->next;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined _WIN32
|
||||||
|
# ifdef TRACY_UWP
|
||||||
|
static auto _GetThreadDescription = &::GetThreadDescription;
|
||||||
|
# else
|
||||||
|
static auto _GetThreadDescription = (t_GetThreadDescription)GetProcAddress( GetModuleHandleA( "kernel32.dll" ), "GetThreadDescription" );
|
||||||
|
# endif
|
||||||
|
if( _GetThreadDescription )
|
||||||
|
{
|
||||||
|
auto hnd = OpenThread( THREAD_QUERY_LIMITED_INFORMATION, FALSE, (DWORD)id );
|
||||||
|
if( hnd != 0 )
|
||||||
|
{
|
||||||
|
PWSTR tmp;
|
||||||
|
if( SUCCEEDED( _GetThreadDescription( hnd, &tmp ) ) )
|
||||||
|
{
|
||||||
|
auto ret = wcstombs( buf, tmp, 256 );
|
||||||
|
CloseHandle( hnd );
|
||||||
|
LocalFree( tmp );
|
||||||
|
if( ret != static_cast<size_t>( -1 ) )
|
||||||
|
{
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif defined __linux__
|
||||||
|
int cs, fd;
|
||||||
|
char path[32];
|
||||||
|
snprintf( path, sizeof( path ), "/proc/self/task/%d/comm", id );
|
||||||
|
sprintf( buf, "%" PRIu32, id );
|
||||||
|
# ifndef __ANDROID__
|
||||||
|
pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &cs );
|
||||||
|
# endif
|
||||||
|
if ( ( fd = open( path, O_RDONLY ) ) > 0) {
|
||||||
|
int len = read( fd, buf, 255 );
|
||||||
|
if( len > 0 )
|
||||||
|
{
|
||||||
|
buf[len] = 0;
|
||||||
|
if( len > 1 && buf[len-1] == '\n' )
|
||||||
|
{
|
||||||
|
buf[len-1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close( fd );
|
||||||
|
}
|
||||||
|
# ifndef __ANDROID__
|
||||||
|
pthread_setcancelstate( cs, 0 );
|
||||||
|
# endif
|
||||||
|
return buf;
|
||||||
|
#elif defined __QNX__
|
||||||
|
static char qnxNameBuf[_NTO_THREAD_NAME_MAX + 1] = {0};
|
||||||
|
if (pthread_getname_np(static_cast<int>(id), qnxNameBuf, _NTO_THREAD_NAME_MAX) == 0) {
|
||||||
|
return qnxNameBuf;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sprintf( buf, "%" PRIu32, id );
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACY_API const char* GetEnvVar( const char* name )
|
||||||
|
{
|
||||||
|
#if defined _WIN32
|
||||||
|
// unfortunately getenv() on Windows is just fundamentally broken. It caches the entire
|
||||||
|
// environment block once on startup, then never refreshes it again. If any environment
|
||||||
|
// strings are added or modified after startup of the CRT, those changes will not be
|
||||||
|
// seen by getenv(). This removes the possibility of an app using this SDK from
|
||||||
|
// programmatically setting any of the behaviour controlling envvars here.
|
||||||
|
//
|
||||||
|
// To work around this, we'll instead go directly to the Win32 environment strings APIs
|
||||||
|
// to get the current value.
|
||||||
|
static char buffer[1024];
|
||||||
|
DWORD const kBufferSize = DWORD(sizeof(buffer) / sizeof(buffer[0]));
|
||||||
|
DWORD count = GetEnvironmentVariableA(name, buffer, kBufferSize);
|
||||||
|
|
||||||
|
if( count == 0 )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if( count >= kBufferSize )
|
||||||
|
{
|
||||||
|
char* buf = reinterpret_cast<char*>(_alloca(count + 1));
|
||||||
|
count = GetEnvironmentVariableA(name, buf, count + 1);
|
||||||
|
memcpy(buffer, buf, kBufferSize);
|
||||||
|
buffer[kBufferSize - 1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
#else
|
||||||
|
return getenv(name);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TRACY_API void ___tracy_set_thread_name( const char* name ) { tracy::SetThreadName( name ); }
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
32
externals/tracy/public/common/TracySystem.hpp
vendored
Normal file
32
externals/tracy/public/common/TracySystem.hpp
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#ifndef __TRACYSYSTEM_HPP__
|
||||||
|
#define __TRACYSYSTEM_HPP__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "TracyApi.h"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
TRACY_API uint32_t GetThreadHandleImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TRACY_ENABLE
|
||||||
|
TRACY_API uint32_t GetThreadHandle();
|
||||||
|
#else
|
||||||
|
static inline uint32_t GetThreadHandle()
|
||||||
|
{
|
||||||
|
return detail::GetThreadHandleImpl();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TRACY_API void SetThreadName( const char* name );
|
||||||
|
TRACY_API const char* GetThreadName( uint32_t id );
|
||||||
|
|
||||||
|
TRACY_API const char* GetEnvVar( const char* name );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
11
externals/tracy/public/common/TracyUwp.hpp
vendored
Normal file
11
externals/tracy/public/common/TracyUwp.hpp
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef __TRACYUWP_HPP__
|
||||||
|
#define __TRACYUWP_HPP__
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# include <winapifamily.h>
|
||||||
|
# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
|
# define TRACY_UWP
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
14
externals/tracy/public/common/TracyVersion.hpp
vendored
Normal file
14
externals/tracy/public/common/TracyVersion.hpp
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef __TRACYVERSION_HPP__
|
||||||
|
#define __TRACYVERSION_HPP__
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
namespace Version
|
||||||
|
{
|
||||||
|
enum { Major = 0 };
|
||||||
|
enum { Minor = 10 };
|
||||||
|
enum { Patch = 0 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
28
externals/tracy/public/common/TracyYield.hpp
vendored
Normal file
28
externals/tracy/public/common/TracyYield.hpp
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef __TRACYYIELD_HPP__
|
||||||
|
#define __TRACYYIELD_HPP__
|
||||||
|
|
||||||
|
#if defined __SSE2__ || defined _M_AMD64 || (defined _M_IX86_FP && _M_IX86_FP == 2)
|
||||||
|
# include <emmintrin.h>
|
||||||
|
#else
|
||||||
|
# include <thread>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "TracyForceInline.hpp"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
static tracy_force_inline void YieldThread()
|
||||||
|
{
|
||||||
|
#if defined __SSE2__ || defined _M_AMD64 || (defined _M_IX86_FP && _M_IX86_FP == 2)
|
||||||
|
_mm_pause();
|
||||||
|
#elif defined __aarch64__
|
||||||
|
asm volatile( "isb" : : );
|
||||||
|
#else
|
||||||
|
std::this_thread::yield();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
2720
externals/tracy/public/common/tracy_lz4.cpp
vendored
Normal file
2720
externals/tracy/public/common/tracy_lz4.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
847
externals/tracy/public/common/tracy_lz4.hpp
vendored
Normal file
847
externals/tracy/public/common/tracy_lz4.hpp
vendored
Normal file
@ -0,0 +1,847 @@
|
|||||||
|
/*
|
||||||
|
* LZ4 - Fast LZ compression algorithm
|
||||||
|
* Header File
|
||||||
|
* Copyright (C) 2011-2020, Yann Collet.
|
||||||
|
|
||||||
|
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
You can contact the author at :
|
||||||
|
- LZ4 homepage : http://www.lz4.org
|
||||||
|
- LZ4 source repository : https://github.com/lz4/lz4
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TRACY_LZ4_H_2983827168210
|
||||||
|
#define TRACY_LZ4_H_2983827168210
|
||||||
|
|
||||||
|
/* --- Dependency --- */
|
||||||
|
#include <stddef.h> /* size_t */
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Introduction
|
||||||
|
|
||||||
|
LZ4 is lossless compression algorithm, providing compression speed >500 MB/s per core,
|
||||||
|
scalable with multi-cores CPU. It features an extremely fast decoder, with speed in
|
||||||
|
multiple GB/s per core, typically reaching RAM speed limits on multi-core systems.
|
||||||
|
|
||||||
|
The LZ4 compression library provides in-memory compression and decompression functions.
|
||||||
|
It gives full buffer control to user.
|
||||||
|
Compression can be done in:
|
||||||
|
- a single step (described as Simple Functions)
|
||||||
|
- a single step, reusing a context (described in Advanced Functions)
|
||||||
|
- unbounded multiple steps (described as Streaming compression)
|
||||||
|
|
||||||
|
lz4.h generates and decodes LZ4-compressed blocks (doc/lz4_Block_format.md).
|
||||||
|
Decompressing such a compressed block requires additional metadata.
|
||||||
|
Exact metadata depends on exact decompression function.
|
||||||
|
For the typical case of LZ4_decompress_safe(),
|
||||||
|
metadata includes block's compressed size, and maximum bound of decompressed size.
|
||||||
|
Each application is free to encode and pass such metadata in whichever way it wants.
|
||||||
|
|
||||||
|
lz4.h only handle blocks, it can not generate Frames.
|
||||||
|
|
||||||
|
Blocks are different from Frames (doc/lz4_Frame_format.md).
|
||||||
|
Frames bundle both blocks and metadata in a specified manner.
|
||||||
|
Embedding metadata is required for compressed data to be self-contained and portable.
|
||||||
|
Frame format is delivered through a companion API, declared in lz4frame.h.
|
||||||
|
The `lz4` CLI can only manage frames.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*^***************************************************************
|
||||||
|
* Export parameters
|
||||||
|
*****************************************************************/
|
||||||
|
/*
|
||||||
|
* LZ4_DLL_EXPORT :
|
||||||
|
* Enable exporting of functions when building a Windows DLL
|
||||||
|
* LZ4LIB_VISIBILITY :
|
||||||
|
* Control library symbols visibility.
|
||||||
|
*/
|
||||||
|
#ifndef LZ4LIB_VISIBILITY
|
||||||
|
# if defined(__GNUC__) && (__GNUC__ >= 4)
|
||||||
|
# define LZ4LIB_VISIBILITY __attribute__ ((visibility ("default")))
|
||||||
|
# else
|
||||||
|
# define LZ4LIB_VISIBILITY
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#if defined(LZ4_DLL_EXPORT) && (LZ4_DLL_EXPORT==1)
|
||||||
|
# define LZ4LIB_API __declspec(dllexport) LZ4LIB_VISIBILITY
|
||||||
|
#elif defined(LZ4_DLL_IMPORT) && (LZ4_DLL_IMPORT==1)
|
||||||
|
# define LZ4LIB_API __declspec(dllimport) LZ4LIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
|
||||||
|
#else
|
||||||
|
# define LZ4LIB_API LZ4LIB_VISIBILITY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! LZ4_FREESTANDING :
|
||||||
|
* When this macro is set to 1, it enables "freestanding mode" that is
|
||||||
|
* suitable for typical freestanding environment which doesn't support
|
||||||
|
* standard C library.
|
||||||
|
*
|
||||||
|
* - LZ4_FREESTANDING is a compile-time switch.
|
||||||
|
* - It requires the following macros to be defined:
|
||||||
|
* LZ4_memcpy, LZ4_memmove, LZ4_memset.
|
||||||
|
* - It only enables LZ4/HC functions which don't use heap.
|
||||||
|
* All LZ4F_* functions are not supported.
|
||||||
|
* - See tests/freestanding.c to check its basic setup.
|
||||||
|
*/
|
||||||
|
#if defined(LZ4_FREESTANDING) && (LZ4_FREESTANDING == 1)
|
||||||
|
# define LZ4_HEAPMODE 0
|
||||||
|
# define LZ4HC_HEAPMODE 0
|
||||||
|
# define LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION 1
|
||||||
|
# if !defined(LZ4_memcpy)
|
||||||
|
# error "LZ4_FREESTANDING requires macro 'LZ4_memcpy'."
|
||||||
|
# endif
|
||||||
|
# if !defined(LZ4_memset)
|
||||||
|
# error "LZ4_FREESTANDING requires macro 'LZ4_memset'."
|
||||||
|
# endif
|
||||||
|
# if !defined(LZ4_memmove)
|
||||||
|
# error "LZ4_FREESTANDING requires macro 'LZ4_memmove'."
|
||||||
|
# endif
|
||||||
|
#elif ! defined(LZ4_FREESTANDING)
|
||||||
|
# define LZ4_FREESTANDING 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*------ Version ------*/
|
||||||
|
#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */
|
||||||
|
#define LZ4_VERSION_MINOR 9 /* for new (non-breaking) interface capabilities */
|
||||||
|
#define LZ4_VERSION_RELEASE 4 /* for tweaks, bug-fixes, or development */
|
||||||
|
|
||||||
|
#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE)
|
||||||
|
|
||||||
|
#define LZ4_LIB_VERSION LZ4_VERSION_MAJOR.LZ4_VERSION_MINOR.LZ4_VERSION_RELEASE
|
||||||
|
#define LZ4_QUOTE(str) #str
|
||||||
|
#define LZ4_EXPAND_AND_QUOTE(str) LZ4_QUOTE(str)
|
||||||
|
#define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION) /* requires v1.7.3+ */
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
LZ4LIB_API int LZ4_versionNumber (void); /**< library version number; useful to check dll version; requires v1.3.0+ */
|
||||||
|
LZ4LIB_API const char* LZ4_versionString (void); /**< library version string; useful to check dll version; requires v1.7.5+ */
|
||||||
|
|
||||||
|
|
||||||
|
/*-************************************
|
||||||
|
* Tuning parameter
|
||||||
|
**************************************/
|
||||||
|
#define LZ4_MEMORY_USAGE_MIN 10
|
||||||
|
#define LZ4_MEMORY_USAGE_DEFAULT 14
|
||||||
|
#define LZ4_MEMORY_USAGE_MAX 20
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* LZ4_MEMORY_USAGE :
|
||||||
|
* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; )
|
||||||
|
* Increasing memory usage improves compression ratio, at the cost of speed.
|
||||||
|
* Reduced memory usage may improve speed at the cost of ratio, thanks to better cache locality.
|
||||||
|
* Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache
|
||||||
|
*/
|
||||||
|
#ifndef LZ4_MEMORY_USAGE
|
||||||
|
# define LZ4_MEMORY_USAGE LZ4_MEMORY_USAGE_DEFAULT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (LZ4_MEMORY_USAGE < LZ4_MEMORY_USAGE_MIN)
|
||||||
|
# error "LZ4_MEMORY_USAGE is too small !"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (LZ4_MEMORY_USAGE > LZ4_MEMORY_USAGE_MAX)
|
||||||
|
# error "LZ4_MEMORY_USAGE is too large !"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-************************************
|
||||||
|
* Simple Functions
|
||||||
|
**************************************/
|
||||||
|
/*! LZ4_compress_default() :
|
||||||
|
* Compresses 'srcSize' bytes from buffer 'src'
|
||||||
|
* into already allocated 'dst' buffer of size 'dstCapacity'.
|
||||||
|
* Compression is guaranteed to succeed if 'dstCapacity' >= LZ4_compressBound(srcSize).
|
||||||
|
* It also runs faster, so it's a recommended setting.
|
||||||
|
* If the function cannot compress 'src' into a more limited 'dst' budget,
|
||||||
|
* compression stops *immediately*, and the function result is zero.
|
||||||
|
* In which case, 'dst' content is undefined (invalid).
|
||||||
|
* srcSize : max supported value is LZ4_MAX_INPUT_SIZE.
|
||||||
|
* dstCapacity : size of buffer 'dst' (which must be already allocated)
|
||||||
|
* @return : the number of bytes written into buffer 'dst' (necessarily <= dstCapacity)
|
||||||
|
* or 0 if compression fails
|
||||||
|
* Note : This function is protected against buffer overflow scenarios (never writes outside 'dst' buffer, nor read outside 'source' buffer).
|
||||||
|
*/
|
||||||
|
LZ4LIB_API int LZ4_compress_default(const char* src, char* dst, int srcSize, int dstCapacity);
|
||||||
|
|
||||||
|
/*! LZ4_decompress_safe() :
|
||||||
|
* compressedSize : is the exact complete size of the compressed block.
|
||||||
|
* dstCapacity : is the size of destination buffer (which must be already allocated), presumed an upper bound of decompressed size.
|
||||||
|
* @return : the number of bytes decompressed into destination buffer (necessarily <= dstCapacity)
|
||||||
|
* If destination buffer is not large enough, decoding will stop and output an error code (negative value).
|
||||||
|
* If the source stream is detected malformed, the function will stop decoding and return a negative result.
|
||||||
|
* Note 1 : This function is protected against malicious data packets :
|
||||||
|
* it will never writes outside 'dst' buffer, nor read outside 'source' buffer,
|
||||||
|
* even if the compressed block is maliciously modified to order the decoder to do these actions.
|
||||||
|
* In such case, the decoder stops immediately, and considers the compressed block malformed.
|
||||||
|
* Note 2 : compressedSize and dstCapacity must be provided to the function, the compressed block does not contain them.
|
||||||
|
* The implementation is free to send / store / derive this information in whichever way is most beneficial.
|
||||||
|
* If there is a need for a different format which bundles together both compressed data and its metadata, consider looking at lz4frame.h instead.
|
||||||
|
*/
|
||||||
|
LZ4LIB_API int LZ4_decompress_safe (const char* src, char* dst, int compressedSize, int dstCapacity);
|
||||||
|
|
||||||
|
|
||||||
|
/*-************************************
|
||||||
|
* Advanced Functions
|
||||||
|
**************************************/
|
||||||
|
#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */
|
||||||
|
#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16)
|
||||||
|
|
||||||
|
/*! LZ4_compressBound() :
|
||||||
|
Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible)
|
||||||
|
This function is primarily useful for memory allocation purposes (destination buffer size).
|
||||||
|
Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example).
|
||||||
|
Note that LZ4_compress_default() compresses faster when dstCapacity is >= LZ4_compressBound(srcSize)
|
||||||
|
inputSize : max supported value is LZ4_MAX_INPUT_SIZE
|
||||||
|
return : maximum output size in a "worst case" scenario
|
||||||
|
or 0, if input size is incorrect (too large or negative)
|
||||||
|
*/
|
||||||
|
LZ4LIB_API int LZ4_compressBound(int inputSize);
|
||||||
|
|
||||||
|
/*! LZ4_compress_fast() :
|
||||||
|
Same as LZ4_compress_default(), but allows selection of "acceleration" factor.
|
||||||
|
The larger the acceleration value, the faster the algorithm, but also the lesser the compression.
|
||||||
|
It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed.
|
||||||
|
An acceleration value of "1" is the same as regular LZ4_compress_default()
|
||||||
|
Values <= 0 will be replaced by LZ4_ACCELERATION_DEFAULT (currently == 1, see lz4.c).
|
||||||
|
Values > LZ4_ACCELERATION_MAX will be replaced by LZ4_ACCELERATION_MAX (currently == 65537, see lz4.c).
|
||||||
|
*/
|
||||||
|
LZ4LIB_API int LZ4_compress_fast (const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
|
||||||
|
|
||||||
|
|
||||||
|
/*! LZ4_compress_fast_extState() :
|
||||||
|
* Same as LZ4_compress_fast(), using an externally allocated memory space for its state.
|
||||||
|
* Use LZ4_sizeofState() to know how much memory must be allocated,
|
||||||
|
* and allocate it on 8-bytes boundaries (using `malloc()` typically).
|
||||||
|
* Then, provide this buffer as `void* state` to compression function.
|
||||||
|
*/
|
||||||
|
LZ4LIB_API int LZ4_sizeofState(void);
|
||||||
|
LZ4LIB_API int LZ4_compress_fast_extState (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
|
||||||
|
|
||||||
|
|
||||||
|
/*! LZ4_compress_destSize() :
|
||||||
|
* Reverse the logic : compresses as much data as possible from 'src' buffer
|
||||||
|
* into already allocated buffer 'dst', of size >= 'targetDestSize'.
|
||||||
|
* This function either compresses the entire 'src' content into 'dst' if it's large enough,
|
||||||
|
* or fill 'dst' buffer completely with as much data as possible from 'src'.
|
||||||
|
* note: acceleration parameter is fixed to "default".
|
||||||
|
*
|
||||||
|
* *srcSizePtr : will be modified to indicate how many bytes where read from 'src' to fill 'dst'.
|
||||||
|
* New value is necessarily <= input value.
|
||||||
|
* @return : Nb bytes written into 'dst' (necessarily <= targetDestSize)
|
||||||
|
* or 0 if compression fails.
|
||||||
|
*
|
||||||
|
* Note : from v1.8.2 to v1.9.1, this function had a bug (fixed un v1.9.2+):
|
||||||
|
* the produced compressed content could, in specific circumstances,
|
||||||
|
* require to be decompressed into a destination buffer larger
|
||||||
|
* by at least 1 byte than the content to decompress.
|
||||||
|
* If an application uses `LZ4_compress_destSize()`,
|
||||||
|
* it's highly recommended to update liblz4 to v1.9.2 or better.
|
||||||
|
* If this can't be done or ensured,
|
||||||
|
* the receiving decompression function should provide
|
||||||
|
* a dstCapacity which is > decompressedSize, by at least 1 byte.
|
||||||
|
* See https://github.com/lz4/lz4/issues/859 for details
|
||||||
|
*/
|
||||||
|
LZ4LIB_API int LZ4_compress_destSize (const char* src, char* dst, int* srcSizePtr, int targetDstSize);
|
||||||
|
|
||||||
|
|
||||||
|
/*! LZ4_decompress_safe_partial() :
|
||||||
|
* Decompress an LZ4 compressed block, of size 'srcSize' at position 'src',
|
||||||
|
* into destination buffer 'dst' of size 'dstCapacity'.
|
||||||
|
* Up to 'targetOutputSize' bytes will be decoded.
|
||||||
|
* The function stops decoding on reaching this objective.
|
||||||
|
* This can be useful to boost performance
|
||||||
|
* whenever only the beginning of a block is required.
|
||||||
|
*
|
||||||
|
* @return : the number of bytes decoded in `dst` (necessarily <= targetOutputSize)
|
||||||
|
* If source stream is detected malformed, function returns a negative result.
|
||||||
|
*
|
||||||
|
* Note 1 : @return can be < targetOutputSize, if compressed block contains less data.
|
||||||
|
*
|
||||||
|
* Note 2 : targetOutputSize must be <= dstCapacity
|
||||||
|
*
|
||||||
|
* Note 3 : this function effectively stops decoding on reaching targetOutputSize,
|
||||||
|
* so dstCapacity is kind of redundant.
|
||||||
|
* This is because in older versions of this function,
|
||||||
|
* decoding operation would still write complete sequences.
|
||||||
|
* Therefore, there was no guarantee that it would stop writing at exactly targetOutputSize,
|
||||||
|
* it could write more bytes, though only up to dstCapacity.
|
||||||
|
* Some "margin" used to be required for this operation to work properly.
|
||||||
|
* Thankfully, this is no longer necessary.
|
||||||
|
* The function nonetheless keeps the same signature, in an effort to preserve API compatibility.
|
||||||
|
*
|
||||||
|
* Note 4 : If srcSize is the exact size of the block,
|
||||||
|
* then targetOutputSize can be any value,
|
||||||
|
* including larger than the block's decompressed size.
|
||||||
|
* The function will, at most, generate block's decompressed size.
|
||||||
|
*
|
||||||
|
* Note 5 : If srcSize is _larger_ than block's compressed size,
|
||||||
|
* then targetOutputSize **MUST** be <= block's decompressed size.
|
||||||
|
* Otherwise, *silent corruption will occur*.
|
||||||
|
*/
|
||||||
|
LZ4LIB_API int LZ4_decompress_safe_partial (const char* src, char* dst, int srcSize, int targetOutputSize, int dstCapacity);
|
||||||
|
|
||||||
|
|
||||||
|
/*-*********************************************
|
||||||
|
* Streaming Compression Functions
|
||||||
|
***********************************************/
|
||||||
|
typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */
|
||||||
|
|
||||||
|
/**
|
||||||
|
Note about RC_INVOKED
|
||||||
|
|
||||||
|
- RC_INVOKED is predefined symbol of rc.exe (the resource compiler which is part of MSVC/Visual Studio).
|
||||||
|
https://docs.microsoft.com/en-us/windows/win32/menurc/predefined-macros
|
||||||
|
|
||||||
|
- Since rc.exe is a legacy compiler, it truncates long symbol (> 30 chars)
|
||||||
|
and reports warning "RC4011: identifier truncated".
|
||||||
|
|
||||||
|
- To eliminate the warning, we surround long preprocessor symbol with
|
||||||
|
"#if !defined(RC_INVOKED) ... #endif" block that means
|
||||||
|
"skip this block when rc.exe is trying to read it".
|
||||||
|
*/
|
||||||
|
#if !defined(RC_INVOKED) /* https://docs.microsoft.com/en-us/windows/win32/menurc/predefined-macros */
|
||||||
|
#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION)
|
||||||
|
LZ4LIB_API LZ4_stream_t* LZ4_createStream(void);
|
||||||
|
LZ4LIB_API int LZ4_freeStream (LZ4_stream_t* streamPtr);
|
||||||
|
#endif /* !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! LZ4_resetStream_fast() : v1.9.0+
|
||||||
|
* Use this to prepare an LZ4_stream_t for a new chain of dependent blocks
|
||||||
|
* (e.g., LZ4_compress_fast_continue()).
|
||||||
|
*
|
||||||
|
* An LZ4_stream_t must be initialized once before usage.
|
||||||
|
* This is automatically done when created by LZ4_createStream().
|
||||||
|
* However, should the LZ4_stream_t be simply declared on stack (for example),
|
||||||
|
* it's necessary to initialize it first, using LZ4_initStream().
|
||||||
|
*
|
||||||
|
* After init, start any new stream with LZ4_resetStream_fast().
|
||||||
|
* A same LZ4_stream_t can be re-used multiple times consecutively
|
||||||
|
* and compress multiple streams,
|
||||||
|
* provided that it starts each new stream with LZ4_resetStream_fast().
|
||||||
|
*
|
||||||
|
* LZ4_resetStream_fast() is much faster than LZ4_initStream(),
|
||||||
|
* but is not compatible with memory regions containing garbage data.
|
||||||
|
*
|
||||||
|
* Note: it's only useful to call LZ4_resetStream_fast()
|
||||||
|
* in the context of streaming compression.
|
||||||
|
* The *extState* functions perform their own resets.
|
||||||
|
* Invoking LZ4_resetStream_fast() before is redundant, and even counterproductive.
|
||||||
|
*/
|
||||||
|
LZ4LIB_API void LZ4_resetStream_fast (LZ4_stream_t* streamPtr);
|
||||||
|
|
||||||
|
/*! LZ4_loadDict() :
|
||||||
|
* Use this function to reference a static dictionary into LZ4_stream_t.
|
||||||
|
* The dictionary must remain available during compression.
|
||||||
|
* LZ4_loadDict() triggers a reset, so any previous data will be forgotten.
|
||||||
|
* The same dictionary will have to be loaded on decompression side for successful decoding.
|
||||||
|
* Dictionary are useful for better compression of small data (KB range).
|
||||||
|
* While LZ4 accept any input as dictionary,
|
||||||
|
* results are generally better when using Zstandard's Dictionary Builder.
|
||||||
|
* Loading a size of 0 is allowed, and is the same as reset.
|
||||||
|
* @return : loaded dictionary size, in bytes (necessarily <= 64 KB)
|
||||||
|
*/
|
||||||
|
LZ4LIB_API int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize);
|
||||||
|
|
||||||
|
/*! LZ4_compress_fast_continue() :
|
||||||
|
* Compress 'src' content using data from previously compressed blocks, for better compression ratio.
|
||||||
|
* 'dst' buffer must be already allocated.
|
||||||
|
* If dstCapacity >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster.
|
||||||
|
*
|
||||||
|
* @return : size of compressed block
|
||||||
|
* or 0 if there is an error (typically, cannot fit into 'dst').
|
||||||
|
*
|
||||||
|
* Note 1 : Each invocation to LZ4_compress_fast_continue() generates a new block.
|
||||||
|
* Each block has precise boundaries.
|
||||||
|
* Each block must be decompressed separately, calling LZ4_decompress_*() with relevant metadata.
|
||||||
|
* It's not possible to append blocks together and expect a single invocation of LZ4_decompress_*() to decompress them together.
|
||||||
|
*
|
||||||
|
* Note 2 : The previous 64KB of source data is __assumed__ to remain present, unmodified, at same address in memory !
|
||||||
|
*
|
||||||
|
* Note 3 : When input is structured as a double-buffer, each buffer can have any size, including < 64 KB.
|
||||||
|
* Make sure that buffers are separated, by at least one byte.
|
||||||
|
* This construction ensures that each block only depends on previous block.
|
||||||
|
*
|
||||||
|
* Note 4 : If input buffer is a ring-buffer, it can have any size, including < 64 KB.
|
||||||
|
*
|
||||||
|
* Note 5 : After an error, the stream status is undefined (invalid), it can only be reset or freed.
|
||||||
|
*/
|
||||||
|
LZ4LIB_API int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
|
||||||
|
|
||||||
|
/*! LZ4_saveDict() :
|
||||||
|
* If last 64KB data cannot be guaranteed to remain available at its current memory location,
|
||||||
|
* save it into a safer place (char* safeBuffer).
|
||||||
|
* This is schematically equivalent to a memcpy() followed by LZ4_loadDict(),
|
||||||
|
* but is much faster, because LZ4_saveDict() doesn't need to rebuild tables.
|
||||||
|
* @return : saved dictionary size in bytes (necessarily <= maxDictSize), or 0 if error.
|
||||||
|
*/
|
||||||
|
LZ4LIB_API int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int maxDictSize);
|
||||||
|
|
||||||
|
|
||||||
|
/*-**********************************************
|
||||||
|
* Streaming Decompression Functions
|
||||||
|
* Bufferless synchronous API
|
||||||
|
************************************************/
|
||||||
|
typedef union LZ4_streamDecode_u LZ4_streamDecode_t; /* tracking context */
|
||||||
|
|
||||||
|
/*! LZ4_createStreamDecode() and LZ4_freeStreamDecode() :
|
||||||
|
* creation / destruction of streaming decompression tracking context.
|
||||||
|
* A tracking context can be re-used multiple times.
|
||||||
|
*/
|
||||||
|
#if !defined(RC_INVOKED) /* https://docs.microsoft.com/en-us/windows/win32/menurc/predefined-macros */
|
||||||
|
#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION)
|
||||||
|
LZ4LIB_API LZ4_streamDecode_t* LZ4_createStreamDecode(void);
|
||||||
|
LZ4LIB_API int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream);
|
||||||
|
#endif /* !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! LZ4_setStreamDecode() :
|
||||||
|
* An LZ4_streamDecode_t context can be allocated once and re-used multiple times.
|
||||||
|
* Use this function to start decompression of a new stream of blocks.
|
||||||
|
* A dictionary can optionally be set. Use NULL or size 0 for a reset order.
|
||||||
|
* Dictionary is presumed stable : it must remain accessible and unmodified during next decompression.
|
||||||
|
* @return : 1 if OK, 0 if error
|
||||||
|
*/
|
||||||
|
LZ4LIB_API int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize);
|
||||||
|
|
||||||
|
/*! LZ4_decoderRingBufferSize() : v1.8.2+
|
||||||
|
* Note : in a ring buffer scenario (optional),
|
||||||
|
* blocks are presumed decompressed next to each other
|
||||||
|
* up to the moment there is not enough remaining space for next block (remainingSize < maxBlockSize),
|
||||||
|
* at which stage it resumes from beginning of ring buffer.
|
||||||
|
* When setting such a ring buffer for streaming decompression,
|
||||||
|
* provides the minimum size of this ring buffer
|
||||||
|
* to be compatible with any source respecting maxBlockSize condition.
|
||||||
|
* @return : minimum ring buffer size,
|
||||||
|
* or 0 if there is an error (invalid maxBlockSize).
|
||||||
|
*/
|
||||||
|
LZ4LIB_API int LZ4_decoderRingBufferSize(int maxBlockSize);
|
||||||
|
#define LZ4_DECODER_RING_BUFFER_SIZE(maxBlockSize) (65536 + 14 + (maxBlockSize)) /* for static allocation; maxBlockSize presumed valid */
|
||||||
|
|
||||||
|
/*! LZ4_decompress_*_continue() :
|
||||||
|
* These decoding functions allow decompression of consecutive blocks in "streaming" mode.
|
||||||
|
* A block is an unsplittable entity, it must be presented entirely to a decompression function.
|
||||||
|
* Decompression functions only accepts one block at a time.
|
||||||
|
* The last 64KB of previously decoded data *must* remain available and unmodified at the memory position where they were decoded.
|
||||||
|
* If less than 64KB of data has been decoded, all the data must be present.
|
||||||
|
*
|
||||||
|
* Special : if decompression side sets a ring buffer, it must respect one of the following conditions :
|
||||||
|
* - Decompression buffer size is _at least_ LZ4_decoderRingBufferSize(maxBlockSize).
|
||||||
|
* maxBlockSize is the maximum size of any single block. It can have any value > 16 bytes.
|
||||||
|
* In which case, encoding and decoding buffers do not need to be synchronized.
|
||||||
|
* Actually, data can be produced by any source compliant with LZ4 format specification, and respecting maxBlockSize.
|
||||||
|
* - Synchronized mode :
|
||||||
|
* Decompression buffer size is _exactly_ the same as compression buffer size,
|
||||||
|
* and follows exactly same update rule (block boundaries at same positions),
|
||||||
|
* and decoding function is provided with exact decompressed size of each block (exception for last block of the stream),
|
||||||
|
* _then_ decoding & encoding ring buffer can have any size, including small ones ( < 64 KB).
|
||||||
|
* - Decompression buffer is larger than encoding buffer, by a minimum of maxBlockSize more bytes.
|
||||||
|
* In which case, encoding and decoding buffers do not need to be synchronized,
|
||||||
|
* and encoding ring buffer can have any size, including small ones ( < 64 KB).
|
||||||
|
*
|
||||||
|
* Whenever these conditions are not possible,
|
||||||
|
* save the last 64KB of decoded data into a safe buffer where it can't be modified during decompression,
|
||||||
|
* then indicate where this data is saved using LZ4_setStreamDecode(), before decompressing next block.
|
||||||
|
*/
|
||||||
|
LZ4LIB_API int
|
||||||
|
LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode,
|
||||||
|
const char* src, char* dst,
|
||||||
|
int srcSize, int dstCapacity);
|
||||||
|
|
||||||
|
|
||||||
|
/*! LZ4_decompress_*_usingDict() :
|
||||||
|
* These decoding functions work the same as
|
||||||
|
* a combination of LZ4_setStreamDecode() followed by LZ4_decompress_*_continue()
|
||||||
|
* They are stand-alone, and don't need an LZ4_streamDecode_t structure.
|
||||||
|
* Dictionary is presumed stable : it must remain accessible and unmodified during decompression.
|
||||||
|
* Performance tip : Decompression speed can be substantially increased
|
||||||
|
* when dst == dictStart + dictSize.
|
||||||
|
*/
|
||||||
|
LZ4LIB_API int
|
||||||
|
LZ4_decompress_safe_usingDict(const char* src, char* dst,
|
||||||
|
int srcSize, int dstCapacity,
|
||||||
|
const char* dictStart, int dictSize);
|
||||||
|
|
||||||
|
LZ4LIB_API int
|
||||||
|
LZ4_decompress_safe_partial_usingDict(const char* src, char* dst,
|
||||||
|
int compressedSize,
|
||||||
|
int targetOutputSize, int maxOutputSize,
|
||||||
|
const char* dictStart, int dictSize);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LZ4_H_2983827168210 */
|
||||||
|
|
||||||
|
|
||||||
|
/*^*************************************
|
||||||
|
* !!!!!! STATIC LINKING ONLY !!!!!!
|
||||||
|
***************************************/
|
||||||
|
|
||||||
|
/*-****************************************************************************
|
||||||
|
* Experimental section
|
||||||
|
*
|
||||||
|
* Symbols declared in this section must be considered unstable. Their
|
||||||
|
* signatures or semantics may change, or they may be removed altogether in the
|
||||||
|
* future. They are therefore only safe to depend on when the caller is
|
||||||
|
* statically linked against the library.
|
||||||
|
*
|
||||||
|
* To protect against unsafe usage, not only are the declarations guarded,
|
||||||
|
* the definitions are hidden by default
|
||||||
|
* when building LZ4 as a shared/dynamic library.
|
||||||
|
*
|
||||||
|
* In order to access these declarations,
|
||||||
|
* define LZ4_STATIC_LINKING_ONLY in your application
|
||||||
|
* before including LZ4's headers.
|
||||||
|
*
|
||||||
|
* In order to make their implementations accessible dynamically, you must
|
||||||
|
* define LZ4_PUBLISH_STATIC_FUNCTIONS when building the LZ4 library.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifdef LZ4_STATIC_LINKING_ONLY
|
||||||
|
|
||||||
|
#ifndef TRACY_LZ4_STATIC_3504398509
|
||||||
|
#define TRACY_LZ4_STATIC_3504398509
|
||||||
|
|
||||||
|
#ifdef LZ4_PUBLISH_STATIC_FUNCTIONS
|
||||||
|
#define LZ4LIB_STATIC_API LZ4LIB_API
|
||||||
|
#else
|
||||||
|
#define LZ4LIB_STATIC_API
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
/*! LZ4_compress_fast_extState_fastReset() :
|
||||||
|
* A variant of LZ4_compress_fast_extState().
|
||||||
|
*
|
||||||
|
* Using this variant avoids an expensive initialization step.
|
||||||
|
* It is only safe to call if the state buffer is known to be correctly initialized already
|
||||||
|
* (see above comment on LZ4_resetStream_fast() for a definition of "correctly initialized").
|
||||||
|
* From a high level, the difference is that
|
||||||
|
* this function initializes the provided state with a call to something like LZ4_resetStream_fast()
|
||||||
|
* while LZ4_compress_fast_extState() starts with a call to LZ4_resetStream().
|
||||||
|
*/
|
||||||
|
LZ4LIB_STATIC_API int LZ4_compress_fast_extState_fastReset (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
|
||||||
|
|
||||||
|
/*! LZ4_attach_dictionary() :
|
||||||
|
* This is an experimental API that allows
|
||||||
|
* efficient use of a static dictionary many times.
|
||||||
|
*
|
||||||
|
* Rather than re-loading the dictionary buffer into a working context before
|
||||||
|
* each compression, or copying a pre-loaded dictionary's LZ4_stream_t into a
|
||||||
|
* working LZ4_stream_t, this function introduces a no-copy setup mechanism,
|
||||||
|
* in which the working stream references the dictionary stream in-place.
|
||||||
|
*
|
||||||
|
* Several assumptions are made about the state of the dictionary stream.
|
||||||
|
* Currently, only streams which have been prepared by LZ4_loadDict() should
|
||||||
|
* be expected to work.
|
||||||
|
*
|
||||||
|
* Alternatively, the provided dictionaryStream may be NULL,
|
||||||
|
* in which case any existing dictionary stream is unset.
|
||||||
|
*
|
||||||
|
* If a dictionary is provided, it replaces any pre-existing stream history.
|
||||||
|
* The dictionary contents are the only history that can be referenced and
|
||||||
|
* logically immediately precede the data compressed in the first subsequent
|
||||||
|
* compression call.
|
||||||
|
*
|
||||||
|
* The dictionary will only remain attached to the working stream through the
|
||||||
|
* first compression call, at the end of which it is cleared. The dictionary
|
||||||
|
* stream (and source buffer) must remain in-place / accessible / unchanged
|
||||||
|
* through the completion of the first compression call on the stream.
|
||||||
|
*/
|
||||||
|
LZ4LIB_STATIC_API void
|
||||||
|
LZ4_attach_dictionary(LZ4_stream_t* workingStream,
|
||||||
|
const LZ4_stream_t* dictionaryStream);
|
||||||
|
|
||||||
|
|
||||||
|
/*! In-place compression and decompression
|
||||||
|
*
|
||||||
|
* It's possible to have input and output sharing the same buffer,
|
||||||
|
* for highly constrained memory environments.
|
||||||
|
* In both cases, it requires input to lay at the end of the buffer,
|
||||||
|
* and decompression to start at beginning of the buffer.
|
||||||
|
* Buffer size must feature some margin, hence be larger than final size.
|
||||||
|
*
|
||||||
|
* |<------------------------buffer--------------------------------->|
|
||||||
|
* |<-----------compressed data--------->|
|
||||||
|
* |<-----------decompressed size------------------>|
|
||||||
|
* |<----margin---->|
|
||||||
|
*
|
||||||
|
* This technique is more useful for decompression,
|
||||||
|
* since decompressed size is typically larger,
|
||||||
|
* and margin is short.
|
||||||
|
*
|
||||||
|
* In-place decompression will work inside any buffer
|
||||||
|
* which size is >= LZ4_DECOMPRESS_INPLACE_BUFFER_SIZE(decompressedSize).
|
||||||
|
* This presumes that decompressedSize > compressedSize.
|
||||||
|
* Otherwise, it means compression actually expanded data,
|
||||||
|
* and it would be more efficient to store such data with a flag indicating it's not compressed.
|
||||||
|
* This can happen when data is not compressible (already compressed, or encrypted).
|
||||||
|
*
|
||||||
|
* For in-place compression, margin is larger, as it must be able to cope with both
|
||||||
|
* history preservation, requiring input data to remain unmodified up to LZ4_DISTANCE_MAX,
|
||||||
|
* and data expansion, which can happen when input is not compressible.
|
||||||
|
* As a consequence, buffer size requirements are much higher,
|
||||||
|
* and memory savings offered by in-place compression are more limited.
|
||||||
|
*
|
||||||
|
* There are ways to limit this cost for compression :
|
||||||
|
* - Reduce history size, by modifying LZ4_DISTANCE_MAX.
|
||||||
|
* Note that it is a compile-time constant, so all compressions will apply this limit.
|
||||||
|
* Lower values will reduce compression ratio, except when input_size < LZ4_DISTANCE_MAX,
|
||||||
|
* so it's a reasonable trick when inputs are known to be small.
|
||||||
|
* - Require the compressor to deliver a "maximum compressed size".
|
||||||
|
* This is the `dstCapacity` parameter in `LZ4_compress*()`.
|
||||||
|
* When this size is < LZ4_COMPRESSBOUND(inputSize), then compression can fail,
|
||||||
|
* in which case, the return code will be 0 (zero).
|
||||||
|
* The caller must be ready for these cases to happen,
|
||||||
|
* and typically design a backup scheme to send data uncompressed.
|
||||||
|
* The combination of both techniques can significantly reduce
|
||||||
|
* the amount of margin required for in-place compression.
|
||||||
|
*
|
||||||
|
* In-place compression can work in any buffer
|
||||||
|
* which size is >= (maxCompressedSize)
|
||||||
|
* with maxCompressedSize == LZ4_COMPRESSBOUND(srcSize) for guaranteed compression success.
|
||||||
|
* LZ4_COMPRESS_INPLACE_BUFFER_SIZE() depends on both maxCompressedSize and LZ4_DISTANCE_MAX,
|
||||||
|
* so it's possible to reduce memory requirements by playing with them.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LZ4_DECOMPRESS_INPLACE_MARGIN(compressedSize) (((compressedSize) >> 8) + 32)
|
||||||
|
#define LZ4_DECOMPRESS_INPLACE_BUFFER_SIZE(decompressedSize) ((decompressedSize) + LZ4_DECOMPRESS_INPLACE_MARGIN(decompressedSize)) /**< note: presumes that compressedSize < decompressedSize. note2: margin is overestimated a bit, since it could use compressedSize instead */
|
||||||
|
|
||||||
|
#ifndef LZ4_DISTANCE_MAX /* history window size; can be user-defined at compile time */
|
||||||
|
# define LZ4_DISTANCE_MAX 65535 /* set to maximum value by default */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LZ4_COMPRESS_INPLACE_MARGIN (LZ4_DISTANCE_MAX + 32) /* LZ4_DISTANCE_MAX can be safely replaced by srcSize when it's smaller */
|
||||||
|
#define LZ4_COMPRESS_INPLACE_BUFFER_SIZE(maxCompressedSize) ((maxCompressedSize) + LZ4_COMPRESS_INPLACE_MARGIN) /**< maxCompressedSize is generally LZ4_COMPRESSBOUND(inputSize), but can be set to any lower value, with the risk that compression can fail (return code 0(zero)) */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LZ4_STATIC_3504398509 */
|
||||||
|
#endif /* LZ4_STATIC_LINKING_ONLY */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TRACY_LZ4_H_98237428734687
|
||||||
|
#define TRACY_LZ4_H_98237428734687
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
/*-************************************************************
|
||||||
|
* Private Definitions
|
||||||
|
**************************************************************
|
||||||
|
* Do not use these definitions directly.
|
||||||
|
* They are only exposed to allow static allocation of `LZ4_stream_t` and `LZ4_streamDecode_t`.
|
||||||
|
* Accessing members will expose user code to API and/or ABI break in future versions of the library.
|
||||||
|
**************************************************************/
|
||||||
|
#define LZ4_HASHLOG (LZ4_MEMORY_USAGE-2)
|
||||||
|
#define LZ4_HASHTABLESIZE (1 << LZ4_MEMORY_USAGE)
|
||||||
|
#define LZ4_HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */
|
||||||
|
|
||||||
|
#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
||||||
|
typedef int8_t LZ4_i8;
|
||||||
|
typedef uint8_t LZ4_byte;
|
||||||
|
typedef uint16_t LZ4_u16;
|
||||||
|
typedef uint32_t LZ4_u32;
|
||||||
|
#else
|
||||||
|
typedef signed char LZ4_i8;
|
||||||
|
typedef unsigned char LZ4_byte;
|
||||||
|
typedef unsigned short LZ4_u16;
|
||||||
|
typedef unsigned int LZ4_u32;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! LZ4_stream_t :
|
||||||
|
* Never ever use below internal definitions directly !
|
||||||
|
* These definitions are not API/ABI safe, and may change in future versions.
|
||||||
|
* If you need static allocation, declare or allocate an LZ4_stream_t object.
|
||||||
|
**/
|
||||||
|
|
||||||
|
typedef struct LZ4_stream_t_internal LZ4_stream_t_internal;
|
||||||
|
struct LZ4_stream_t_internal {
|
||||||
|
LZ4_u32 hashTable[LZ4_HASH_SIZE_U32];
|
||||||
|
const LZ4_byte* dictionary;
|
||||||
|
const LZ4_stream_t_internal* dictCtx;
|
||||||
|
LZ4_u32 currentOffset;
|
||||||
|
LZ4_u32 tableType;
|
||||||
|
LZ4_u32 dictSize;
|
||||||
|
/* Implicit padding to ensure structure is aligned */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LZ4_STREAM_MINSIZE ((1UL << LZ4_MEMORY_USAGE) + 32) /* static size, for inter-version compatibility */
|
||||||
|
union LZ4_stream_u {
|
||||||
|
char minStateSize[LZ4_STREAM_MINSIZE];
|
||||||
|
LZ4_stream_t_internal internal_donotuse;
|
||||||
|
}; /* previously typedef'd to LZ4_stream_t */
|
||||||
|
|
||||||
|
|
||||||
|
/*! LZ4_initStream() : v1.9.0+
|
||||||
|
* An LZ4_stream_t structure must be initialized at least once.
|
||||||
|
* This is automatically done when invoking LZ4_createStream(),
|
||||||
|
* but it's not when the structure is simply declared on stack (for example).
|
||||||
|
*
|
||||||
|
* Use LZ4_initStream() to properly initialize a newly declared LZ4_stream_t.
|
||||||
|
* It can also initialize any arbitrary buffer of sufficient size,
|
||||||
|
* and will @return a pointer of proper type upon initialization.
|
||||||
|
*
|
||||||
|
* Note : initialization fails if size and alignment conditions are not respected.
|
||||||
|
* In which case, the function will @return NULL.
|
||||||
|
* Note2: An LZ4_stream_t structure guarantees correct alignment and size.
|
||||||
|
* Note3: Before v1.9.0, use LZ4_resetStream() instead
|
||||||
|
**/
|
||||||
|
LZ4LIB_API LZ4_stream_t* LZ4_initStream (void* buffer, size_t size);
|
||||||
|
|
||||||
|
|
||||||
|
/*! LZ4_streamDecode_t :
|
||||||
|
* Never ever use below internal definitions directly !
|
||||||
|
* These definitions are not API/ABI safe, and may change in future versions.
|
||||||
|
* If you need static allocation, declare or allocate an LZ4_streamDecode_t object.
|
||||||
|
**/
|
||||||
|
typedef struct {
|
||||||
|
const LZ4_byte* externalDict;
|
||||||
|
const LZ4_byte* prefixEnd;
|
||||||
|
size_t extDictSize;
|
||||||
|
size_t prefixSize;
|
||||||
|
} LZ4_streamDecode_t_internal;
|
||||||
|
|
||||||
|
#define LZ4_STREAMDECODE_MINSIZE 32
|
||||||
|
union LZ4_streamDecode_u {
|
||||||
|
char minStateSize[LZ4_STREAMDECODE_MINSIZE];
|
||||||
|
LZ4_streamDecode_t_internal internal_donotuse;
|
||||||
|
} ; /* previously typedef'd to LZ4_streamDecode_t */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-************************************
|
||||||
|
* Obsolete Functions
|
||||||
|
**************************************/
|
||||||
|
|
||||||
|
/*! Deprecation warnings
|
||||||
|
*
|
||||||
|
* Deprecated functions make the compiler generate a warning when invoked.
|
||||||
|
* This is meant to invite users to update their source code.
|
||||||
|
* Should deprecation warnings be a problem, it is generally possible to disable them,
|
||||||
|
* typically with -Wno-deprecated-declarations for gcc
|
||||||
|
* or _CRT_SECURE_NO_WARNINGS in Visual.
|
||||||
|
*
|
||||||
|
* Another method is to define LZ4_DISABLE_DEPRECATE_WARNINGS
|
||||||
|
* before including the header file.
|
||||||
|
*/
|
||||||
|
#ifdef LZ4_DISABLE_DEPRECATE_WARNINGS
|
||||||
|
# define LZ4_DEPRECATED(message) /* disable deprecation warnings */
|
||||||
|
#else
|
||||||
|
# if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */
|
||||||
|
# define LZ4_DEPRECATED(message) [[deprecated(message)]]
|
||||||
|
# elif defined(_MSC_VER)
|
||||||
|
# define LZ4_DEPRECATED(message) __declspec(deprecated(message))
|
||||||
|
# elif defined(__clang__) || (defined(__GNUC__) && (__GNUC__ * 10 + __GNUC_MINOR__ >= 45))
|
||||||
|
# define LZ4_DEPRECATED(message) __attribute__((deprecated(message)))
|
||||||
|
# elif defined(__GNUC__) && (__GNUC__ * 10 + __GNUC_MINOR__ >= 31)
|
||||||
|
# define LZ4_DEPRECATED(message) __attribute__((deprecated))
|
||||||
|
# else
|
||||||
|
# pragma message("WARNING: LZ4_DEPRECATED needs custom implementation for this compiler")
|
||||||
|
# define LZ4_DEPRECATED(message) /* disabled */
|
||||||
|
# endif
|
||||||
|
#endif /* LZ4_DISABLE_DEPRECATE_WARNINGS */
|
||||||
|
|
||||||
|
/*! Obsolete compression functions (since v1.7.3) */
|
||||||
|
LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress (const char* src, char* dest, int srcSize);
|
||||||
|
LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress_limitedOutput (const char* src, char* dest, int srcSize, int maxOutputSize);
|
||||||
|
LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize);
|
||||||
|
LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize);
|
||||||
|
LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize);
|
||||||
|
LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
|
||||||
|
|
||||||
|
/*! Obsolete decompression functions (since v1.8.0) */
|
||||||
|
LZ4_DEPRECATED("use LZ4_decompress_fast() instead") LZ4LIB_API int LZ4_uncompress (const char* source, char* dest, int outputSize);
|
||||||
|
LZ4_DEPRECATED("use LZ4_decompress_safe() instead") LZ4LIB_API int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize);
|
||||||
|
|
||||||
|
/* Obsolete streaming functions (since v1.7.0)
|
||||||
|
* degraded functionality; do not use!
|
||||||
|
*
|
||||||
|
* In order to perform streaming compression, these functions depended on data
|
||||||
|
* that is no longer tracked in the state. They have been preserved as well as
|
||||||
|
* possible: using them will still produce a correct output. However, they don't
|
||||||
|
* actually retain any history between compression calls. The compression ratio
|
||||||
|
* achieved will therefore be no better than compressing each chunk
|
||||||
|
* independently.
|
||||||
|
*/
|
||||||
|
LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API void* LZ4_create (char* inputBuffer);
|
||||||
|
LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API int LZ4_sizeofStreamState(void);
|
||||||
|
LZ4_DEPRECATED("Use LZ4_resetStream() instead") LZ4LIB_API int LZ4_resetStreamState(void* state, char* inputBuffer);
|
||||||
|
LZ4_DEPRECATED("Use LZ4_saveDict() instead") LZ4LIB_API char* LZ4_slideInputBuffer (void* state);
|
||||||
|
|
||||||
|
/*! Obsolete streaming decoding functions (since v1.7.0) */
|
||||||
|
LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") LZ4LIB_API int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize);
|
||||||
|
LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") LZ4LIB_API int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize);
|
||||||
|
|
||||||
|
/*! Obsolete LZ4_decompress_fast variants (since v1.9.0) :
|
||||||
|
* These functions used to be faster than LZ4_decompress_safe(),
|
||||||
|
* but this is no longer the case. They are now slower.
|
||||||
|
* This is because LZ4_decompress_fast() doesn't know the input size,
|
||||||
|
* and therefore must progress more cautiously into the input buffer to not read beyond the end of block.
|
||||||
|
* On top of that `LZ4_decompress_fast()` is not protected vs malformed or malicious inputs, making it a security liability.
|
||||||
|
* As a consequence, LZ4_decompress_fast() is strongly discouraged, and deprecated.
|
||||||
|
*
|
||||||
|
* The last remaining LZ4_decompress_fast() specificity is that
|
||||||
|
* it can decompress a block without knowing its compressed size.
|
||||||
|
* Such functionality can be achieved in a more secure manner
|
||||||
|
* by employing LZ4_decompress_safe_partial().
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* originalSize : is the uncompressed size to regenerate.
|
||||||
|
* `dst` must be already allocated, its size must be >= 'originalSize' bytes.
|
||||||
|
* @return : number of bytes read from source buffer (== compressed size).
|
||||||
|
* The function expects to finish at block's end exactly.
|
||||||
|
* If the source stream is detected malformed, the function stops decoding and returns a negative result.
|
||||||
|
* note : LZ4_decompress_fast*() requires originalSize. Thanks to this information, it never writes past the output buffer.
|
||||||
|
* However, since it doesn't know its 'src' size, it may read an unknown amount of input, past input buffer bounds.
|
||||||
|
* Also, since match offsets are not validated, match reads from 'src' may underflow too.
|
||||||
|
* These issues never happen if input (compressed) data is correct.
|
||||||
|
* But they may happen if input data is invalid (error or intentional tampering).
|
||||||
|
* As a consequence, use these functions in trusted environments with trusted data **only**.
|
||||||
|
*/
|
||||||
|
LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe() instead")
|
||||||
|
LZ4LIB_API int LZ4_decompress_fast (const char* src, char* dst, int originalSize);
|
||||||
|
LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_continue() instead")
|
||||||
|
LZ4LIB_API int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int originalSize);
|
||||||
|
LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_usingDict() instead")
|
||||||
|
LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* src, char* dst, int originalSize, const char* dictStart, int dictSize);
|
||||||
|
|
||||||
|
/*! LZ4_resetStream() :
|
||||||
|
* An LZ4_stream_t structure must be initialized at least once.
|
||||||
|
* This is done with LZ4_initStream(), or LZ4_resetStream().
|
||||||
|
* Consider switching to LZ4_initStream(),
|
||||||
|
* invoking LZ4_resetStream() will trigger deprecation warnings in the future.
|
||||||
|
*/
|
||||||
|
LZ4LIB_API void LZ4_resetStream (LZ4_stream_t* streamPtr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LZ4_H_98237428734687 */
|
1636
externals/tracy/public/common/tracy_lz4hc.cpp
vendored
Normal file
1636
externals/tracy/public/common/tracy_lz4hc.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
405
externals/tracy/public/common/tracy_lz4hc.hpp
vendored
Normal file
405
externals/tracy/public/common/tracy_lz4hc.hpp
vendored
Normal file
@ -0,0 +1,405 @@
|
|||||||
|
/*
|
||||||
|
LZ4 HC - High Compression Mode of LZ4
|
||||||
|
Header File
|
||||||
|
Copyright (C) 2011-2020, Yann Collet.
|
||||||
|
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
You can contact the author at :
|
||||||
|
- LZ4 source repository : https://github.com/lz4/lz4
|
||||||
|
- LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
|
||||||
|
*/
|
||||||
|
#ifndef TRACY_LZ4_HC_H_19834876238432
|
||||||
|
#define TRACY_LZ4_HC_H_19834876238432
|
||||||
|
|
||||||
|
/* --- Dependency --- */
|
||||||
|
/* note : lz4hc requires lz4.h/lz4.c for compilation */
|
||||||
|
#include "tracy_lz4.hpp" /* stddef, LZ4LIB_API, LZ4_DEPRECATED */
|
||||||
|
|
||||||
|
|
||||||
|
/* --- Useful constants --- */
|
||||||
|
#define LZ4HC_CLEVEL_MIN 3
|
||||||
|
#define LZ4HC_CLEVEL_DEFAULT 9
|
||||||
|
#define LZ4HC_CLEVEL_OPT_MIN 10
|
||||||
|
#define LZ4HC_CLEVEL_MAX 12
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
/*-************************************
|
||||||
|
* Block Compression
|
||||||
|
**************************************/
|
||||||
|
/*! LZ4_compress_HC() :
|
||||||
|
* Compress data from `src` into `dst`, using the powerful but slower "HC" algorithm.
|
||||||
|
* `dst` must be already allocated.
|
||||||
|
* Compression is guaranteed to succeed if `dstCapacity >= LZ4_compressBound(srcSize)` (see "lz4.h")
|
||||||
|
* Max supported `srcSize` value is LZ4_MAX_INPUT_SIZE (see "lz4.h")
|
||||||
|
* `compressionLevel` : any value between 1 and LZ4HC_CLEVEL_MAX will work.
|
||||||
|
* Values > LZ4HC_CLEVEL_MAX behave the same as LZ4HC_CLEVEL_MAX.
|
||||||
|
* @return : the number of bytes written into 'dst'
|
||||||
|
* or 0 if compression fails.
|
||||||
|
*/
|
||||||
|
LZ4LIB_API int LZ4_compress_HC (const char* src, char* dst, int srcSize, int dstCapacity, int compressionLevel);
|
||||||
|
|
||||||
|
|
||||||
|
/* Note :
|
||||||
|
* Decompression functions are provided within "lz4.h" (BSD license)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*! LZ4_compress_HC_extStateHC() :
|
||||||
|
* Same as LZ4_compress_HC(), but using an externally allocated memory segment for `state`.
|
||||||
|
* `state` size is provided by LZ4_sizeofStateHC().
|
||||||
|
* Memory segment must be aligned on 8-bytes boundaries (which a normal malloc() should do properly).
|
||||||
|
*/
|
||||||
|
LZ4LIB_API int LZ4_sizeofStateHC(void);
|
||||||
|
LZ4LIB_API int LZ4_compress_HC_extStateHC(void* stateHC, const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel);
|
||||||
|
|
||||||
|
|
||||||
|
/*! LZ4_compress_HC_destSize() : v1.9.0+
|
||||||
|
* Will compress as much data as possible from `src`
|
||||||
|
* to fit into `targetDstSize` budget.
|
||||||
|
* Result is provided in 2 parts :
|
||||||
|
* @return : the number of bytes written into 'dst' (necessarily <= targetDstSize)
|
||||||
|
* or 0 if compression fails.
|
||||||
|
* `srcSizePtr` : on success, *srcSizePtr is updated to indicate how much bytes were read from `src`
|
||||||
|
*/
|
||||||
|
LZ4LIB_API int LZ4_compress_HC_destSize(void* stateHC,
|
||||||
|
const char* src, char* dst,
|
||||||
|
int* srcSizePtr, int targetDstSize,
|
||||||
|
int compressionLevel);
|
||||||
|
|
||||||
|
|
||||||
|
/*-************************************
|
||||||
|
* Streaming Compression
|
||||||
|
* Bufferless synchronous API
|
||||||
|
**************************************/
|
||||||
|
typedef union LZ4_streamHC_u LZ4_streamHC_t; /* incomplete type (defined later) */
|
||||||
|
|
||||||
|
/*! LZ4_createStreamHC() and LZ4_freeStreamHC() :
|
||||||
|
* These functions create and release memory for LZ4 HC streaming state.
|
||||||
|
* Newly created states are automatically initialized.
|
||||||
|
* A same state can be used multiple times consecutively,
|
||||||
|
* starting with LZ4_resetStreamHC_fast() to start a new stream of blocks.
|
||||||
|
*/
|
||||||
|
LZ4LIB_API LZ4_streamHC_t* LZ4_createStreamHC(void);
|
||||||
|
LZ4LIB_API int LZ4_freeStreamHC (LZ4_streamHC_t* streamHCPtr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
These functions compress data in successive blocks of any size,
|
||||||
|
using previous blocks as dictionary, to improve compression ratio.
|
||||||
|
One key assumption is that previous blocks (up to 64 KB) remain read-accessible while compressing next blocks.
|
||||||
|
There is an exception for ring buffers, which can be smaller than 64 KB.
|
||||||
|
Ring-buffer scenario is automatically detected and handled within LZ4_compress_HC_continue().
|
||||||
|
|
||||||
|
Before starting compression, state must be allocated and properly initialized.
|
||||||
|
LZ4_createStreamHC() does both, though compression level is set to LZ4HC_CLEVEL_DEFAULT.
|
||||||
|
|
||||||
|
Selecting the compression level can be done with LZ4_resetStreamHC_fast() (starts a new stream)
|
||||||
|
or LZ4_setCompressionLevel() (anytime, between blocks in the same stream) (experimental).
|
||||||
|
LZ4_resetStreamHC_fast() only works on states which have been properly initialized at least once,
|
||||||
|
which is automatically the case when state is created using LZ4_createStreamHC().
|
||||||
|
|
||||||
|
After reset, a first "fictional block" can be designated as initial dictionary,
|
||||||
|
using LZ4_loadDictHC() (Optional).
|
||||||
|
|
||||||
|
Invoke LZ4_compress_HC_continue() to compress each successive block.
|
||||||
|
The number of blocks is unlimited.
|
||||||
|
Previous input blocks, including initial dictionary when present,
|
||||||
|
must remain accessible and unmodified during compression.
|
||||||
|
|
||||||
|
It's allowed to update compression level anytime between blocks,
|
||||||
|
using LZ4_setCompressionLevel() (experimental).
|
||||||
|
|
||||||
|
'dst' buffer should be sized to handle worst case scenarios
|
||||||
|
(see LZ4_compressBound(), it ensures compression success).
|
||||||
|
In case of failure, the API does not guarantee recovery,
|
||||||
|
so the state _must_ be reset.
|
||||||
|
To ensure compression success
|
||||||
|
whenever `dst` buffer size cannot be made >= LZ4_compressBound(),
|
||||||
|
consider using LZ4_compress_HC_continue_destSize().
|
||||||
|
|
||||||
|
Whenever previous input blocks can't be preserved unmodified in-place during compression of next blocks,
|
||||||
|
it's possible to copy the last blocks into a more stable memory space, using LZ4_saveDictHC().
|
||||||
|
Return value of LZ4_saveDictHC() is the size of dictionary effectively saved into 'safeBuffer' (<= 64 KB)
|
||||||
|
|
||||||
|
After completing a streaming compression,
|
||||||
|
it's possible to start a new stream of blocks, using the same LZ4_streamHC_t state,
|
||||||
|
just by resetting it, using LZ4_resetStreamHC_fast().
|
||||||
|
*/
|
||||||
|
|
||||||
|
LZ4LIB_API void LZ4_resetStreamHC_fast(LZ4_streamHC_t* streamHCPtr, int compressionLevel); /* v1.9.0+ */
|
||||||
|
LZ4LIB_API int LZ4_loadDictHC (LZ4_streamHC_t* streamHCPtr, const char* dictionary, int dictSize);
|
||||||
|
|
||||||
|
LZ4LIB_API int LZ4_compress_HC_continue (LZ4_streamHC_t* streamHCPtr,
|
||||||
|
const char* src, char* dst,
|
||||||
|
int srcSize, int maxDstSize);
|
||||||
|
|
||||||
|
/*! LZ4_compress_HC_continue_destSize() : v1.9.0+
|
||||||
|
* Similar to LZ4_compress_HC_continue(),
|
||||||
|
* but will read as much data as possible from `src`
|
||||||
|
* to fit into `targetDstSize` budget.
|
||||||
|
* Result is provided into 2 parts :
|
||||||
|
* @return : the number of bytes written into 'dst' (necessarily <= targetDstSize)
|
||||||
|
* or 0 if compression fails.
|
||||||
|
* `srcSizePtr` : on success, *srcSizePtr will be updated to indicate how much bytes were read from `src`.
|
||||||
|
* Note that this function may not consume the entire input.
|
||||||
|
*/
|
||||||
|
LZ4LIB_API int LZ4_compress_HC_continue_destSize(LZ4_streamHC_t* LZ4_streamHCPtr,
|
||||||
|
const char* src, char* dst,
|
||||||
|
int* srcSizePtr, int targetDstSize);
|
||||||
|
|
||||||
|
LZ4LIB_API int LZ4_saveDictHC (LZ4_streamHC_t* streamHCPtr, char* safeBuffer, int maxDictSize);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*^**********************************************
|
||||||
|
* !!!!!! STATIC LINKING ONLY !!!!!!
|
||||||
|
***********************************************/
|
||||||
|
|
||||||
|
/*-******************************************************************
|
||||||
|
* PRIVATE DEFINITIONS :
|
||||||
|
* Do not use these definitions directly.
|
||||||
|
* They are merely exposed to allow static allocation of `LZ4_streamHC_t`.
|
||||||
|
* Declare an `LZ4_streamHC_t` directly, rather than any type below.
|
||||||
|
* Even then, only do so in the context of static linking, as definitions may change between versions.
|
||||||
|
********************************************************************/
|
||||||
|
|
||||||
|
#define LZ4HC_DICTIONARY_LOGSIZE 16
|
||||||
|
#define LZ4HC_MAXD (1<<LZ4HC_DICTIONARY_LOGSIZE)
|
||||||
|
#define LZ4HC_MAXD_MASK (LZ4HC_MAXD - 1)
|
||||||
|
|
||||||
|
#define LZ4HC_HASH_LOG 15
|
||||||
|
#define LZ4HC_HASHTABLESIZE (1 << LZ4HC_HASH_LOG)
|
||||||
|
#define LZ4HC_HASH_MASK (LZ4HC_HASHTABLESIZE - 1)
|
||||||
|
|
||||||
|
|
||||||
|
/* Never ever use these definitions directly !
|
||||||
|
* Declare or allocate an LZ4_streamHC_t instead.
|
||||||
|
**/
|
||||||
|
typedef struct LZ4HC_CCtx_internal LZ4HC_CCtx_internal;
|
||||||
|
struct LZ4HC_CCtx_internal
|
||||||
|
{
|
||||||
|
LZ4_u32 hashTable[LZ4HC_HASHTABLESIZE];
|
||||||
|
LZ4_u16 chainTable[LZ4HC_MAXD];
|
||||||
|
const LZ4_byte* end; /* next block here to continue on current prefix */
|
||||||
|
const LZ4_byte* prefixStart; /* Indexes relative to this position */
|
||||||
|
const LZ4_byte* dictStart; /* alternate reference for extDict */
|
||||||
|
LZ4_u32 dictLimit; /* below that point, need extDict */
|
||||||
|
LZ4_u32 lowLimit; /* below that point, no more dict */
|
||||||
|
LZ4_u32 nextToUpdate; /* index from which to continue dictionary update */
|
||||||
|
short compressionLevel;
|
||||||
|
LZ4_i8 favorDecSpeed; /* favor decompression speed if this flag set,
|
||||||
|
otherwise, favor compression ratio */
|
||||||
|
LZ4_i8 dirty; /* stream has to be fully reset if this flag is set */
|
||||||
|
const LZ4HC_CCtx_internal* dictCtx;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LZ4_STREAMHC_MINSIZE 262200 /* static size, for inter-version compatibility */
|
||||||
|
union LZ4_streamHC_u {
|
||||||
|
char minStateSize[LZ4_STREAMHC_MINSIZE];
|
||||||
|
LZ4HC_CCtx_internal internal_donotuse;
|
||||||
|
}; /* previously typedef'd to LZ4_streamHC_t */
|
||||||
|
|
||||||
|
/* LZ4_streamHC_t :
|
||||||
|
* This structure allows static allocation of LZ4 HC streaming state.
|
||||||
|
* This can be used to allocate statically on stack, or as part of a larger structure.
|
||||||
|
*
|
||||||
|
* Such state **must** be initialized using LZ4_initStreamHC() before first use.
|
||||||
|
*
|
||||||
|
* Note that invoking LZ4_initStreamHC() is not required when
|
||||||
|
* the state was created using LZ4_createStreamHC() (which is recommended).
|
||||||
|
* Using the normal builder, a newly created state is automatically initialized.
|
||||||
|
*
|
||||||
|
* Static allocation shall only be used in combination with static linking.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* LZ4_initStreamHC() : v1.9.0+
|
||||||
|
* Required before first use of a statically allocated LZ4_streamHC_t.
|
||||||
|
* Before v1.9.0 : use LZ4_resetStreamHC() instead
|
||||||
|
*/
|
||||||
|
LZ4LIB_API LZ4_streamHC_t* LZ4_initStreamHC(void* buffer, size_t size);
|
||||||
|
|
||||||
|
|
||||||
|
/*-************************************
|
||||||
|
* Deprecated Functions
|
||||||
|
**************************************/
|
||||||
|
/* see lz4.h LZ4_DISABLE_DEPRECATE_WARNINGS to turn off deprecation warnings */
|
||||||
|
|
||||||
|
/* deprecated compression functions */
|
||||||
|
LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC (const char* source, char* dest, int inputSize);
|
||||||
|
LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize);
|
||||||
|
LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC2 (const char* source, char* dest, int inputSize, int compressionLevel);
|
||||||
|
LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC2_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
|
||||||
|
LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC_withStateHC (void* state, const char* source, char* dest, int inputSize);
|
||||||
|
LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC_limitedOutput_withStateHC (void* state, const char* source, char* dest, int inputSize, int maxOutputSize);
|
||||||
|
LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC2_withStateHC (void* state, const char* source, char* dest, int inputSize, int compressionLevel);
|
||||||
|
LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC2_limitedOutput_withStateHC(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
|
||||||
|
LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize);
|
||||||
|
LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
|
||||||
|
|
||||||
|
/* Obsolete streaming functions; degraded functionality; do not use!
|
||||||
|
*
|
||||||
|
* In order to perform streaming compression, these functions depended on data
|
||||||
|
* that is no longer tracked in the state. They have been preserved as well as
|
||||||
|
* possible: using them will still produce a correct output. However, use of
|
||||||
|
* LZ4_slideInputBufferHC() will truncate the history of the stream, rather
|
||||||
|
* than preserve a window-sized chunk of history.
|
||||||
|
*/
|
||||||
|
#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION)
|
||||||
|
LZ4_DEPRECATED("use LZ4_createStreamHC() instead") LZ4LIB_API void* LZ4_createHC (const char* inputBuffer);
|
||||||
|
LZ4_DEPRECATED("use LZ4_freeStreamHC() instead") LZ4LIB_API int LZ4_freeHC (void* LZ4HC_Data);
|
||||||
|
#endif
|
||||||
|
LZ4_DEPRECATED("use LZ4_saveDictHC() instead") LZ4LIB_API char* LZ4_slideInputBufferHC (void* LZ4HC_Data);
|
||||||
|
LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel);
|
||||||
|
LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
|
||||||
|
LZ4_DEPRECATED("use LZ4_createStreamHC() instead") LZ4LIB_API int LZ4_sizeofStreamStateHC(void);
|
||||||
|
LZ4_DEPRECATED("use LZ4_initStreamHC() instead") LZ4LIB_API int LZ4_resetStreamStateHC(void* state, char* inputBuffer);
|
||||||
|
|
||||||
|
|
||||||
|
/* LZ4_resetStreamHC() is now replaced by LZ4_initStreamHC().
|
||||||
|
* The intention is to emphasize the difference with LZ4_resetStreamHC_fast(),
|
||||||
|
* which is now the recommended function to start a new stream of blocks,
|
||||||
|
* but cannot be used to initialize a memory segment containing arbitrary garbage data.
|
||||||
|
*
|
||||||
|
* It is recommended to switch to LZ4_initStreamHC().
|
||||||
|
* LZ4_resetStreamHC() will generate deprecation warnings in a future version.
|
||||||
|
*/
|
||||||
|
LZ4LIB_API void LZ4_resetStreamHC (LZ4_streamHC_t* streamHCPtr, int compressionLevel);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LZ4_HC_H_19834876238432 */
|
||||||
|
|
||||||
|
|
||||||
|
/*-**************************************************
|
||||||
|
* !!!!! STATIC LINKING ONLY !!!!!
|
||||||
|
* Following definitions are considered experimental.
|
||||||
|
* They should not be linked from DLL,
|
||||||
|
* as there is no guarantee of API stability yet.
|
||||||
|
* Prototypes will be promoted to "stable" status
|
||||||
|
* after successful usage in real-life scenarios.
|
||||||
|
***************************************************/
|
||||||
|
#ifdef LZ4_HC_STATIC_LINKING_ONLY /* protection macro */
|
||||||
|
#ifndef TRACY_LZ4_HC_SLO_098092834
|
||||||
|
#define TRACY_LZ4_HC_SLO_098092834
|
||||||
|
|
||||||
|
#define LZ4_STATIC_LINKING_ONLY /* LZ4LIB_STATIC_API */
|
||||||
|
#include "tracy_lz4.hpp"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
/*! LZ4_setCompressionLevel() : v1.8.0+ (experimental)
|
||||||
|
* It's possible to change compression level
|
||||||
|
* between successive invocations of LZ4_compress_HC_continue*()
|
||||||
|
* for dynamic adaptation.
|
||||||
|
*/
|
||||||
|
LZ4LIB_STATIC_API void LZ4_setCompressionLevel(
|
||||||
|
LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel);
|
||||||
|
|
||||||
|
/*! LZ4_favorDecompressionSpeed() : v1.8.2+ (experimental)
|
||||||
|
* Opt. Parser will favor decompression speed over compression ratio.
|
||||||
|
* Only applicable to levels >= LZ4HC_CLEVEL_OPT_MIN.
|
||||||
|
*/
|
||||||
|
LZ4LIB_STATIC_API void LZ4_favorDecompressionSpeed(
|
||||||
|
LZ4_streamHC_t* LZ4_streamHCPtr, int favor);
|
||||||
|
|
||||||
|
/*! LZ4_resetStreamHC_fast() : v1.9.0+
|
||||||
|
* When an LZ4_streamHC_t is known to be in a internally coherent state,
|
||||||
|
* it can often be prepared for a new compression with almost no work, only
|
||||||
|
* sometimes falling back to the full, expensive reset that is always required
|
||||||
|
* when the stream is in an indeterminate state (i.e., the reset performed by
|
||||||
|
* LZ4_resetStreamHC()).
|
||||||
|
*
|
||||||
|
* LZ4_streamHCs are guaranteed to be in a valid state when:
|
||||||
|
* - returned from LZ4_createStreamHC()
|
||||||
|
* - reset by LZ4_resetStreamHC()
|
||||||
|
* - memset(stream, 0, sizeof(LZ4_streamHC_t))
|
||||||
|
* - the stream was in a valid state and was reset by LZ4_resetStreamHC_fast()
|
||||||
|
* - the stream was in a valid state and was then used in any compression call
|
||||||
|
* that returned success
|
||||||
|
* - the stream was in an indeterminate state and was used in a compression
|
||||||
|
* call that fully reset the state (LZ4_compress_HC_extStateHC()) and that
|
||||||
|
* returned success
|
||||||
|
*
|
||||||
|
* Note:
|
||||||
|
* A stream that was last used in a compression call that returned an error
|
||||||
|
* may be passed to this function. However, it will be fully reset, which will
|
||||||
|
* clear any existing history and settings from the context.
|
||||||
|
*/
|
||||||
|
LZ4LIB_STATIC_API void LZ4_resetStreamHC_fast(
|
||||||
|
LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel);
|
||||||
|
|
||||||
|
/*! LZ4_compress_HC_extStateHC_fastReset() :
|
||||||
|
* A variant of LZ4_compress_HC_extStateHC().
|
||||||
|
*
|
||||||
|
* Using this variant avoids an expensive initialization step. It is only safe
|
||||||
|
* to call if the state buffer is known to be correctly initialized already
|
||||||
|
* (see above comment on LZ4_resetStreamHC_fast() for a definition of
|
||||||
|
* "correctly initialized"). From a high level, the difference is that this
|
||||||
|
* function initializes the provided state with a call to
|
||||||
|
* LZ4_resetStreamHC_fast() while LZ4_compress_HC_extStateHC() starts with a
|
||||||
|
* call to LZ4_resetStreamHC().
|
||||||
|
*/
|
||||||
|
LZ4LIB_STATIC_API int LZ4_compress_HC_extStateHC_fastReset (
|
||||||
|
void* state,
|
||||||
|
const char* src, char* dst,
|
||||||
|
int srcSize, int dstCapacity,
|
||||||
|
int compressionLevel);
|
||||||
|
|
||||||
|
/*! LZ4_attach_HC_dictionary() :
|
||||||
|
* This is an experimental API that allows for the efficient use of a
|
||||||
|
* static dictionary many times.
|
||||||
|
*
|
||||||
|
* Rather than re-loading the dictionary buffer into a working context before
|
||||||
|
* each compression, or copying a pre-loaded dictionary's LZ4_streamHC_t into a
|
||||||
|
* working LZ4_streamHC_t, this function introduces a no-copy setup mechanism,
|
||||||
|
* in which the working stream references the dictionary stream in-place.
|
||||||
|
*
|
||||||
|
* Several assumptions are made about the state of the dictionary stream.
|
||||||
|
* Currently, only streams which have been prepared by LZ4_loadDictHC() should
|
||||||
|
* be expected to work.
|
||||||
|
*
|
||||||
|
* Alternatively, the provided dictionary stream pointer may be NULL, in which
|
||||||
|
* case any existing dictionary stream is unset.
|
||||||
|
*
|
||||||
|
* A dictionary should only be attached to a stream without any history (i.e.,
|
||||||
|
* a stream that has just been reset).
|
||||||
|
*
|
||||||
|
* The dictionary will remain attached to the working stream only for the
|
||||||
|
* current stream session. Calls to LZ4_resetStreamHC(_fast) will remove the
|
||||||
|
* dictionary context association from the working stream. The dictionary
|
||||||
|
* stream (and source buffer) must remain in-place / accessible / unchanged
|
||||||
|
* through the lifetime of the stream session.
|
||||||
|
*/
|
||||||
|
LZ4LIB_STATIC_API void LZ4_attach_HC_dictionary(
|
||||||
|
LZ4_streamHC_t *working_stream,
|
||||||
|
const LZ4_streamHC_t *dictionary_stream);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LZ4_HC_SLO_098092834 */
|
||||||
|
#endif /* LZ4_HC_STATIC_LINKING_ONLY */
|
29
externals/tracy/public/libbacktrace/LICENSE
vendored
Normal file
29
externals/tracy/public/libbacktrace/LICENSE
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Copyright (C) 2012-2016 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are
|
||||||
|
# met:
|
||||||
|
|
||||||
|
# (1) Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
# (2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in
|
||||||
|
# the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
|
||||||
|
# (3) The name of the author may not be used to
|
||||||
|
# endorse or promote products derived from this software without
|
||||||
|
# specific prior written permission.
|
||||||
|
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
174
externals/tracy/public/libbacktrace/alloc.cpp
vendored
Normal file
174
externals/tracy/public/libbacktrace/alloc.cpp
vendored
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
/* alloc.c -- Memory allocation without mmap.
|
||||||
|
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "backtrace.hpp"
|
||||||
|
#include "internal.hpp"
|
||||||
|
|
||||||
|
#include "../common/TracyAlloc.hpp"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Allocation routines to use on systems that do not support anonymous
|
||||||
|
mmap. This implementation just uses malloc, which means that the
|
||||||
|
backtrace functions may not be safely invoked from a signal
|
||||||
|
handler. */
|
||||||
|
|
||||||
|
/* Allocate memory like malloc. If ERROR_CALLBACK is NULL, don't
|
||||||
|
report an error. */
|
||||||
|
|
||||||
|
void *
|
||||||
|
backtrace_alloc (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||||
|
size_t size, backtrace_error_callback error_callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
ret = tracy_malloc (size);
|
||||||
|
if (ret == NULL)
|
||||||
|
{
|
||||||
|
if (error_callback)
|
||||||
|
error_callback (data, "malloc", errno);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free memory. */
|
||||||
|
|
||||||
|
void
|
||||||
|
backtrace_free (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||||
|
void *p, size_t size ATTRIBUTE_UNUSED,
|
||||||
|
backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
|
||||||
|
void *data ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
tracy_free (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grow VEC by SIZE bytes. */
|
||||||
|
|
||||||
|
void *
|
||||||
|
backtrace_vector_grow (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||||
|
size_t size, backtrace_error_callback error_callback,
|
||||||
|
void *data, struct backtrace_vector *vec)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
if (size > vec->alc)
|
||||||
|
{
|
||||||
|
size_t alc;
|
||||||
|
void *base;
|
||||||
|
|
||||||
|
if (vec->size == 0)
|
||||||
|
alc = 32 * size;
|
||||||
|
else if (vec->size >= 4096)
|
||||||
|
alc = vec->size + 4096;
|
||||||
|
else
|
||||||
|
alc = 2 * vec->size;
|
||||||
|
|
||||||
|
if (alc < vec->size + size)
|
||||||
|
alc = vec->size + size;
|
||||||
|
|
||||||
|
base = tracy_realloc (vec->base, alc);
|
||||||
|
if (base == NULL)
|
||||||
|
{
|
||||||
|
error_callback (data, "realloc", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec->base = base;
|
||||||
|
vec->alc = alc - vec->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = (char *) vec->base + vec->size;
|
||||||
|
vec->size += size;
|
||||||
|
vec->alc -= size;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finish the current allocation on VEC. */
|
||||||
|
|
||||||
|
void *
|
||||||
|
backtrace_vector_finish (struct backtrace_state *state,
|
||||||
|
struct backtrace_vector *vec,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
/* With this allocator we call realloc in backtrace_vector_grow,
|
||||||
|
which means we can't easily reuse the memory here. So just
|
||||||
|
release it. */
|
||||||
|
if (!backtrace_vector_release (state, vec, error_callback, data))
|
||||||
|
return NULL;
|
||||||
|
ret = vec->base;
|
||||||
|
vec->base = NULL;
|
||||||
|
vec->size = 0;
|
||||||
|
vec->alc = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release any extra space allocated for VEC. */
|
||||||
|
|
||||||
|
int
|
||||||
|
backtrace_vector_release (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||||
|
struct backtrace_vector *vec,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
vec->alc = 0;
|
||||||
|
|
||||||
|
if (vec->size == 0)
|
||||||
|
{
|
||||||
|
/* As of C17, realloc with size 0 is marked as an obsolescent feature, use
|
||||||
|
free instead. */
|
||||||
|
tracy_free (vec->base);
|
||||||
|
vec->base = NULL;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec->base = tracy_realloc (vec->base, vec->size);
|
||||||
|
if (vec->base == NULL)
|
||||||
|
{
|
||||||
|
error_callback (data, "realloc", errno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
186
externals/tracy/public/libbacktrace/backtrace.hpp
vendored
Normal file
186
externals/tracy/public/libbacktrace/backtrace.hpp
vendored
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
/* backtrace.h -- Public header file for stack backtrace library.
|
||||||
|
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#ifndef BACKTRACE_H
|
||||||
|
#define BACKTRACE_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
/* The backtrace state. This struct is intentionally not defined in
|
||||||
|
the public interface. */
|
||||||
|
|
||||||
|
struct backtrace_state;
|
||||||
|
|
||||||
|
/* The type of the error callback argument to backtrace functions.
|
||||||
|
This function, if not NULL, will be called for certain error cases.
|
||||||
|
The DATA argument is passed to the function that calls this one.
|
||||||
|
The MSG argument is an error message. The ERRNUM argument, if
|
||||||
|
greater than 0, holds an errno value. The MSG buffer may become
|
||||||
|
invalid after this function returns.
|
||||||
|
|
||||||
|
As a special case, the ERRNUM argument will be passed as -1 if no
|
||||||
|
debug info can be found for the executable, or if the debug info
|
||||||
|
exists but has an unsupported version, but the function requires
|
||||||
|
debug info (e.g., backtrace_full, backtrace_pcinfo). The MSG in
|
||||||
|
this case will be something along the lines of "no debug info".
|
||||||
|
Similarly, ERRNUM will be passed as -1 if there is no symbol table,
|
||||||
|
but the function requires a symbol table (e.g., backtrace_syminfo).
|
||||||
|
This may be used as a signal that some other approach should be
|
||||||
|
tried. */
|
||||||
|
|
||||||
|
typedef void (*backtrace_error_callback) (void *data, const char *msg,
|
||||||
|
int errnum);
|
||||||
|
|
||||||
|
/* Create state information for the backtrace routines. This must be
|
||||||
|
called before any of the other routines, and its return value must
|
||||||
|
be passed to all of the other routines. FILENAME is the path name
|
||||||
|
of the executable file; if it is NULL the library will try
|
||||||
|
system-specific path names. If not NULL, FILENAME must point to a
|
||||||
|
permanent buffer. If THREADED is non-zero the state may be
|
||||||
|
accessed by multiple threads simultaneously, and the library will
|
||||||
|
use appropriate atomic operations. If THREADED is zero the state
|
||||||
|
may only be accessed by one thread at a time. This returns a state
|
||||||
|
pointer on success, NULL on error. If an error occurs, this will
|
||||||
|
call the ERROR_CALLBACK routine.
|
||||||
|
|
||||||
|
Calling this function allocates resources that cannot be freed.
|
||||||
|
There is no backtrace_free_state function. The state is used to
|
||||||
|
cache information that is expensive to recompute. Programs are
|
||||||
|
expected to call this function at most once and to save the return
|
||||||
|
value for all later calls to backtrace functions. */
|
||||||
|
|
||||||
|
extern struct backtrace_state *backtrace_create_state (
|
||||||
|
const char *filename, int threaded,
|
||||||
|
backtrace_error_callback error_callback, void *data);
|
||||||
|
|
||||||
|
/* The type of the callback argument to the backtrace_full function.
|
||||||
|
DATA is the argument passed to backtrace_full. PC is the program
|
||||||
|
counter. FILENAME is the name of the file containing PC, or NULL
|
||||||
|
if not available. LINENO is the line number in FILENAME containing
|
||||||
|
PC, or 0 if not available. FUNCTION is the name of the function
|
||||||
|
containing PC, or NULL if not available. This should return 0 to
|
||||||
|
continuing tracing. The FILENAME and FUNCTION buffers may become
|
||||||
|
invalid after this function returns. */
|
||||||
|
|
||||||
|
typedef int (*backtrace_full_callback) (void *data, uintptr_t pc, uintptr_t lowaddr,
|
||||||
|
const char *filename, int lineno,
|
||||||
|
const char *function);
|
||||||
|
|
||||||
|
/* Get a full stack backtrace. SKIP is the number of frames to skip;
|
||||||
|
passing 0 will start the trace with the function calling
|
||||||
|
backtrace_full. DATA is passed to the callback routine. If any
|
||||||
|
call to CALLBACK returns a non-zero value, the stack backtrace
|
||||||
|
stops, and backtrace returns that value; this may be used to limit
|
||||||
|
the number of stack frames desired. If all calls to CALLBACK
|
||||||
|
return 0, backtrace returns 0. The backtrace_full function will
|
||||||
|
make at least one call to either CALLBACK or ERROR_CALLBACK. This
|
||||||
|
function requires debug info for the executable. */
|
||||||
|
|
||||||
|
extern int backtrace_full (struct backtrace_state *state, int skip,
|
||||||
|
backtrace_full_callback callback,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
/* The type of the callback argument to the backtrace_simple function.
|
||||||
|
DATA is the argument passed to simple_backtrace. PC is the program
|
||||||
|
counter. This should return 0 to continue tracing. */
|
||||||
|
|
||||||
|
typedef int (*backtrace_simple_callback) (void *data, uintptr_t pc);
|
||||||
|
|
||||||
|
/* Get a simple backtrace. SKIP is the number of frames to skip, as
|
||||||
|
in backtrace. DATA is passed to the callback routine. If any call
|
||||||
|
to CALLBACK returns a non-zero value, the stack backtrace stops,
|
||||||
|
and backtrace_simple returns that value. Otherwise
|
||||||
|
backtrace_simple returns 0. The backtrace_simple function will
|
||||||
|
make at least one call to either CALLBACK or ERROR_CALLBACK. This
|
||||||
|
function does not require any debug info for the executable. */
|
||||||
|
|
||||||
|
extern int backtrace_simple (struct backtrace_state *state, int skip,
|
||||||
|
backtrace_simple_callback callback,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
/* Print the current backtrace in a user readable format to a FILE.
|
||||||
|
SKIP is the number of frames to skip, as in backtrace_full. Any
|
||||||
|
error messages are printed to stderr. This function requires debug
|
||||||
|
info for the executable. */
|
||||||
|
|
||||||
|
extern void backtrace_print (struct backtrace_state *state, int skip, FILE *);
|
||||||
|
|
||||||
|
/* Given PC, a program counter in the current program, call the
|
||||||
|
callback function with filename, line number, and function name
|
||||||
|
information. This will normally call the callback function exactly
|
||||||
|
once. However, if the PC happens to describe an inlined call, and
|
||||||
|
the debugging information contains the necessary information, then
|
||||||
|
this may call the callback function multiple times. This will make
|
||||||
|
at least one call to either CALLBACK or ERROR_CALLBACK. This
|
||||||
|
returns the first non-zero value returned by CALLBACK, or 0. */
|
||||||
|
|
||||||
|
extern int backtrace_pcinfo (struct backtrace_state *state, uintptr_t pc,
|
||||||
|
backtrace_full_callback callback,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
/* The type of the callback argument to backtrace_syminfo. DATA and
|
||||||
|
PC are the arguments passed to backtrace_syminfo. SYMNAME is the
|
||||||
|
name of the symbol for the corresponding code. SYMVAL is the
|
||||||
|
value and SYMSIZE is the size of the symbol. SYMNAME will be NULL
|
||||||
|
if no error occurred but the symbol could not be found. */
|
||||||
|
|
||||||
|
typedef void (*backtrace_syminfo_callback) (void *data, uintptr_t pc,
|
||||||
|
const char *symname,
|
||||||
|
uintptr_t symval,
|
||||||
|
uintptr_t symsize);
|
||||||
|
|
||||||
|
/* Given ADDR, an address or program counter in the current program,
|
||||||
|
call the callback information with the symbol name and value
|
||||||
|
describing the function or variable in which ADDR may be found.
|
||||||
|
This will call either CALLBACK or ERROR_CALLBACK exactly once.
|
||||||
|
This returns 1 on success, 0 on failure. This function requires
|
||||||
|
the symbol table but does not require the debug info. Note that if
|
||||||
|
the symbol table is present but ADDR could not be found in the
|
||||||
|
table, CALLBACK will be called with a NULL SYMNAME argument.
|
||||||
|
Returns 1 on success, 0 on error. */
|
||||||
|
|
||||||
|
extern int backtrace_syminfo (struct backtrace_state *state, uintptr_t addr,
|
||||||
|
backtrace_syminfo_callback callback,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
26
externals/tracy/public/libbacktrace/config.h
vendored
Normal file
26
externals/tracy/public/libbacktrace/config.h
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#include <limits.h>
|
||||||
|
#if defined(__linux__) && !defined(__GLIBC__) && !defined(__WORDSIZE)
|
||||||
|
// include __WORDSIZE headers for musl
|
||||||
|
# include <bits/reg.h>
|
||||||
|
#endif
|
||||||
|
#if __WORDSIZE == 64
|
||||||
|
# define BACKTRACE_ELF_SIZE 64
|
||||||
|
#else
|
||||||
|
# define BACKTRACE_ELF_SIZE 32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define HAVE_DLFCN_H 1
|
||||||
|
#define HAVE_FCNTL 1
|
||||||
|
#define HAVE_INTTYPES_H 1
|
||||||
|
#define HAVE_LSTAT 1
|
||||||
|
#define HAVE_READLINK 1
|
||||||
|
#define HAVE_DL_ITERATE_PHDR 1
|
||||||
|
#define HAVE_ATOMIC_FUNCTIONS 1
|
||||||
|
#define HAVE_DECL_STRNLEN 1
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
# define HAVE_MACH_O_DYLD_H 1
|
||||||
|
#elif defined BSD
|
||||||
|
# define HAVE_KERN_PROC 1
|
||||||
|
# define HAVE_KERN_PROC_ARGS 1
|
||||||
|
#endif
|
4448
externals/tracy/public/libbacktrace/dwarf.cpp
vendored
Normal file
4448
externals/tracy/public/libbacktrace/dwarf.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7582
externals/tracy/public/libbacktrace/elf.cpp
vendored
Normal file
7582
externals/tracy/public/libbacktrace/elf.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
351
externals/tracy/public/libbacktrace/fileline.cpp
vendored
Normal file
351
externals/tracy/public/libbacktrace/fileline.cpp
vendored
Normal file
@ -0,0 +1,351 @@
|
|||||||
|
/* fileline.c -- Get file and line number information in a backtrace.
|
||||||
|
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#if defined (HAVE_KERN_PROC_ARGS) || defined (HAVE_KERN_PROC)
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_MACH_O_DYLD_H
|
||||||
|
#include <mach-o/dyld.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "backtrace.hpp"
|
||||||
|
#include "internal.hpp"
|
||||||
|
|
||||||
|
#ifndef HAVE_GETEXECNAME
|
||||||
|
#define getexecname() NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
#if !defined (HAVE_KERN_PROC_ARGS) && !defined (HAVE_KERN_PROC)
|
||||||
|
|
||||||
|
#define sysctl_exec_name1(state, error_callback, data) NULL
|
||||||
|
#define sysctl_exec_name2(state, error_callback, data) NULL
|
||||||
|
|
||||||
|
#else /* defined (HAVE_KERN_PROC_ARGS) || |defined (HAVE_KERN_PROC) */
|
||||||
|
|
||||||
|
static char *
|
||||||
|
sysctl_exec_name (struct backtrace_state *state,
|
||||||
|
int mib0, int mib1, int mib2, int mib3,
|
||||||
|
backtrace_error_callback error_callback, void *data)
|
||||||
|
{
|
||||||
|
int mib[4];
|
||||||
|
size_t len;
|
||||||
|
char *name;
|
||||||
|
size_t rlen;
|
||||||
|
|
||||||
|
mib[0] = mib0;
|
||||||
|
mib[1] = mib1;
|
||||||
|
mib[2] = mib2;
|
||||||
|
mib[3] = mib3;
|
||||||
|
|
||||||
|
if (sysctl (mib, 4, NULL, &len, NULL, 0) < 0)
|
||||||
|
return NULL;
|
||||||
|
name = (char *) backtrace_alloc (state, len, error_callback, data);
|
||||||
|
if (name == NULL)
|
||||||
|
return NULL;
|
||||||
|
rlen = len;
|
||||||
|
if (sysctl (mib, 4, name, &rlen, NULL, 0) < 0)
|
||||||
|
{
|
||||||
|
backtrace_free (state, name, len, error_callback, data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_KERN_PROC_ARGS
|
||||||
|
|
||||||
|
static char *
|
||||||
|
sysctl_exec_name1 (struct backtrace_state *state,
|
||||||
|
backtrace_error_callback error_callback, void *data)
|
||||||
|
{
|
||||||
|
/* This variant is used on NetBSD. */
|
||||||
|
return sysctl_exec_name (state, CTL_KERN, KERN_PROC_ARGS, -1,
|
||||||
|
KERN_PROC_PATHNAME, error_callback, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define sysctl_exec_name1(state, error_callback, data) NULL
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_KERN_PROC
|
||||||
|
|
||||||
|
static char *
|
||||||
|
sysctl_exec_name2 (struct backtrace_state *state,
|
||||||
|
backtrace_error_callback error_callback, void *data)
|
||||||
|
{
|
||||||
|
/* This variant is used on FreeBSD. */
|
||||||
|
return sysctl_exec_name (state, CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1,
|
||||||
|
error_callback, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define sysctl_exec_name2(state, error_callback, data) NULL
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* defined (HAVE_KERN_PROC_ARGS) || |defined (HAVE_KERN_PROC) */
|
||||||
|
|
||||||
|
#ifdef HAVE_MACH_O_DYLD_H
|
||||||
|
|
||||||
|
static char *
|
||||||
|
macho_get_executable_path (struct backtrace_state *state,
|
||||||
|
backtrace_error_callback error_callback, void *data)
|
||||||
|
{
|
||||||
|
uint32_t len;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
len = 0;
|
||||||
|
if (_NSGetExecutablePath (NULL, &len) == 0)
|
||||||
|
return NULL;
|
||||||
|
name = (char *) backtrace_alloc (state, len, error_callback, data);
|
||||||
|
if (name == NULL)
|
||||||
|
return NULL;
|
||||||
|
if (_NSGetExecutablePath (name, &len) != 0)
|
||||||
|
{
|
||||||
|
backtrace_free (state, name, len, error_callback, data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* !defined (HAVE_MACH_O_DYLD_H) */
|
||||||
|
|
||||||
|
#define macho_get_executable_path(state, error_callback, data) NULL
|
||||||
|
|
||||||
|
#endif /* !defined (HAVE_MACH_O_DYLD_H) */
|
||||||
|
|
||||||
|
/* Initialize the fileline information from the executable. Returns 1
|
||||||
|
on success, 0 on failure. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
fileline_initialize (struct backtrace_state *state,
|
||||||
|
backtrace_error_callback error_callback, void *data)
|
||||||
|
{
|
||||||
|
int failed;
|
||||||
|
fileline fileline_fn;
|
||||||
|
int pass;
|
||||||
|
int called_error_callback;
|
||||||
|
int descriptor;
|
||||||
|
const char *filename;
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
if (!state->threaded)
|
||||||
|
failed = state->fileline_initialization_failed;
|
||||||
|
else
|
||||||
|
failed = backtrace_atomic_load_int (&state->fileline_initialization_failed);
|
||||||
|
|
||||||
|
if (failed)
|
||||||
|
{
|
||||||
|
error_callback (data, "failed to read executable information", -1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!state->threaded)
|
||||||
|
fileline_fn = state->fileline_fn;
|
||||||
|
else
|
||||||
|
fileline_fn = backtrace_atomic_load_pointer (&state->fileline_fn);
|
||||||
|
if (fileline_fn != NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* We have not initialized the information. Do it now. */
|
||||||
|
|
||||||
|
descriptor = -1;
|
||||||
|
called_error_callback = 0;
|
||||||
|
for (pass = 0; pass < 8; ++pass)
|
||||||
|
{
|
||||||
|
int does_not_exist;
|
||||||
|
|
||||||
|
switch (pass)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
filename = state->filename;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
filename = getexecname ();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
filename = "/proc/self/exe";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
filename = "/proc/curproc/file";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
snprintf (buf, sizeof (buf), "/proc/%ld/object/a.out",
|
||||||
|
(long) getpid ());
|
||||||
|
filename = buf;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
filename = sysctl_exec_name1 (state, error_callback, data);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
filename = sysctl_exec_name2 (state, error_callback, data);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
filename = macho_get_executable_path (state, error_callback, data);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filename == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
descriptor = backtrace_open (filename, error_callback, data,
|
||||||
|
&does_not_exist);
|
||||||
|
if (descriptor < 0 && !does_not_exist)
|
||||||
|
{
|
||||||
|
called_error_callback = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (descriptor >= 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (descriptor < 0)
|
||||||
|
{
|
||||||
|
if (!called_error_callback)
|
||||||
|
{
|
||||||
|
if (state->filename != NULL)
|
||||||
|
error_callback (data, state->filename, ENOENT);
|
||||||
|
else
|
||||||
|
error_callback (data,
|
||||||
|
"libbacktrace could not find executable to open",
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
failed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!failed)
|
||||||
|
{
|
||||||
|
if (!backtrace_initialize (state, filename, descriptor, error_callback,
|
||||||
|
data, &fileline_fn))
|
||||||
|
failed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed)
|
||||||
|
{
|
||||||
|
if (!state->threaded)
|
||||||
|
state->fileline_initialization_failed = 1;
|
||||||
|
else
|
||||||
|
backtrace_atomic_store_int (&state->fileline_initialization_failed, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!state->threaded)
|
||||||
|
state->fileline_fn = fileline_fn;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
backtrace_atomic_store_pointer (&state->fileline_fn, fileline_fn);
|
||||||
|
|
||||||
|
/* Note that if two threads initialize at once, one of the data
|
||||||
|
sets may be leaked. */
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Given a PC, find the file name, line number, and function name. */
|
||||||
|
|
||||||
|
int
|
||||||
|
backtrace_pcinfo (struct backtrace_state *state, uintptr_t pc,
|
||||||
|
backtrace_full_callback callback,
|
||||||
|
backtrace_error_callback error_callback, void *data)
|
||||||
|
{
|
||||||
|
if (!fileline_initialize (state, error_callback, data))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (state->fileline_initialization_failed)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return state->fileline_fn (state, pc, callback, error_callback, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Given a PC, find the symbol for it, and its value. */
|
||||||
|
|
||||||
|
int
|
||||||
|
backtrace_syminfo (struct backtrace_state *state, uintptr_t pc,
|
||||||
|
backtrace_syminfo_callback callback,
|
||||||
|
backtrace_error_callback error_callback, void *data)
|
||||||
|
{
|
||||||
|
if (!fileline_initialize (state, error_callback, data))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (state->fileline_initialization_failed)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
state->syminfo_fn (state, pc, callback, error_callback, data);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A backtrace_syminfo_callback that can call into a
|
||||||
|
backtrace_full_callback, used when we have a symbol table but no
|
||||||
|
debug info. */
|
||||||
|
|
||||||
|
void
|
||||||
|
backtrace_syminfo_to_full_callback (void *data, uintptr_t pc,
|
||||||
|
const char *symname,
|
||||||
|
uintptr_t symval ATTRIBUTE_UNUSED,
|
||||||
|
uintptr_t symsize ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
struct backtrace_call_full *bdata = (struct backtrace_call_full *) data;
|
||||||
|
|
||||||
|
bdata->ret = bdata->full_callback (bdata->full_data, pc, 0, NULL, 0, symname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* An error callback that corresponds to
|
||||||
|
backtrace_syminfo_to_full_callback. */
|
||||||
|
|
||||||
|
void
|
||||||
|
backtrace_syminfo_to_full_error_callback (void *data, const char *msg,
|
||||||
|
int errnum)
|
||||||
|
{
|
||||||
|
struct backtrace_call_full *bdata = (struct backtrace_call_full *) data;
|
||||||
|
|
||||||
|
bdata->full_error_callback (bdata->full_data, msg, errnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
52
externals/tracy/public/libbacktrace/filenames.hpp
vendored
Normal file
52
externals/tracy/public/libbacktrace/filenames.hpp
vendored
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/* btest.c -- Filename header for libbacktrace library
|
||||||
|
Copyright (C) 2012-2018 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#ifndef GCC_VERSION
|
||||||
|
# define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (GCC_VERSION < 2007)
|
||||||
|
# define __attribute__(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ATTRIBUTE_UNUSED
|
||||||
|
# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__) || defined (__CYGWIN__)
|
||||||
|
# define IS_DIR_SEPARATOR(c) ((c) == '/' || (c) == '\\')
|
||||||
|
# define HAS_DRIVE_SPEC(f) ((f)[0] != '\0' && (f)[1] == ':')
|
||||||
|
# define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0]) || HAS_DRIVE_SPEC(f))
|
||||||
|
#else
|
||||||
|
# define IS_DIR_SEPARATOR(c) ((c) == '/')
|
||||||
|
# define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0]))
|
||||||
|
#endif
|
401
externals/tracy/public/libbacktrace/internal.hpp
vendored
Normal file
401
externals/tracy/public/libbacktrace/internal.hpp
vendored
Normal file
@ -0,0 +1,401 @@
|
|||||||
|
/* internal.h -- Internal header file for stack backtrace library.
|
||||||
|
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#ifndef BACKTRACE_INTERNAL_H
|
||||||
|
#define BACKTRACE_INTERNAL_H
|
||||||
|
|
||||||
|
/* We assume that <sys/types.h> and "backtrace.h" have already been
|
||||||
|
included. */
|
||||||
|
|
||||||
|
#ifndef GCC_VERSION
|
||||||
|
# define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (GCC_VERSION < 2007)
|
||||||
|
# define __attribute__(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ATTRIBUTE_UNUSED
|
||||||
|
# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ATTRIBUTE_MALLOC
|
||||||
|
# if (GCC_VERSION >= 2096)
|
||||||
|
# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_MALLOC
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ATTRIBUTE_FALLTHROUGH
|
||||||
|
# if (GCC_VERSION >= 7000)
|
||||||
|
# define ATTRIBUTE_FALLTHROUGH __attribute__ ((__fallthrough__))
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_FALLTHROUGH
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_SYNC_FUNCTIONS
|
||||||
|
|
||||||
|
/* Define out the sync functions. These should never be called if
|
||||||
|
they are not available. */
|
||||||
|
|
||||||
|
#define __sync_bool_compare_and_swap(A, B, C) (abort(), 1)
|
||||||
|
#define __sync_lock_test_and_set(A, B) (abort(), 0)
|
||||||
|
#define __sync_lock_release(A) abort()
|
||||||
|
|
||||||
|
#endif /* !defined (HAVE_SYNC_FUNCTIONS) */
|
||||||
|
|
||||||
|
#ifdef HAVE_ATOMIC_FUNCTIONS
|
||||||
|
|
||||||
|
/* We have the atomic builtin functions. */
|
||||||
|
|
||||||
|
#define backtrace_atomic_load_pointer(p) \
|
||||||
|
__atomic_load_n ((p), __ATOMIC_ACQUIRE)
|
||||||
|
#define backtrace_atomic_load_int(p) \
|
||||||
|
__atomic_load_n ((p), __ATOMIC_ACQUIRE)
|
||||||
|
#define backtrace_atomic_store_pointer(p, v) \
|
||||||
|
__atomic_store_n ((p), (v), __ATOMIC_RELEASE)
|
||||||
|
#define backtrace_atomic_store_size_t(p, v) \
|
||||||
|
__atomic_store_n ((p), (v), __ATOMIC_RELEASE)
|
||||||
|
#define backtrace_atomic_store_int(p, v) \
|
||||||
|
__atomic_store_n ((p), (v), __ATOMIC_RELEASE)
|
||||||
|
|
||||||
|
#else /* !defined (HAVE_ATOMIC_FUNCTIONS) */
|
||||||
|
#ifdef HAVE_SYNC_FUNCTIONS
|
||||||
|
|
||||||
|
/* We have the sync functions but not the atomic functions. Define
|
||||||
|
the atomic ones in terms of the sync ones. */
|
||||||
|
|
||||||
|
extern void *backtrace_atomic_load_pointer (void *);
|
||||||
|
extern int backtrace_atomic_load_int (int *);
|
||||||
|
extern void backtrace_atomic_store_pointer (void *, void *);
|
||||||
|
extern void backtrace_atomic_store_size_t (size_t *, size_t);
|
||||||
|
extern void backtrace_atomic_store_int (int *, int);
|
||||||
|
|
||||||
|
#else /* !defined (HAVE_SYNC_FUNCTIONS) */
|
||||||
|
|
||||||
|
/* We have neither the sync nor the atomic functions. These will
|
||||||
|
never be called. */
|
||||||
|
|
||||||
|
#define backtrace_atomic_load_pointer(p) (abort(), (void *) NULL)
|
||||||
|
#define backtrace_atomic_load_int(p) (abort(), 0)
|
||||||
|
#define backtrace_atomic_store_pointer(p, v) abort()
|
||||||
|
#define backtrace_atomic_store_size_t(p, v) abort()
|
||||||
|
#define backtrace_atomic_store_int(p, v) abort()
|
||||||
|
|
||||||
|
#endif /* !defined (HAVE_SYNC_FUNCTIONS) */
|
||||||
|
#endif /* !defined (HAVE_ATOMIC_FUNCTIONS) */
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
/* The type of the function that collects file/line information. This
|
||||||
|
is like backtrace_pcinfo. */
|
||||||
|
|
||||||
|
typedef int (*fileline) (struct backtrace_state *state, uintptr_t pc,
|
||||||
|
backtrace_full_callback callback,
|
||||||
|
backtrace_error_callback error_callback, void *data);
|
||||||
|
|
||||||
|
/* The type of the function that collects symbol information. This is
|
||||||
|
like backtrace_syminfo. */
|
||||||
|
|
||||||
|
typedef void (*syminfo) (struct backtrace_state *state, uintptr_t pc,
|
||||||
|
backtrace_syminfo_callback callback,
|
||||||
|
backtrace_error_callback error_callback, void *data);
|
||||||
|
|
||||||
|
/* The type of the function that will trigger an known address range refresh
|
||||||
|
(if pc passed in is for an address whichs lies ourtisde of known ranges) */
|
||||||
|
typedef int (*request_known_address_ranges_refresh)(struct backtrace_state *state,
|
||||||
|
uintptr_t pc);
|
||||||
|
|
||||||
|
/* What the backtrace state pointer points to. */
|
||||||
|
|
||||||
|
struct backtrace_state
|
||||||
|
{
|
||||||
|
/* The name of the executable. */
|
||||||
|
const char *filename;
|
||||||
|
/* Non-zero if threaded. */
|
||||||
|
int threaded;
|
||||||
|
/* The master lock for fileline_fn, fileline_data, syminfo_fn,
|
||||||
|
syminfo_data, fileline_initialization_failed and everything the
|
||||||
|
data pointers point to. */
|
||||||
|
void *lock;
|
||||||
|
/* The function that returns file/line information. */
|
||||||
|
fileline fileline_fn;
|
||||||
|
/* The data to pass to FILELINE_FN. */
|
||||||
|
void *fileline_data;
|
||||||
|
/* The function that returns symbol information. */
|
||||||
|
syminfo syminfo_fn;
|
||||||
|
/* The data to pass to SYMINFO_FN. */
|
||||||
|
void *syminfo_data;
|
||||||
|
/* Whether initializing the file/line information failed. */
|
||||||
|
int fileline_initialization_failed;
|
||||||
|
/* The lock for the freelist. */
|
||||||
|
int lock_alloc;
|
||||||
|
/* The freelist when using mmap. */
|
||||||
|
struct backtrace_freelist_struct *freelist;
|
||||||
|
/* Trigger an known address range refresh */
|
||||||
|
request_known_address_ranges_refresh request_known_address_ranges_refresh_fn;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Open a file for reading. Returns -1 on error. If DOES_NOT_EXIST
|
||||||
|
is not NULL, *DOES_NOT_EXIST will be set to 0 normally and set to 1
|
||||||
|
if the file does not exist. If the file does not exist and
|
||||||
|
DOES_NOT_EXIST is not NULL, the function will return -1 and will
|
||||||
|
not call ERROR_CALLBACK. On other errors, or if DOES_NOT_EXIST is
|
||||||
|
NULL, the function will call ERROR_CALLBACK before returning. */
|
||||||
|
extern int backtrace_open (const char *filename,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data,
|
||||||
|
int *does_not_exist);
|
||||||
|
|
||||||
|
/* A view of the contents of a file. This supports mmap when
|
||||||
|
available. A view will remain in memory even after backtrace_close
|
||||||
|
is called on the file descriptor from which the view was
|
||||||
|
obtained. */
|
||||||
|
|
||||||
|
struct backtrace_view
|
||||||
|
{
|
||||||
|
/* The data that the caller requested. */
|
||||||
|
const void *data;
|
||||||
|
/* The base of the view. */
|
||||||
|
void *base;
|
||||||
|
/* The total length of the view. */
|
||||||
|
size_t len;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Create a view of SIZE bytes from DESCRIPTOR at OFFSET. Store the
|
||||||
|
result in *VIEW. Returns 1 on success, 0 on error. */
|
||||||
|
extern int backtrace_get_view (struct backtrace_state *state, int descriptor,
|
||||||
|
off_t offset, uint64_t size,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data, struct backtrace_view *view);
|
||||||
|
|
||||||
|
/* Release a view created by backtrace_get_view. */
|
||||||
|
extern void backtrace_release_view (struct backtrace_state *state,
|
||||||
|
struct backtrace_view *view,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
/* Close a file opened by backtrace_open. Returns 1 on success, 0 on
|
||||||
|
error. */
|
||||||
|
|
||||||
|
extern int backtrace_close (int descriptor,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
/* Sort without using memory. */
|
||||||
|
|
||||||
|
extern void backtrace_qsort (void *base, size_t count, size_t size,
|
||||||
|
int (*compar) (const void *, const void *));
|
||||||
|
|
||||||
|
/* Allocate memory. This is like malloc. If ERROR_CALLBACK is NULL,
|
||||||
|
this does not report an error, it just returns NULL. */
|
||||||
|
|
||||||
|
extern void *backtrace_alloc (struct backtrace_state *state, size_t size,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data) ATTRIBUTE_MALLOC;
|
||||||
|
|
||||||
|
/* Free memory allocated by backtrace_alloc. If ERROR_CALLBACK is
|
||||||
|
NULL, this does not report an error. */
|
||||||
|
|
||||||
|
extern void backtrace_free (struct backtrace_state *state, void *mem,
|
||||||
|
size_t size,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
/* A growable vector of some struct. This is used for more efficient
|
||||||
|
allocation when we don't know the final size of some group of data
|
||||||
|
that we want to represent as an array. */
|
||||||
|
|
||||||
|
struct backtrace_vector
|
||||||
|
{
|
||||||
|
/* The base of the vector. */
|
||||||
|
void *base;
|
||||||
|
/* The number of bytes in the vector. */
|
||||||
|
size_t size;
|
||||||
|
/* The number of bytes available at the current allocation. */
|
||||||
|
size_t alc;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Grow VEC by SIZE bytes. Return a pointer to the newly allocated
|
||||||
|
bytes. Note that this may move the entire vector to a new memory
|
||||||
|
location. Returns NULL on failure. */
|
||||||
|
|
||||||
|
extern void *backtrace_vector_grow (struct backtrace_state *state, size_t size,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data,
|
||||||
|
struct backtrace_vector *vec);
|
||||||
|
|
||||||
|
/* Finish the current allocation on VEC. Prepare to start a new
|
||||||
|
allocation. The finished allocation will never be freed. Returns
|
||||||
|
a pointer to the base of the finished entries, or NULL on
|
||||||
|
failure. */
|
||||||
|
|
||||||
|
extern void* backtrace_vector_finish (struct backtrace_state *state,
|
||||||
|
struct backtrace_vector *vec,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
/* Release any extra space allocated for VEC. This may change
|
||||||
|
VEC->base. Returns 1 on success, 0 on failure. */
|
||||||
|
|
||||||
|
extern int backtrace_vector_release (struct backtrace_state *state,
|
||||||
|
struct backtrace_vector *vec,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
/* Free the space managed by VEC. This will reset VEC. */
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
backtrace_vector_free (struct backtrace_state *state,
|
||||||
|
struct backtrace_vector *vec,
|
||||||
|
backtrace_error_callback error_callback, void *data)
|
||||||
|
{
|
||||||
|
vec->alc += vec->size;
|
||||||
|
vec->size = 0;
|
||||||
|
backtrace_vector_release (state, vec, error_callback, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read initial debug data from a descriptor, and set the
|
||||||
|
fileline_data, syminfo_fn, and syminfo_data fields of STATE.
|
||||||
|
Return the fileln_fn field in *FILELN_FN--this is done this way so
|
||||||
|
that the synchronization code is only implemented once. This is
|
||||||
|
called after the descriptor has first been opened. It will close
|
||||||
|
the descriptor if it is no longer needed. Returns 1 on success, 0
|
||||||
|
on error. There will be multiple implementations of this function,
|
||||||
|
for different file formats. Each system will compile the
|
||||||
|
appropriate one. */
|
||||||
|
|
||||||
|
extern int backtrace_initialize (struct backtrace_state *state,
|
||||||
|
const char *filename,
|
||||||
|
int descriptor,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data,
|
||||||
|
fileline *fileline_fn);
|
||||||
|
|
||||||
|
/* An enum for the DWARF sections we care about. */
|
||||||
|
|
||||||
|
enum dwarf_section
|
||||||
|
{
|
||||||
|
DEBUG_INFO,
|
||||||
|
DEBUG_LINE,
|
||||||
|
DEBUG_ABBREV,
|
||||||
|
DEBUG_RANGES,
|
||||||
|
DEBUG_STR,
|
||||||
|
DEBUG_ADDR,
|
||||||
|
DEBUG_STR_OFFSETS,
|
||||||
|
DEBUG_LINE_STR,
|
||||||
|
DEBUG_RNGLISTS,
|
||||||
|
|
||||||
|
DEBUG_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Data for the DWARF sections we care about. */
|
||||||
|
|
||||||
|
struct dwarf_sections
|
||||||
|
{
|
||||||
|
const unsigned char *data[DEBUG_MAX];
|
||||||
|
size_t size[DEBUG_MAX];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* DWARF data read from a file, used for .gnu_debugaltlink. */
|
||||||
|
|
||||||
|
struct dwarf_data;
|
||||||
|
|
||||||
|
/* Add file/line information for a DWARF module. */
|
||||||
|
|
||||||
|
extern int backtrace_dwarf_add (struct backtrace_state *state,
|
||||||
|
uintptr_t base_address,
|
||||||
|
const struct dwarf_sections *dwarf_sections,
|
||||||
|
int is_bigendian,
|
||||||
|
struct dwarf_data *fileline_altlink,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data, fileline *fileline_fn,
|
||||||
|
struct dwarf_data **fileline_entry);
|
||||||
|
|
||||||
|
/* A data structure to pass to backtrace_syminfo_to_full. */
|
||||||
|
|
||||||
|
struct backtrace_call_full
|
||||||
|
{
|
||||||
|
backtrace_full_callback full_callback;
|
||||||
|
backtrace_error_callback full_error_callback;
|
||||||
|
void *full_data;
|
||||||
|
int ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A backtrace_syminfo_callback that can call into a
|
||||||
|
backtrace_full_callback, used when we have a symbol table but no
|
||||||
|
debug info. */
|
||||||
|
|
||||||
|
extern void backtrace_syminfo_to_full_callback (void *data, uintptr_t pc,
|
||||||
|
const char *symname,
|
||||||
|
uintptr_t symval,
|
||||||
|
uintptr_t symsize);
|
||||||
|
|
||||||
|
/* An error callback that corresponds to
|
||||||
|
backtrace_syminfo_to_full_callback. */
|
||||||
|
|
||||||
|
extern void backtrace_syminfo_to_full_error_callback (void *, const char *,
|
||||||
|
int);
|
||||||
|
|
||||||
|
/* A test-only hook for elf_uncompress_zdebug. */
|
||||||
|
|
||||||
|
extern int backtrace_uncompress_zdebug (struct backtrace_state *,
|
||||||
|
const unsigned char *compressed,
|
||||||
|
size_t compressed_size,
|
||||||
|
backtrace_error_callback, void *data,
|
||||||
|
unsigned char **uncompressed,
|
||||||
|
size_t *uncompressed_size);
|
||||||
|
|
||||||
|
/* A test-only hook for elf_zstd_decompress. */
|
||||||
|
|
||||||
|
extern int backtrace_uncompress_zstd (struct backtrace_state *,
|
||||||
|
const unsigned char *compressed,
|
||||||
|
size_t compressed_size,
|
||||||
|
backtrace_error_callback, void *data,
|
||||||
|
unsigned char *uncompressed,
|
||||||
|
size_t uncompressed_size);
|
||||||
|
|
||||||
|
/* A test-only hook for elf_uncompress_lzma. */
|
||||||
|
|
||||||
|
extern int backtrace_uncompress_lzma (struct backtrace_state *,
|
||||||
|
const unsigned char *compressed,
|
||||||
|
size_t compressed_size,
|
||||||
|
backtrace_error_callback, void *data,
|
||||||
|
unsigned char **uncompressed,
|
||||||
|
size_t *uncompressed_size);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
1360
externals/tracy/public/libbacktrace/macho.cpp
vendored
Normal file
1360
externals/tracy/public/libbacktrace/macho.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
115
externals/tracy/public/libbacktrace/mmapio.cpp
vendored
Normal file
115
externals/tracy/public/libbacktrace/mmapio.cpp
vendored
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/* mmapio.c -- File views using mmap.
|
||||||
|
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "backtrace.hpp"
|
||||||
|
#include "internal.hpp"
|
||||||
|
|
||||||
|
#ifndef HAVE_DECL_GETPAGESIZE
|
||||||
|
extern int getpagesize (void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAP_FAILED
|
||||||
|
#define MAP_FAILED ((void *)-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
/* This file implements file views and memory allocation when mmap is
|
||||||
|
available. */
|
||||||
|
|
||||||
|
/* Create a view of SIZE bytes from DESCRIPTOR at OFFSET. */
|
||||||
|
|
||||||
|
int
|
||||||
|
backtrace_get_view (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||||
|
int descriptor, off_t offset, uint64_t size,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data, struct backtrace_view *view)
|
||||||
|
{
|
||||||
|
size_t pagesize;
|
||||||
|
unsigned int inpage;
|
||||||
|
off_t pageoff;
|
||||||
|
void *map;
|
||||||
|
|
||||||
|
if ((uint64_t) (size_t) size != size)
|
||||||
|
{
|
||||||
|
error_callback (data, "file size too large", 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pagesize = getpagesize ();
|
||||||
|
inpage = offset % pagesize;
|
||||||
|
pageoff = offset - inpage;
|
||||||
|
|
||||||
|
size += inpage;
|
||||||
|
size = (size + (pagesize - 1)) & ~ (pagesize - 1);
|
||||||
|
|
||||||
|
map = mmap (NULL, size, PROT_READ, MAP_PRIVATE, descriptor, pageoff);
|
||||||
|
if (map == MAP_FAILED)
|
||||||
|
{
|
||||||
|
error_callback (data, "mmap", errno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
view->data = (char *) map + inpage;
|
||||||
|
view->base = map;
|
||||||
|
view->len = size;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release a view read by backtrace_get_view. */
|
||||||
|
|
||||||
|
void
|
||||||
|
backtrace_release_view (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||||
|
struct backtrace_view *view,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
const void *cv;
|
||||||
|
void *v;
|
||||||
|
} cc;
|
||||||
|
|
||||||
|
cc.cv = view->base;
|
||||||
|
if (munmap (cc.v, view->len) < 0)
|
||||||
|
error_callback (data, "munmap", errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
109
externals/tracy/public/libbacktrace/posix.cpp
vendored
Normal file
109
externals/tracy/public/libbacktrace/posix.cpp
vendored
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/* posix.c -- POSIX file I/O routines for the backtrace library.
|
||||||
|
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "backtrace.hpp"
|
||||||
|
#include "internal.hpp"
|
||||||
|
|
||||||
|
#ifndef O_BINARY
|
||||||
|
#define O_BINARY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_CLOEXEC
|
||||||
|
#define O_CLOEXEC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FD_CLOEXEC
|
||||||
|
#define FD_CLOEXEC 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Open a file for reading. */
|
||||||
|
|
||||||
|
int
|
||||||
|
backtrace_open (const char *filename, backtrace_error_callback error_callback,
|
||||||
|
void *data, int *does_not_exist)
|
||||||
|
{
|
||||||
|
int descriptor;
|
||||||
|
|
||||||
|
if (does_not_exist != NULL)
|
||||||
|
*does_not_exist = 0;
|
||||||
|
|
||||||
|
descriptor = open (filename, (int) (O_RDONLY | O_BINARY | O_CLOEXEC));
|
||||||
|
if (descriptor < 0)
|
||||||
|
{
|
||||||
|
/* If DOES_NOT_EXIST is not NULL, then don't call ERROR_CALLBACK
|
||||||
|
if the file does not exist. We treat lacking permission to
|
||||||
|
open the file as the file not existing; this case arises when
|
||||||
|
running the libgo syscall package tests as root. */
|
||||||
|
if (does_not_exist != NULL && (errno == ENOENT || errno == EACCES))
|
||||||
|
*does_not_exist = 1;
|
||||||
|
else
|
||||||
|
error_callback (data, filename, errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_FCNTL
|
||||||
|
/* Set FD_CLOEXEC just in case the kernel does not support
|
||||||
|
O_CLOEXEC. It doesn't matter if this fails for some reason.
|
||||||
|
FIXME: At some point it should be safe to only do this if
|
||||||
|
O_CLOEXEC == 0. */
|
||||||
|
fcntl (descriptor, F_SETFD, FD_CLOEXEC);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close DESCRIPTOR. */
|
||||||
|
|
||||||
|
int
|
||||||
|
backtrace_close (int descriptor, backtrace_error_callback error_callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
if (close (descriptor) < 0)
|
||||||
|
{
|
||||||
|
error_callback (data, "close", errno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
113
externals/tracy/public/libbacktrace/sort.cpp
vendored
Normal file
113
externals/tracy/public/libbacktrace/sort.cpp
vendored
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/* sort.c -- Sort without allocating memory
|
||||||
|
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "backtrace.hpp"
|
||||||
|
#include "internal.hpp"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
/* The GNU glibc version of qsort allocates memory, which we must not
|
||||||
|
do if we are invoked by a signal handler. So provide our own
|
||||||
|
sort. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
swap (char *a, char *b, size_t size)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < size; i++, a++, b++)
|
||||||
|
{
|
||||||
|
char t;
|
||||||
|
|
||||||
|
t = *a;
|
||||||
|
*a = *b;
|
||||||
|
*b = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
backtrace_qsort (void *basearg, size_t count, size_t size,
|
||||||
|
int (*compar) (const void *, const void *))
|
||||||
|
{
|
||||||
|
char *base = (char *) basearg;
|
||||||
|
size_t i;
|
||||||
|
size_t mid;
|
||||||
|
|
||||||
|
tail_recurse:
|
||||||
|
if (count < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* The symbol table and DWARF tables, which is all we use this
|
||||||
|
routine for, tend to be roughly sorted. Pick the middle element
|
||||||
|
in the array as our pivot point, so that we are more likely to
|
||||||
|
cut the array in half for each recursion step. */
|
||||||
|
swap (base, base + (count / 2) * size, size);
|
||||||
|
|
||||||
|
mid = 0;
|
||||||
|
for (i = 1; i < count; i++)
|
||||||
|
{
|
||||||
|
if ((*compar) (base, base + i * size) > 0)
|
||||||
|
{
|
||||||
|
++mid;
|
||||||
|
if (i != mid)
|
||||||
|
swap (base + mid * size, base + i * size, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mid > 0)
|
||||||
|
swap (base, base + mid * size, size);
|
||||||
|
|
||||||
|
/* Recurse with the smaller array, loop with the larger one. That
|
||||||
|
ensures that our maximum stack depth is log count. */
|
||||||
|
if (2 * mid < count)
|
||||||
|
{
|
||||||
|
backtrace_qsort (base, mid, size, compar);
|
||||||
|
base += (mid + 1) * size;
|
||||||
|
count -= mid + 1;
|
||||||
|
goto tail_recurse;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
backtrace_qsort (base + (mid + 1) * size, count - (mid + 1),
|
||||||
|
size, compar);
|
||||||
|
count = mid;
|
||||||
|
goto tail_recurse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
76
externals/tracy/public/libbacktrace/state.cpp
vendored
Normal file
76
externals/tracy/public/libbacktrace/state.cpp
vendored
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/* state.c -- Create the backtrace state.
|
||||||
|
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
(1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
(2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
(3) The name of the author may not be used to
|
||||||
|
endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "backtrace.hpp"
|
||||||
|
#include "internal.hpp"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Create the backtrace state. This will then be passed to all the
|
||||||
|
other routines. */
|
||||||
|
|
||||||
|
struct backtrace_state *
|
||||||
|
backtrace_create_state (const char *filename, int threaded,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
struct backtrace_state init_state;
|
||||||
|
struct backtrace_state *state;
|
||||||
|
|
||||||
|
#ifndef HAVE_SYNC_FUNCTIONS
|
||||||
|
if (threaded)
|
||||||
|
{
|
||||||
|
error_callback (data, "backtrace library does not support threads", 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
memset (&init_state, 0, sizeof init_state);
|
||||||
|
init_state.filename = filename;
|
||||||
|
init_state.threaded = threaded;
|
||||||
|
|
||||||
|
state = ((struct backtrace_state *)
|
||||||
|
backtrace_alloc (&init_state, sizeof *state, error_callback, data));
|
||||||
|
if (state == NULL)
|
||||||
|
return NULL;
|
||||||
|
*state = init_state;
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
284
externals/tracy/public/tracy/Tracy.hpp
vendored
Normal file
284
externals/tracy/public/tracy/Tracy.hpp
vendored
Normal file
@ -0,0 +1,284 @@
|
|||||||
|
#ifndef __TRACY_HPP__
|
||||||
|
#define __TRACY_HPP__
|
||||||
|
|
||||||
|
#include "../common/TracyColor.hpp"
|
||||||
|
#include "../common/TracySystem.hpp"
|
||||||
|
|
||||||
|
#ifndef TracyFunction
|
||||||
|
# define TracyFunction __FUNCTION__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TracyFile
|
||||||
|
# define TracyFile __FILE__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TracyLine
|
||||||
|
# define TracyLine __LINE__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TRACY_ENABLE
|
||||||
|
|
||||||
|
#define ZoneNamed(x,y)
|
||||||
|
#define ZoneNamedN(x,y,z)
|
||||||
|
#define ZoneNamedC(x,y,z)
|
||||||
|
#define ZoneNamedNC(x,y,z,w)
|
||||||
|
|
||||||
|
#define ZoneTransient(x,y)
|
||||||
|
#define ZoneTransientN(x,y,z)
|
||||||
|
|
||||||
|
#define ZoneScoped
|
||||||
|
#define ZoneScopedN(x)
|
||||||
|
#define ZoneScopedC(x)
|
||||||
|
#define ZoneScopedNC(x,y)
|
||||||
|
|
||||||
|
#define ZoneText(x,y)
|
||||||
|
#define ZoneTextV(x,y,z)
|
||||||
|
#define ZoneName(x,y)
|
||||||
|
#define ZoneNameV(x,y,z)
|
||||||
|
#define ZoneColor(x)
|
||||||
|
#define ZoneColorV(x,y)
|
||||||
|
#define ZoneValue(x)
|
||||||
|
#define ZoneValueV(x,y)
|
||||||
|
#define ZoneIsActive false
|
||||||
|
#define ZoneIsActiveV(x) false
|
||||||
|
|
||||||
|
#define FrameMark
|
||||||
|
#define FrameMarkNamed(x)
|
||||||
|
#define FrameMarkStart(x)
|
||||||
|
#define FrameMarkEnd(x)
|
||||||
|
|
||||||
|
#define FrameImage(x,y,z,w,a)
|
||||||
|
|
||||||
|
#define TracyLockable( type, varname ) type varname
|
||||||
|
#define TracyLockableN( type, varname, desc ) type varname
|
||||||
|
#define TracySharedLockable( type, varname ) type varname
|
||||||
|
#define TracySharedLockableN( type, varname, desc ) type varname
|
||||||
|
#define LockableBase( type ) type
|
||||||
|
#define SharedLockableBase( type ) type
|
||||||
|
#define LockMark(x) (void)x
|
||||||
|
#define LockableName(x,y,z)
|
||||||
|
|
||||||
|
#define TracyPlot(x,y)
|
||||||
|
#define TracyPlotConfig(x,y,z,w,a)
|
||||||
|
|
||||||
|
#define TracyMessage(x,y)
|
||||||
|
#define TracyMessageL(x)
|
||||||
|
#define TracyMessageC(x,y,z)
|
||||||
|
#define TracyMessageLC(x,y)
|
||||||
|
#define TracyAppInfo(x,y)
|
||||||
|
|
||||||
|
#define TracyAlloc(x,y)
|
||||||
|
#define TracyFree(x)
|
||||||
|
#define TracySecureAlloc(x,y)
|
||||||
|
#define TracySecureFree(x)
|
||||||
|
|
||||||
|
#define TracyAllocN(x,y,z)
|
||||||
|
#define TracyFreeN(x,y)
|
||||||
|
#define TracySecureAllocN(x,y,z)
|
||||||
|
#define TracySecureFreeN(x,y)
|
||||||
|
|
||||||
|
#define ZoneNamedS(x,y,z)
|
||||||
|
#define ZoneNamedNS(x,y,z,w)
|
||||||
|
#define ZoneNamedCS(x,y,z,w)
|
||||||
|
#define ZoneNamedNCS(x,y,z,w,a)
|
||||||
|
|
||||||
|
#define ZoneTransientS(x,y,z)
|
||||||
|
#define ZoneTransientNS(x,y,z,w)
|
||||||
|
|
||||||
|
#define ZoneScopedS(x)
|
||||||
|
#define ZoneScopedNS(x,y)
|
||||||
|
#define ZoneScopedCS(x,y)
|
||||||
|
#define ZoneScopedNCS(x,y,z)
|
||||||
|
|
||||||
|
#define TracyAllocS(x,y,z)
|
||||||
|
#define TracyFreeS(x,y)
|
||||||
|
#define TracySecureAllocS(x,y,z)
|
||||||
|
#define TracySecureFreeS(x,y)
|
||||||
|
|
||||||
|
#define TracyAllocNS(x,y,z,w)
|
||||||
|
#define TracyFreeNS(x,y,z)
|
||||||
|
#define TracySecureAllocNS(x,y,z,w)
|
||||||
|
#define TracySecureFreeNS(x,y,z)
|
||||||
|
|
||||||
|
#define TracyMessageS(x,y,z)
|
||||||
|
#define TracyMessageLS(x,y)
|
||||||
|
#define TracyMessageCS(x,y,z,w)
|
||||||
|
#define TracyMessageLCS(x,y,z)
|
||||||
|
|
||||||
|
#define TracySourceCallbackRegister(x,y)
|
||||||
|
#define TracyParameterRegister(x,y)
|
||||||
|
#define TracyParameterSetup(x,y,z,w)
|
||||||
|
#define TracyIsConnected false
|
||||||
|
#define TracyIsStarted false
|
||||||
|
#define TracySetProgramName(x)
|
||||||
|
|
||||||
|
#define TracyFiberEnter(x)
|
||||||
|
#define TracyFiberLeave
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../client/TracyLock.hpp"
|
||||||
|
#include "../client/TracyProfiler.hpp"
|
||||||
|
#include "../client/TracyScoped.hpp"
|
||||||
|
|
||||||
|
#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK
|
||||||
|
# define ZoneNamed( varname, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { nullptr, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), TRACY_CALLSTACK, active )
|
||||||
|
# define ZoneNamedN( varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), TRACY_CALLSTACK, active )
|
||||||
|
# define ZoneNamedC( varname, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { nullptr, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), TRACY_CALLSTACK, active )
|
||||||
|
# define ZoneNamedNC( varname, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), TRACY_CALLSTACK, active )
|
||||||
|
|
||||||
|
# define ZoneTransient( varname, active ) tracy::ScopedZone varname( TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), nullptr, 0, TRACY_CALLSTACK, active )
|
||||||
|
# define ZoneTransientN( varname, name, active ) tracy::ScopedZone varname( TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), TRACY_CALLSTACK, active )
|
||||||
|
#else
|
||||||
|
# define ZoneNamed( varname, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { nullptr, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), active )
|
||||||
|
# define ZoneNamedN( varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), active )
|
||||||
|
# define ZoneNamedC( varname, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { nullptr, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), active )
|
||||||
|
# define ZoneNamedNC( varname, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), active )
|
||||||
|
|
||||||
|
# define ZoneTransient( varname, active ) tracy::ScopedZone varname( TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), nullptr, 0, active )
|
||||||
|
# define ZoneTransientN( varname, name, active ) tracy::ScopedZone varname( TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), active )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ZoneScoped ZoneNamed( ___tracy_scoped_zone, true )
|
||||||
|
#define ZoneScopedN( name ) ZoneNamedN( ___tracy_scoped_zone, name, true )
|
||||||
|
#define ZoneScopedC( color ) ZoneNamedC( ___tracy_scoped_zone, color, true )
|
||||||
|
#define ZoneScopedNC( name, color ) ZoneNamedNC( ___tracy_scoped_zone, name, color, true )
|
||||||
|
|
||||||
|
#define ZoneText( txt, size ) ___tracy_scoped_zone.Text( txt, size )
|
||||||
|
#define ZoneTextV( varname, txt, size ) varname.Text( txt, size )
|
||||||
|
#define ZoneName( txt, size ) ___tracy_scoped_zone.Name( txt, size )
|
||||||
|
#define ZoneNameV( varname, txt, size ) varname.Name( txt, size )
|
||||||
|
#define ZoneColor( color ) ___tracy_scoped_zone.Color( color )
|
||||||
|
#define ZoneColorV( varname, color ) varname.Color( color )
|
||||||
|
#define ZoneValue( value ) ___tracy_scoped_zone.Value( value )
|
||||||
|
#define ZoneValueV( varname, value ) varname.Value( value )
|
||||||
|
#define ZoneIsActive ___tracy_scoped_zone.IsActive()
|
||||||
|
#define ZoneIsActiveV( varname ) varname.IsActive()
|
||||||
|
|
||||||
|
#define FrameMark tracy::Profiler::SendFrameMark( nullptr )
|
||||||
|
#define FrameMarkNamed( name ) tracy::Profiler::SendFrameMark( name )
|
||||||
|
#define FrameMarkStart( name ) tracy::Profiler::SendFrameMark( name, tracy::QueueType::FrameMarkMsgStart )
|
||||||
|
#define FrameMarkEnd( name ) tracy::Profiler::SendFrameMark( name, tracy::QueueType::FrameMarkMsgEnd )
|
||||||
|
|
||||||
|
#define FrameImage( image, width, height, offset, flip ) tracy::Profiler::SendFrameImage( image, width, height, offset, flip )
|
||||||
|
|
||||||
|
#define TracyLockable( type, varname ) tracy::Lockable<type> varname { [] () -> const tracy::SourceLocationData* { static constexpr tracy::SourceLocationData srcloc { nullptr, #type " " #varname, TracyFile, TracyLine, 0 }; return &srcloc; }() }
|
||||||
|
#define TracyLockableN( type, varname, desc ) tracy::Lockable<type> varname { [] () -> const tracy::SourceLocationData* { static constexpr tracy::SourceLocationData srcloc { nullptr, desc, TracyFile, TracyLine, 0 }; return &srcloc; }() }
|
||||||
|
#define TracySharedLockable( type, varname ) tracy::SharedLockable<type> varname { [] () -> const tracy::SourceLocationData* { static constexpr tracy::SourceLocationData srcloc { nullptr, #type " " #varname, TracyFile, TracyLine, 0 }; return &srcloc; }() }
|
||||||
|
#define TracySharedLockableN( type, varname, desc ) tracy::SharedLockable<type> varname { [] () -> const tracy::SourceLocationData* { static constexpr tracy::SourceLocationData srcloc { nullptr, desc, TracyFile, TracyLine, 0 }; return &srcloc; }() }
|
||||||
|
#define LockableBase( type ) tracy::Lockable<type>
|
||||||
|
#define SharedLockableBase( type ) tracy::SharedLockable<type>
|
||||||
|
#define LockMark( varname ) static constexpr tracy::SourceLocationData __tracy_lock_location_##varname { nullptr, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; varname.Mark( &__tracy_lock_location_##varname )
|
||||||
|
#define LockableName( varname, txt, size ) varname.CustomName( txt, size )
|
||||||
|
|
||||||
|
#define TracyPlot( name, val ) tracy::Profiler::PlotData( name, val )
|
||||||
|
#define TracyPlotConfig( name, type, step, fill, color ) tracy::Profiler::ConfigurePlot( name, type, step, fill, color )
|
||||||
|
|
||||||
|
#define TracyAppInfo( txt, size ) tracy::Profiler::MessageAppInfo( txt, size )
|
||||||
|
|
||||||
|
#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK
|
||||||
|
# define TracyMessage( txt, size ) tracy::Profiler::Message( txt, size, TRACY_CALLSTACK )
|
||||||
|
# define TracyMessageL( txt ) tracy::Profiler::Message( txt, TRACY_CALLSTACK )
|
||||||
|
# define TracyMessageC( txt, size, color ) tracy::Profiler::MessageColor( txt, size, color, TRACY_CALLSTACK )
|
||||||
|
# define TracyMessageLC( txt, color ) tracy::Profiler::MessageColor( txt, color, TRACY_CALLSTACK )
|
||||||
|
|
||||||
|
# define TracyAlloc( ptr, size ) tracy::Profiler::MemAllocCallstack( ptr, size, TRACY_CALLSTACK, false )
|
||||||
|
# define TracyFree( ptr ) tracy::Profiler::MemFreeCallstack( ptr, TRACY_CALLSTACK, false )
|
||||||
|
# define TracySecureAlloc( ptr, size ) tracy::Profiler::MemAllocCallstack( ptr, size, TRACY_CALLSTACK, true )
|
||||||
|
# define TracySecureFree( ptr ) tracy::Profiler::MemFreeCallstack( ptr, TRACY_CALLSTACK, true )
|
||||||
|
|
||||||
|
# define TracyAllocN( ptr, size, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, TRACY_CALLSTACK, false, name )
|
||||||
|
# define TracyFreeN( ptr, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, TRACY_CALLSTACK, false, name )
|
||||||
|
# define TracySecureAllocN( ptr, size, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, TRACY_CALLSTACK, true, name )
|
||||||
|
# define TracySecureFreeN( ptr, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, TRACY_CALLSTACK, true, name )
|
||||||
|
#else
|
||||||
|
# define TracyMessage( txt, size ) tracy::Profiler::Message( txt, size, 0 )
|
||||||
|
# define TracyMessageL( txt ) tracy::Profiler::Message( txt, 0 )
|
||||||
|
# define TracyMessageC( txt, size, color ) tracy::Profiler::MessageColor( txt, size, color, 0 )
|
||||||
|
# define TracyMessageLC( txt, color ) tracy::Profiler::MessageColor( txt, color, 0 )
|
||||||
|
|
||||||
|
# define TracyAlloc( ptr, size ) tracy::Profiler::MemAlloc( ptr, size, false )
|
||||||
|
# define TracyFree( ptr ) tracy::Profiler::MemFree( ptr, false )
|
||||||
|
# define TracySecureAlloc( ptr, size ) tracy::Profiler::MemAlloc( ptr, size, true )
|
||||||
|
# define TracySecureFree( ptr ) tracy::Profiler::MemFree( ptr, true )
|
||||||
|
|
||||||
|
# define TracyAllocN( ptr, size, name ) tracy::Profiler::MemAllocNamed( ptr, size, false, name )
|
||||||
|
# define TracyFreeN( ptr, name ) tracy::Profiler::MemFreeNamed( ptr, false, name )
|
||||||
|
# define TracySecureAllocN( ptr, size, name ) tracy::Profiler::MemAllocNamed( ptr, size, true, name )
|
||||||
|
# define TracySecureFreeN( ptr, name ) tracy::Profiler::MemFreeNamed( ptr, true, name )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TRACY_HAS_CALLSTACK
|
||||||
|
# define ZoneNamedS( varname, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { nullptr, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), depth, active )
|
||||||
|
# define ZoneNamedNS( varname, name, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), depth, active )
|
||||||
|
# define ZoneNamedCS( varname, color, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { nullptr, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), depth, active )
|
||||||
|
# define ZoneNamedNCS( varname, name, color, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,TracyLine), depth, active )
|
||||||
|
|
||||||
|
# define ZoneTransientS( varname, depth, active ) tracy::ScopedZone varname( TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), nullptr, 0, depth, active )
|
||||||
|
# define ZoneTransientNS( varname, name, depth, active ) tracy::ScopedZone varname( TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), depth, active )
|
||||||
|
|
||||||
|
# define ZoneScopedS( depth ) ZoneNamedS( ___tracy_scoped_zone, depth, true )
|
||||||
|
# define ZoneScopedNS( name, depth ) ZoneNamedNS( ___tracy_scoped_zone, name, depth, true )
|
||||||
|
# define ZoneScopedCS( color, depth ) ZoneNamedCS( ___tracy_scoped_zone, color, depth, true )
|
||||||
|
# define ZoneScopedNCS( name, color, depth ) ZoneNamedNCS( ___tracy_scoped_zone, name, color, depth, true )
|
||||||
|
|
||||||
|
# define TracyAllocS( ptr, size, depth ) tracy::Profiler::MemAllocCallstack( ptr, size, depth, false )
|
||||||
|
# define TracyFreeS( ptr, depth ) tracy::Profiler::MemFreeCallstack( ptr, depth, false )
|
||||||
|
# define TracySecureAllocS( ptr, size, depth ) tracy::Profiler::MemAllocCallstack( ptr, size, depth, true )
|
||||||
|
# define TracySecureFreeS( ptr, depth ) tracy::Profiler::MemFreeCallstack( ptr, depth, true )
|
||||||
|
|
||||||
|
# define TracyAllocNS( ptr, size, depth, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, depth, false, name )
|
||||||
|
# define TracyFreeNS( ptr, depth, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, depth, false, name )
|
||||||
|
# define TracySecureAllocNS( ptr, size, depth, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, depth, true, name )
|
||||||
|
# define TracySecureFreeNS( ptr, depth, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, depth, true, name )
|
||||||
|
|
||||||
|
# define TracyMessageS( txt, size, depth ) tracy::Profiler::Message( txt, size, depth )
|
||||||
|
# define TracyMessageLS( txt, depth ) tracy::Profiler::Message( txt, depth )
|
||||||
|
# define TracyMessageCS( txt, size, color, depth ) tracy::Profiler::MessageColor( txt, size, color, depth )
|
||||||
|
# define TracyMessageLCS( txt, color, depth ) tracy::Profiler::MessageColor( txt, color, depth )
|
||||||
|
#else
|
||||||
|
# define ZoneNamedS( varname, depth, active ) ZoneNamed( varname, active )
|
||||||
|
# define ZoneNamedNS( varname, name, depth, active ) ZoneNamedN( varname, name, active )
|
||||||
|
# define ZoneNamedCS( varname, color, depth, active ) ZoneNamedC( varname, color, active )
|
||||||
|
# define ZoneNamedNCS( varname, name, color, depth, active ) ZoneNamedNC( varname, name, color, active )
|
||||||
|
|
||||||
|
# define ZoneTransientS( varname, depth, active ) ZoneTransient( varname, active )
|
||||||
|
# define ZoneTransientNS( varname, name, depth, active ) ZoneTransientN( varname, name, active )
|
||||||
|
|
||||||
|
# define ZoneScopedS( depth ) ZoneScoped
|
||||||
|
# define ZoneScopedNS( name, depth ) ZoneScopedN( name )
|
||||||
|
# define ZoneScopedCS( color, depth ) ZoneScopedC( color )
|
||||||
|
# define ZoneScopedNCS( name, color, depth ) ZoneScopedNC( name, color )
|
||||||
|
|
||||||
|
# define TracyAllocS( ptr, size, depth ) TracyAlloc( ptr, size )
|
||||||
|
# define TracyFreeS( ptr, depth ) TracyFree( ptr )
|
||||||
|
# define TracySecureAllocS( ptr, size, depth ) TracySecureAlloc( ptr, size )
|
||||||
|
# define TracySecureFreeS( ptr, depth ) TracySecureFree( ptr )
|
||||||
|
|
||||||
|
# define TracyAllocNS( ptr, size, depth, name ) TracyAllocN( ptr, size, name )
|
||||||
|
# define TracyFreeNS( ptr, depth, name ) TracyFreeN( ptr, name )
|
||||||
|
# define TracySecureAllocNS( ptr, size, depth, name ) TracySecureAllocN( ptr, size, name )
|
||||||
|
# define TracySecureFreeNS( ptr, depth, name ) TracySecureFreeN( ptr, name )
|
||||||
|
|
||||||
|
# define TracyMessageS( txt, size, depth ) TracyMessage( txt, size )
|
||||||
|
# define TracyMessageLS( txt, depth ) TracyMessageL( txt )
|
||||||
|
# define TracyMessageCS( txt, size, color, depth ) TracyMessageC( txt, size, color )
|
||||||
|
# define TracyMessageLCS( txt, color, depth ) TracyMessageLC( txt, color )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TracySourceCallbackRegister( cb, data ) tracy::Profiler::SourceCallbackRegister( cb, data )
|
||||||
|
#define TracyParameterRegister( cb, data ) tracy::Profiler::ParameterRegister( cb, data )
|
||||||
|
#define TracyParameterSetup( idx, name, isBool, val ) tracy::Profiler::ParameterSetup( idx, name, isBool, val )
|
||||||
|
#define TracyIsConnected tracy::GetProfiler().IsConnected()
|
||||||
|
#define TracySetProgramName( name ) tracy::GetProfiler().SetProgramName( name );
|
||||||
|
|
||||||
|
#ifdef TRACY_FIBERS
|
||||||
|
# define TracyFiberEnter( fiber ) tracy::Profiler::EnterFiber( fiber )
|
||||||
|
# define TracyFiberLeave tracy::Profiler::LeaveFiber()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
383
externals/tracy/public/tracy/TracyC.h
vendored
Normal file
383
externals/tracy/public/tracy/TracyC.h
vendored
Normal file
@ -0,0 +1,383 @@
|
|||||||
|
#ifndef __TRACYC_HPP__
|
||||||
|
#define __TRACYC_HPP__
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "../client/TracyCallstack.h"
|
||||||
|
#include "../common/TracyApi.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum TracyPlotFormatEnum
|
||||||
|
{
|
||||||
|
TracyPlotFormatNumber,
|
||||||
|
TracyPlotFormatMemory,
|
||||||
|
TracyPlotFormatPercentage,
|
||||||
|
TracyPlotFormatWatt
|
||||||
|
};
|
||||||
|
|
||||||
|
TRACY_API void ___tracy_set_thread_name( const char* name );
|
||||||
|
|
||||||
|
#define TracyCSetThreadName( name ) ___tracy_set_thread_name( name );
|
||||||
|
|
||||||
|
#ifndef TracyFunction
|
||||||
|
# define TracyFunction __FUNCTION__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TracyFile
|
||||||
|
# define TracyFile __FILE__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TracyLine
|
||||||
|
# define TracyLine __LINE__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TRACY_ENABLE
|
||||||
|
|
||||||
|
typedef const void* TracyCZoneCtx;
|
||||||
|
|
||||||
|
#define TracyCZone(c,x)
|
||||||
|
#define TracyCZoneN(c,x,y)
|
||||||
|
#define TracyCZoneC(c,x,y)
|
||||||
|
#define TracyCZoneNC(c,x,y,z)
|
||||||
|
#define TracyCZoneEnd(c)
|
||||||
|
#define TracyCZoneText(c,x,y)
|
||||||
|
#define TracyCZoneName(c,x,y)
|
||||||
|
#define TracyCZoneColor(c,x)
|
||||||
|
#define TracyCZoneValue(c,x)
|
||||||
|
|
||||||
|
#define TracyCAlloc(x,y)
|
||||||
|
#define TracyCFree(x)
|
||||||
|
#define TracyCSecureAlloc(x,y)
|
||||||
|
#define TracyCSecureFree(x)
|
||||||
|
|
||||||
|
#define TracyCAllocN(x,y,z)
|
||||||
|
#define TracyCFreeN(x,y)
|
||||||
|
#define TracyCSecureAllocN(x,y,z)
|
||||||
|
#define TracyCSecureFreeN(x,y)
|
||||||
|
|
||||||
|
#define TracyCFrameMark
|
||||||
|
#define TracyCFrameMarkNamed(x)
|
||||||
|
#define TracyCFrameMarkStart(x)
|
||||||
|
#define TracyCFrameMarkEnd(x)
|
||||||
|
#define TracyCFrameImage(x,y,z,w,a)
|
||||||
|
|
||||||
|
#define TracyCPlot(x,y)
|
||||||
|
#define TracyCPlotF(x,y)
|
||||||
|
#define TracyCPlotI(x,y)
|
||||||
|
#define TracyCPlotConfig(x,y,z,w,a)
|
||||||
|
|
||||||
|
#define TracyCMessage(x,y)
|
||||||
|
#define TracyCMessageL(x)
|
||||||
|
#define TracyCMessageC(x,y,z)
|
||||||
|
#define TracyCMessageLC(x,y)
|
||||||
|
#define TracyCAppInfo(x,y)
|
||||||
|
|
||||||
|
#define TracyCZoneS(x,y,z)
|
||||||
|
#define TracyCZoneNS(x,y,z,w)
|
||||||
|
#define TracyCZoneCS(x,y,z,w)
|
||||||
|
#define TracyCZoneNCS(x,y,z,w,a)
|
||||||
|
|
||||||
|
#define TracyCAllocS(x,y,z)
|
||||||
|
#define TracyCFreeS(x,y)
|
||||||
|
#define TracyCSecureAllocS(x,y,z)
|
||||||
|
#define TracyCSecureFreeS(x,y)
|
||||||
|
|
||||||
|
#define TracyCAllocNS(x,y,z,w)
|
||||||
|
#define TracyCFreeNS(x,y,z)
|
||||||
|
#define TracyCSecureAllocNS(x,y,z,w)
|
||||||
|
#define TracyCSecureFreeNS(x,y,z)
|
||||||
|
|
||||||
|
#define TracyCMessageS(x,y,z)
|
||||||
|
#define TracyCMessageLS(x,y)
|
||||||
|
#define TracyCMessageCS(x,y,z,w)
|
||||||
|
#define TracyCMessageLCS(x,y,z)
|
||||||
|
|
||||||
|
#define TracyCIsConnected 0
|
||||||
|
#define TracyCIsStarted 0
|
||||||
|
|
||||||
|
#ifdef TRACY_FIBERS
|
||||||
|
# define TracyCFiberEnter(fiber)
|
||||||
|
# define TracyCFiberLeave
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifndef TracyConcat
|
||||||
|
# define TracyConcat(x,y) TracyConcatIndirect(x,y)
|
||||||
|
#endif
|
||||||
|
#ifndef TracyConcatIndirect
|
||||||
|
# define TracyConcatIndirect(x,y) x##y
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct ___tracy_source_location_data
|
||||||
|
{
|
||||||
|
const char* name;
|
||||||
|
const char* function;
|
||||||
|
const char* file;
|
||||||
|
uint32_t line;
|
||||||
|
uint32_t color;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ___tracy_c_zone_context
|
||||||
|
{
|
||||||
|
uint32_t id;
|
||||||
|
int active;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ___tracy_gpu_time_data
|
||||||
|
{
|
||||||
|
int64_t gpuTime;
|
||||||
|
uint16_t queryId;
|
||||||
|
uint8_t context;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ___tracy_gpu_zone_begin_data {
|
||||||
|
uint64_t srcloc;
|
||||||
|
uint16_t queryId;
|
||||||
|
uint8_t context;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ___tracy_gpu_zone_begin_callstack_data {
|
||||||
|
uint64_t srcloc;
|
||||||
|
int depth;
|
||||||
|
uint16_t queryId;
|
||||||
|
uint8_t context;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ___tracy_gpu_zone_end_data {
|
||||||
|
uint16_t queryId;
|
||||||
|
uint8_t context;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ___tracy_gpu_new_context_data {
|
||||||
|
int64_t gpuTime;
|
||||||
|
float period;
|
||||||
|
uint8_t context;
|
||||||
|
uint8_t flags;
|
||||||
|
uint8_t type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ___tracy_gpu_context_name_data {
|
||||||
|
uint8_t context;
|
||||||
|
const char* name;
|
||||||
|
uint16_t len;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ___tracy_gpu_calibration_data {
|
||||||
|
int64_t gpuTime;
|
||||||
|
int64_t cpuDelta;
|
||||||
|
uint8_t context;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ___tracy_gpu_time_sync_data {
|
||||||
|
int64_t gpuTime;
|
||||||
|
uint8_t context;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Some containers don't support storing const types.
|
||||||
|
// This struct, as visible to user, is immutable, so treat it as if const was declared here.
|
||||||
|
typedef /*const*/ struct ___tracy_c_zone_context TracyCZoneCtx;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TRACY_MANUAL_LIFETIME
|
||||||
|
TRACY_API void ___tracy_startup_profiler(void);
|
||||||
|
TRACY_API void ___tracy_shutdown_profiler(void);
|
||||||
|
TRACY_API int ___tracy_profiler_started(void);
|
||||||
|
|
||||||
|
# define TracyCIsStarted ___tracy_profiler_started()
|
||||||
|
#else
|
||||||
|
# define TracyCIsStarted 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TRACY_API uint64_t ___tracy_alloc_srcloc( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz );
|
||||||
|
TRACY_API uint64_t ___tracy_alloc_srcloc_name( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz );
|
||||||
|
|
||||||
|
TRACY_API TracyCZoneCtx ___tracy_emit_zone_begin( const struct ___tracy_source_location_data* srcloc, int active );
|
||||||
|
TRACY_API TracyCZoneCtx ___tracy_emit_zone_begin_callstack( const struct ___tracy_source_location_data* srcloc, int depth, int active );
|
||||||
|
TRACY_API TracyCZoneCtx ___tracy_emit_zone_begin_alloc( uint64_t srcloc, int active );
|
||||||
|
TRACY_API TracyCZoneCtx ___tracy_emit_zone_begin_alloc_callstack( uint64_t srcloc, int depth, int active );
|
||||||
|
TRACY_API void ___tracy_emit_zone_end( TracyCZoneCtx ctx );
|
||||||
|
TRACY_API void ___tracy_emit_zone_text( TracyCZoneCtx ctx, const char* txt, size_t size );
|
||||||
|
TRACY_API void ___tracy_emit_zone_name( TracyCZoneCtx ctx, const char* txt, size_t size );
|
||||||
|
TRACY_API void ___tracy_emit_zone_color( TracyCZoneCtx ctx, uint32_t color );
|
||||||
|
TRACY_API void ___tracy_emit_zone_value( TracyCZoneCtx ctx, uint64_t value );
|
||||||
|
|
||||||
|
TRACY_API void ___tracy_emit_gpu_zone_begin( const struct ___tracy_gpu_zone_begin_data );
|
||||||
|
TRACY_API void ___tracy_emit_gpu_zone_begin_callstack( const struct ___tracy_gpu_zone_begin_callstack_data );
|
||||||
|
TRACY_API void ___tracy_emit_gpu_zone_begin_alloc( const struct ___tracy_gpu_zone_begin_data );
|
||||||
|
TRACY_API void ___tracy_emit_gpu_zone_begin_alloc_callstack( const struct ___tracy_gpu_zone_begin_callstack_data );
|
||||||
|
TRACY_API void ___tracy_emit_gpu_zone_end( const struct ___tracy_gpu_zone_end_data data );
|
||||||
|
TRACY_API void ___tracy_emit_gpu_time( const struct ___tracy_gpu_time_data );
|
||||||
|
TRACY_API void ___tracy_emit_gpu_new_context( const struct ___tracy_gpu_new_context_data );
|
||||||
|
TRACY_API void ___tracy_emit_gpu_context_name( const struct ___tracy_gpu_context_name_data );
|
||||||
|
TRACY_API void ___tracy_emit_gpu_calibration( const struct ___tracy_gpu_calibration_data );
|
||||||
|
TRACY_API void ___tracy_emit_gpu_time_sync( const struct ___tracy_gpu_time_sync_data );
|
||||||
|
|
||||||
|
TRACY_API void ___tracy_emit_gpu_zone_begin_serial( const struct ___tracy_gpu_zone_begin_data );
|
||||||
|
TRACY_API void ___tracy_emit_gpu_zone_begin_callstack_serial( const struct ___tracy_gpu_zone_begin_callstack_data );
|
||||||
|
TRACY_API void ___tracy_emit_gpu_zone_begin_alloc_serial( const struct ___tracy_gpu_zone_begin_data );
|
||||||
|
TRACY_API void ___tracy_emit_gpu_zone_begin_alloc_callstack_serial( const struct ___tracy_gpu_zone_begin_callstack_data );
|
||||||
|
TRACY_API void ___tracy_emit_gpu_zone_end_serial( const struct ___tracy_gpu_zone_end_data data );
|
||||||
|
TRACY_API void ___tracy_emit_gpu_time_serial( const struct ___tracy_gpu_time_data );
|
||||||
|
TRACY_API void ___tracy_emit_gpu_new_context_serial( const struct ___tracy_gpu_new_context_data );
|
||||||
|
TRACY_API void ___tracy_emit_gpu_context_name_serial( const struct ___tracy_gpu_context_name_data );
|
||||||
|
TRACY_API void ___tracy_emit_gpu_calibration_serial( const struct ___tracy_gpu_calibration_data );
|
||||||
|
TRACY_API void ___tracy_emit_gpu_time_sync_serial( const struct ___tracy_gpu_time_sync_data );
|
||||||
|
|
||||||
|
TRACY_API int ___tracy_connected(void);
|
||||||
|
|
||||||
|
#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK
|
||||||
|
# define TracyCZone( ctx, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { NULL, __func__, TracyFile, (uint32_t)TracyLine, 0 }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,TracyLine), TRACY_CALLSTACK, active );
|
||||||
|
# define TracyCZoneN( ctx, name, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { name, __func__, TracyFile, (uint32_t)TracyLine, 0 }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,TracyLine), TRACY_CALLSTACK, active );
|
||||||
|
# define TracyCZoneC( ctx, color, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { NULL, __func__, TracyFile, (uint32_t)TracyLine, color }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,TracyLine), TRACY_CALLSTACK, active );
|
||||||
|
# define TracyCZoneNC( ctx, name, color, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { name, __func__, TracyFile, (uint32_t)TracyLine, color }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,TracyLine), TRACY_CALLSTACK, active );
|
||||||
|
#else
|
||||||
|
# define TracyCZone( ctx, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { NULL, __func__, TracyFile, (uint32_t)TracyLine, 0 }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin( &TracyConcat(__tracy_source_location,TracyLine), active );
|
||||||
|
# define TracyCZoneN( ctx, name, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { name, __func__, TracyFile, (uint32_t)TracyLine, 0 }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin( &TracyConcat(__tracy_source_location,TracyLine), active );
|
||||||
|
# define TracyCZoneC( ctx, color, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { NULL, __func__, TracyFile, (uint32_t)TracyLine, color }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin( &TracyConcat(__tracy_source_location,TracyLine), active );
|
||||||
|
# define TracyCZoneNC( ctx, name, color, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { name, __func__, TracyFile, (uint32_t)TracyLine, color }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin( &TracyConcat(__tracy_source_location,TracyLine), active );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TracyCZoneEnd( ctx ) ___tracy_emit_zone_end( ctx );
|
||||||
|
|
||||||
|
#define TracyCZoneText( ctx, txt, size ) ___tracy_emit_zone_text( ctx, txt, size );
|
||||||
|
#define TracyCZoneName( ctx, txt, size ) ___tracy_emit_zone_name( ctx, txt, size );
|
||||||
|
#define TracyCZoneColor( ctx, color ) ___tracy_emit_zone_color( ctx, color );
|
||||||
|
#define TracyCZoneValue( ctx, value ) ___tracy_emit_zone_value( ctx, value );
|
||||||
|
|
||||||
|
|
||||||
|
TRACY_API void ___tracy_emit_memory_alloc( const void* ptr, size_t size, int secure );
|
||||||
|
TRACY_API void ___tracy_emit_memory_alloc_callstack( const void* ptr, size_t size, int depth, int secure );
|
||||||
|
TRACY_API void ___tracy_emit_memory_free( const void* ptr, int secure );
|
||||||
|
TRACY_API void ___tracy_emit_memory_free_callstack( const void* ptr, int depth, int secure );
|
||||||
|
TRACY_API void ___tracy_emit_memory_alloc_named( const void* ptr, size_t size, int secure, const char* name );
|
||||||
|
TRACY_API void ___tracy_emit_memory_alloc_callstack_named( const void* ptr, size_t size, int depth, int secure, const char* name );
|
||||||
|
TRACY_API void ___tracy_emit_memory_free_named( const void* ptr, int secure, const char* name );
|
||||||
|
TRACY_API void ___tracy_emit_memory_free_callstack_named( const void* ptr, int depth, int secure, const char* name );
|
||||||
|
|
||||||
|
TRACY_API void ___tracy_emit_message( const char* txt, size_t size, int callstack );
|
||||||
|
TRACY_API void ___tracy_emit_messageL( const char* txt, int callstack );
|
||||||
|
TRACY_API void ___tracy_emit_messageC( const char* txt, size_t size, uint32_t color, int callstack );
|
||||||
|
TRACY_API void ___tracy_emit_messageLC( const char* txt, uint32_t color, int callstack );
|
||||||
|
|
||||||
|
#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK
|
||||||
|
# define TracyCAlloc( ptr, size ) ___tracy_emit_memory_alloc_callstack( ptr, size, TRACY_CALLSTACK, 0 )
|
||||||
|
# define TracyCFree( ptr ) ___tracy_emit_memory_free_callstack( ptr, TRACY_CALLSTACK, 0 )
|
||||||
|
# define TracyCSecureAlloc( ptr, size ) ___tracy_emit_memory_alloc_callstack( ptr, size, TRACY_CALLSTACK, 1 )
|
||||||
|
# define TracyCSecureFree( ptr ) ___tracy_emit_memory_free_callstack( ptr, TRACY_CALLSTACK, 1 )
|
||||||
|
|
||||||
|
# define TracyCAllocN( ptr, size, name ) ___tracy_emit_memory_alloc_callstack_named( ptr, size, TRACY_CALLSTACK, 0, name )
|
||||||
|
# define TracyCFreeN( ptr, name ) ___tracy_emit_memory_free_callstack_named( ptr, TRACY_CALLSTACK, 0, name )
|
||||||
|
# define TracyCSecureAllocN( ptr, size, name ) ___tracy_emit_memory_alloc_callstack_named( ptr, size, TRACY_CALLSTACK, 1, name )
|
||||||
|
# define TracyCSecureFreeN( ptr, name ) ___tracy_emit_memory_free_callstack_named( ptr, TRACY_CALLSTACK, 1, name )
|
||||||
|
|
||||||
|
# define TracyCMessage( txt, size ) ___tracy_emit_message( txt, size, TRACY_CALLSTACK );
|
||||||
|
# define TracyCMessageL( txt ) ___tracy_emit_messageL( txt, TRACY_CALLSTACK );
|
||||||
|
# define TracyCMessageC( txt, size, color ) ___tracy_emit_messageC( txt, size, color, TRACY_CALLSTACK );
|
||||||
|
# define TracyCMessageLC( txt, color ) ___tracy_emit_messageLC( txt, color, TRACY_CALLSTACK );
|
||||||
|
#else
|
||||||
|
# define TracyCAlloc( ptr, size ) ___tracy_emit_memory_alloc( ptr, size, 0 );
|
||||||
|
# define TracyCFree( ptr ) ___tracy_emit_memory_free( ptr, 0 );
|
||||||
|
# define TracyCSecureAlloc( ptr, size ) ___tracy_emit_memory_alloc( ptr, size, 1 );
|
||||||
|
# define TracyCSecureFree( ptr ) ___tracy_emit_memory_free( ptr, 1 );
|
||||||
|
|
||||||
|
# define TracyCAllocN( ptr, size, name ) ___tracy_emit_memory_alloc_named( ptr, size, 0, name );
|
||||||
|
# define TracyCFreeN( ptr, name ) ___tracy_emit_memory_free_named( ptr, 0, name );
|
||||||
|
# define TracyCSecureAllocN( ptr, size, name ) ___tracy_emit_memory_alloc_named( ptr, size, 1, name );
|
||||||
|
# define TracyCSecureFreeN( ptr, name ) ___tracy_emit_memory_free_named( ptr, 1, name );
|
||||||
|
|
||||||
|
# define TracyCMessage( txt, size ) ___tracy_emit_message( txt, size, 0 );
|
||||||
|
# define TracyCMessageL( txt ) ___tracy_emit_messageL( txt, 0 );
|
||||||
|
# define TracyCMessageC( txt, size, color ) ___tracy_emit_messageC( txt, size, color, 0 );
|
||||||
|
# define TracyCMessageLC( txt, color ) ___tracy_emit_messageLC( txt, color, 0 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
TRACY_API void ___tracy_emit_frame_mark( const char* name );
|
||||||
|
TRACY_API void ___tracy_emit_frame_mark_start( const char* name );
|
||||||
|
TRACY_API void ___tracy_emit_frame_mark_end( const char* name );
|
||||||
|
TRACY_API void ___tracy_emit_frame_image( const void* image, uint16_t w, uint16_t h, uint8_t offset, int flip );
|
||||||
|
|
||||||
|
#define TracyCFrameMark ___tracy_emit_frame_mark( 0 );
|
||||||
|
#define TracyCFrameMarkNamed( name ) ___tracy_emit_frame_mark( name );
|
||||||
|
#define TracyCFrameMarkStart( name ) ___tracy_emit_frame_mark_start( name );
|
||||||
|
#define TracyCFrameMarkEnd( name ) ___tracy_emit_frame_mark_end( name );
|
||||||
|
#define TracyCFrameImage( image, width, height, offset, flip ) ___tracy_emit_frame_image( image, width, height, offset, flip );
|
||||||
|
|
||||||
|
|
||||||
|
TRACY_API void ___tracy_emit_plot( const char* name, double val );
|
||||||
|
TRACY_API void ___tracy_emit_plot_float( const char* name, float val );
|
||||||
|
TRACY_API void ___tracy_emit_plot_int( const char* name, int64_t val );
|
||||||
|
TRACY_API void ___tracy_emit_plot_config( const char* name, int type, int step, int fill, uint32_t color );
|
||||||
|
TRACY_API void ___tracy_emit_message_appinfo( const char* txt, size_t size );
|
||||||
|
|
||||||
|
#define TracyCPlot( name, val ) ___tracy_emit_plot( name, val );
|
||||||
|
#define TracyCPlotF( name, val ) ___tracy_emit_plot_float( name, val );
|
||||||
|
#define TracyCPlotI( name, val ) ___tracy_emit_plot_int( name, val );
|
||||||
|
#define TracyCPlotConfig( name, type, step, fill, color ) ___tracy_emit_plot_config( name, type, step, fill, color );
|
||||||
|
#define TracyCAppInfo( txt, size ) ___tracy_emit_message_appinfo( txt, size );
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TRACY_HAS_CALLSTACK
|
||||||
|
# define TracyCZoneS( ctx, depth, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { NULL, __func__, TracyFile, (uint32_t)TracyLine, 0 }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,TracyLine), depth, active );
|
||||||
|
# define TracyCZoneNS( ctx, name, depth, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { name, __func__, TracyFile, (uint32_t)TracyLine, 0 }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,TracyLine), depth, active );
|
||||||
|
# define TracyCZoneCS( ctx, color, depth, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { NULL, __func__, TracyFile, (uint32_t)TracyLine, color }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,TracyLine), depth, active );
|
||||||
|
# define TracyCZoneNCS( ctx, name, color, depth, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,TracyLine) = { name, __func__, TracyFile, (uint32_t)TracyLine, color }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,TracyLine), depth, active );
|
||||||
|
|
||||||
|
# define TracyCAllocS( ptr, size, depth ) ___tracy_emit_memory_alloc_callstack( ptr, size, depth, 0 )
|
||||||
|
# define TracyCFreeS( ptr, depth ) ___tracy_emit_memory_free_callstack( ptr, depth, 0 )
|
||||||
|
# define TracyCSecureAllocS( ptr, size, depth ) ___tracy_emit_memory_alloc_callstack( ptr, size, depth, 1 )
|
||||||
|
# define TracyCSecureFreeS( ptr, depth ) ___tracy_emit_memory_free_callstack( ptr, depth, 1 )
|
||||||
|
|
||||||
|
# define TracyCAllocNS( ptr, size, depth, name ) ___tracy_emit_memory_alloc_callstack_named( ptr, size, depth, 0, name )
|
||||||
|
# define TracyCFreeNS( ptr, depth, name ) ___tracy_emit_memory_free_callstack_named( ptr, depth, 0, name )
|
||||||
|
# define TracyCSecureAllocNS( ptr, size, depth, name ) ___tracy_emit_memory_alloc_callstack_named( ptr, size, depth, 1, name )
|
||||||
|
# define TracyCSecureFreeNS( ptr, depth, name ) ___tracy_emit_memory_free_callstack_named( ptr, depth, 1, name )
|
||||||
|
|
||||||
|
# define TracyCMessageS( txt, size, depth ) ___tracy_emit_message( txt, size, depth );
|
||||||
|
# define TracyCMessageLS( txt, depth ) ___tracy_emit_messageL( txt, depth );
|
||||||
|
# define TracyCMessageCS( txt, size, color, depth ) ___tracy_emit_messageC( txt, size, color, depth );
|
||||||
|
# define TracyCMessageLCS( txt, color, depth ) ___tracy_emit_messageLC( txt, color, depth );
|
||||||
|
#else
|
||||||
|
# define TracyCZoneS( ctx, depth, active ) TracyCZone( ctx, active )
|
||||||
|
# define TracyCZoneNS( ctx, name, depth, active ) TracyCZoneN( ctx, name, active )
|
||||||
|
# define TracyCZoneCS( ctx, color, depth, active ) TracyCZoneC( ctx, color, active )
|
||||||
|
# define TracyCZoneNCS( ctx, name, color, depth, active ) TracyCZoneNC( ctx, name, color, active )
|
||||||
|
|
||||||
|
# define TracyCAllocS( ptr, size, depth ) TracyCAlloc( ptr, size )
|
||||||
|
# define TracyCFreeS( ptr, depth ) TracyCFree( ptr )
|
||||||
|
# define TracyCSecureAllocS( ptr, size, depth ) TracyCSecureAlloc( ptr, size )
|
||||||
|
# define TracyCSecureFreeS( ptr, depth ) TracyCSecureFree( ptr )
|
||||||
|
|
||||||
|
# define TracyCAllocNS( ptr, size, depth, name ) TracyCAllocN( ptr, size, name )
|
||||||
|
# define TracyCFreeNS( ptr, depth, name ) TracyCFreeN( ptr, name )
|
||||||
|
# define TracyCSecureAllocNS( ptr, size, depth, name ) TracyCSecureAllocN( ptr, size, name )
|
||||||
|
# define TracyCSecureFreeNS( ptr, depth, name ) TracyCSecureFreeN( ptr, name )
|
||||||
|
|
||||||
|
# define TracyCMessageS( txt, size, depth ) TracyCMessage( txt, size )
|
||||||
|
# define TracyCMessageLS( txt, depth ) TracyCMessageL( txt )
|
||||||
|
# define TracyCMessageCS( txt, size, color, depth ) TracyCMessageC( txt, size, color )
|
||||||
|
# define TracyCMessageLCS( txt, color, depth ) TracyCMessageLC( txt, color )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TracyCIsConnected ___tracy_connected()
|
||||||
|
|
||||||
|
#ifdef TRACY_FIBERS
|
||||||
|
TRACY_API void ___tracy_fiber_enter( const char* fiber );
|
||||||
|
TRACY_API void ___tracy_fiber_leave( void );
|
||||||
|
|
||||||
|
# define TracyCFiberEnter( fiber ) ___tracy_fiber_enter( fiber );
|
||||||
|
# define TracyCFiberLeave ___tracy_fiber_leave();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
446
externals/tracy/public/tracy/TracyD3D11.hpp
vendored
Normal file
446
externals/tracy/public/tracy/TracyD3D11.hpp
vendored
Normal file
@ -0,0 +1,446 @@
|
|||||||
|
#ifndef __TRACYD3D11_HPP__
|
||||||
|
#define __TRACYD3D11_HPP__
|
||||||
|
|
||||||
|
#ifndef TRACY_ENABLE
|
||||||
|
|
||||||
|
#define TracyD3D11Context(device,queue) nullptr
|
||||||
|
#define TracyD3D11Destroy(ctx)
|
||||||
|
#define TracyD3D11ContextName(ctx, name, size)
|
||||||
|
|
||||||
|
#define TracyD3D11NewFrame(ctx)
|
||||||
|
|
||||||
|
#define TracyD3D11Zone(ctx, name)
|
||||||
|
#define TracyD3D11ZoneC(ctx, name, color)
|
||||||
|
#define TracyD3D11NamedZone(ctx, varname, name, active)
|
||||||
|
#define TracyD3D11NamedZoneC(ctx, varname, name, color, active)
|
||||||
|
#define TracyD3D11ZoneTransient(ctx, varname, name, active)
|
||||||
|
|
||||||
|
#define TracyD3D11ZoneS(ctx, name, depth)
|
||||||
|
#define TracyD3D11ZoneCS(ctx, name, color, depth)
|
||||||
|
#define TracyD3D11NamedZoneS(ctx, varname, name, depth, active)
|
||||||
|
#define TracyD3D11NamedZoneCS(ctx, varname, name, color, depth, active)
|
||||||
|
#define TracyD3D11ZoneTransientS(ctx, varname, name, depth, active)
|
||||||
|
|
||||||
|
#define TracyD3D11Collect(ctx)
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
class D3D11ZoneScope {};
|
||||||
|
}
|
||||||
|
|
||||||
|
using TracyD3D11Ctx = void*;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "Tracy.hpp"
|
||||||
|
#include "../client/TracyProfiler.hpp"
|
||||||
|
#include "../client/TracyCallstack.hpp"
|
||||||
|
#include "../common/TracyYield.hpp"
|
||||||
|
|
||||||
|
#include <d3d11.h>
|
||||||
|
|
||||||
|
#define TracyD3D11Panic(msg, ...) do { assert(false && "TracyD3D11: " msg); TracyMessageLC("TracyD3D11: " msg, tracy::Color::Red4); __VA_ARGS__; } while(false);
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
class D3D11Ctx
|
||||||
|
{
|
||||||
|
friend class D3D11ZoneScope;
|
||||||
|
|
||||||
|
static constexpr uint32_t MaxQueries = 64 * 1024;
|
||||||
|
|
||||||
|
enum CollectMode { POLL, BLOCK };
|
||||||
|
|
||||||
|
public:
|
||||||
|
D3D11Ctx( ID3D11Device* device, ID3D11DeviceContext* devicectx )
|
||||||
|
{
|
||||||
|
// TODO: consider calling ID3D11Device::GetImmediateContext() instead of passing it as an argument
|
||||||
|
m_device = device;
|
||||||
|
device->AddRef();
|
||||||
|
m_immediateDevCtx = devicectx;
|
||||||
|
devicectx->AddRef();
|
||||||
|
|
||||||
|
{
|
||||||
|
D3D11_QUERY_DESC desc = { };
|
||||||
|
desc.Query = D3D11_QUERY_TIMESTAMP_DISJOINT;
|
||||||
|
if (FAILED(m_device->CreateQuery(&desc, &m_disjointQuery)))
|
||||||
|
{
|
||||||
|
TracyD3D11Panic("unable to create disjoint timestamp query.", return);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ID3D11Query*& query : m_queries)
|
||||||
|
{
|
||||||
|
D3D11_QUERY_DESC desc = { };
|
||||||
|
desc.Query = D3D11_QUERY_TIMESTAMP;
|
||||||
|
if (FAILED(m_device->CreateQuery(&desc, &query)))
|
||||||
|
{
|
||||||
|
TracyD3D11Panic("unable to create timestamp query.", return);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calibrate CPU and GPU timestamps
|
||||||
|
int64_t tcpu = 0;
|
||||||
|
int64_t tgpu = 0;
|
||||||
|
for (int attempts = 0; attempts < 50; attempts++)
|
||||||
|
{
|
||||||
|
m_immediateDevCtx->Begin(m_disjointQuery);
|
||||||
|
m_immediateDevCtx->End(m_queries[0]);
|
||||||
|
m_immediateDevCtx->End(m_disjointQuery);
|
||||||
|
|
||||||
|
int64_t tcpu0 = Profiler::GetTime();
|
||||||
|
WaitForQuery(m_disjointQuery);
|
||||||
|
int64_t tcpu1 = Profiler::GetTime();
|
||||||
|
|
||||||
|
D3D11_QUERY_DATA_TIMESTAMP_DISJOINT disjoint = { };
|
||||||
|
if (m_immediateDevCtx->GetData(m_disjointQuery, &disjoint, sizeof(disjoint), 0) != S_OK)
|
||||||
|
{
|
||||||
|
TracyMessageLC("TracyD3D11: unable to query GPU timestamp; retrying...", tracy::Color::Tomato);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disjoint.Disjoint)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
UINT64 timestamp = 0;
|
||||||
|
if (m_immediateDevCtx->GetData(m_queries[0], ×tamp, sizeof(timestamp), 0) != S_OK)
|
||||||
|
continue; // this should never happen, since the enclosing disjoint query succeeded
|
||||||
|
|
||||||
|
tcpu = tcpu0 + (tcpu1 - tcpu0) * 1 / 2;
|
||||||
|
tgpu = timestamp * (1000000000 / disjoint.Frequency);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ready to roll
|
||||||
|
m_contextId = GetGpuCtxCounter().fetch_add(1);
|
||||||
|
m_immediateDevCtx->Begin(m_disjointQuery);
|
||||||
|
m_previousCheckpoint = m_nextCheckpoint = 0;
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuNewContext );
|
||||||
|
MemWrite( &item->gpuNewContext.cpuTime, tcpu );
|
||||||
|
MemWrite( &item->gpuNewContext.gpuTime, tgpu );
|
||||||
|
MemWrite( &item->gpuNewContext.thread, uint32_t(0) ); // #TODO: why not GetThreadHandle()?
|
||||||
|
MemWrite( &item->gpuNewContext.period, 1.0f );
|
||||||
|
MemWrite( &item->gpuNewContext.context, m_contextId);
|
||||||
|
MemWrite( &item->gpuNewContext.flags, uint8_t(0) );
|
||||||
|
MemWrite( &item->gpuNewContext.type, GpuContextType::Direct3D11 );
|
||||||
|
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
GetProfiler().DeferItem( *item );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
~D3D11Ctx()
|
||||||
|
{
|
||||||
|
// collect all pending timestamps before destroying everything
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Collect(BLOCK);
|
||||||
|
} while (m_previousCheckpoint != m_queryCounter);
|
||||||
|
|
||||||
|
for (ID3D11Query* query : m_queries)
|
||||||
|
{
|
||||||
|
query->Release();
|
||||||
|
}
|
||||||
|
m_immediateDevCtx->End(m_disjointQuery);
|
||||||
|
m_disjointQuery->Release();
|
||||||
|
m_immediateDevCtx->Release();
|
||||||
|
m_device->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Name( const char* name, uint16_t len )
|
||||||
|
{
|
||||||
|
auto ptr = (char*)tracy_malloc( len );
|
||||||
|
memcpy( ptr, name, len );
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuContextName );
|
||||||
|
MemWrite( &item->gpuContextNameFat.context, m_contextId );
|
||||||
|
MemWrite( &item->gpuContextNameFat.ptr, (uint64_t)ptr );
|
||||||
|
MemWrite( &item->gpuContextNameFat.size, len );
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
GetProfiler().DeferItem( *item );
|
||||||
|
#endif
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Collect(CollectMode mode = POLL)
|
||||||
|
{
|
||||||
|
ZoneScopedC( Color::Red4 );
|
||||||
|
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if( !GetProfiler().IsConnected() )
|
||||||
|
{
|
||||||
|
m_previousCheckpoint = m_nextCheckpoint = m_queryCounter;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (m_previousCheckpoint == m_nextCheckpoint)
|
||||||
|
{
|
||||||
|
uintptr_t nextCheckpoint = m_queryCounter;
|
||||||
|
if (nextCheckpoint == m_nextCheckpoint)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_nextCheckpoint = nextCheckpoint;
|
||||||
|
m_immediateDevCtx->End(m_disjointQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == CollectMode::BLOCK)
|
||||||
|
{
|
||||||
|
WaitForQuery(m_disjointQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D11_QUERY_DATA_TIMESTAMP_DISJOINT disjoint = { };
|
||||||
|
if (m_immediateDevCtx->GetData(m_disjointQuery, &disjoint, sizeof(disjoint), D3D11_ASYNC_GETDATA_DONOTFLUSH) != S_OK)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disjoint.Disjoint == TRUE)
|
||||||
|
{
|
||||||
|
m_previousCheckpoint = m_nextCheckpoint;
|
||||||
|
TracyD3D11Panic("disjoint timestamps detected; dropping.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto begin = m_previousCheckpoint;
|
||||||
|
auto end = m_nextCheckpoint;
|
||||||
|
for (auto i = begin; i != end; ++i)
|
||||||
|
{
|
||||||
|
uint32_t k = RingIndex(i);
|
||||||
|
UINT64 timestamp = 0;
|
||||||
|
if (m_immediateDevCtx->GetData(m_queries[k], ×tamp, sizeof(timestamp), 0) != S_OK)
|
||||||
|
{
|
||||||
|
TracyD3D11Panic("timestamp expected to be ready, but it was not!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
timestamp *= (1000000000ull / disjoint.Frequency);
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
MemWrite(&item->hdr.type, QueueType::GpuTime);
|
||||||
|
MemWrite(&item->gpuTime.gpuTime, static_cast<int64_t>(timestamp));
|
||||||
|
MemWrite(&item->gpuTime.queryId, static_cast<uint16_t>(k));
|
||||||
|
MemWrite(&item->gpuTime.context, m_contextId);
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
// disjoint timestamp queries should only be invoked once per frame or less
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/d3d11/ne-d3d11-d3d11_query
|
||||||
|
m_immediateDevCtx->Begin(m_disjointQuery);
|
||||||
|
m_previousCheckpoint = m_nextCheckpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
tracy_force_inline uint32_t RingIndex(uintptr_t index)
|
||||||
|
{
|
||||||
|
index %= MaxQueries;
|
||||||
|
return static_cast<uint32_t>(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline uint32_t RingCount(uintptr_t begin, uintptr_t end)
|
||||||
|
{
|
||||||
|
// wrap-around safe: all unsigned
|
||||||
|
uintptr_t count = end - begin;
|
||||||
|
return static_cast<uint32_t>(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline uint32_t NextQueryId()
|
||||||
|
{
|
||||||
|
auto id = m_queryCounter++;
|
||||||
|
if (RingCount(m_previousCheckpoint, id) >= MaxQueries)
|
||||||
|
{
|
||||||
|
TracyD3D11Panic("too many pending timestamp queries.");
|
||||||
|
// #TODO: return some sentinel value; ideally a "hidden" query index
|
||||||
|
}
|
||||||
|
return RingIndex(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline ID3D11Query* GetQueryObjectFromId(uint32_t id)
|
||||||
|
{
|
||||||
|
return m_queries[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void WaitForQuery(ID3D11Query* query)
|
||||||
|
{
|
||||||
|
m_immediateDevCtx->Flush();
|
||||||
|
while (m_immediateDevCtx->GetData(query, nullptr, 0, 0) != S_OK)
|
||||||
|
YieldThread(); // busy-wait :-( attempt to reduce power usage with _mm_pause() & friends...
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline uint8_t GetContextId() const
|
||||||
|
{
|
||||||
|
return m_contextId;
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D11Device* m_device = nullptr;
|
||||||
|
ID3D11DeviceContext* m_immediateDevCtx = nullptr;
|
||||||
|
|
||||||
|
ID3D11Query* m_queries[MaxQueries];
|
||||||
|
ID3D11Query* m_disjointQuery = nullptr;
|
||||||
|
|
||||||
|
uint8_t m_contextId = 255; // NOTE: apparently, 255 means invalid id; is this documented anywhere?
|
||||||
|
|
||||||
|
uintptr_t m_queryCounter = 0;
|
||||||
|
|
||||||
|
uintptr_t m_previousCheckpoint = 0;
|
||||||
|
uintptr_t m_nextCheckpoint = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class D3D11ZoneScope
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
tracy_force_inline D3D11ZoneScope( D3D11Ctx* ctx, const SourceLocationData* srcloc, bool active )
|
||||||
|
: D3D11ZoneScope(ctx, active)
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
WriteQueueItem(item, QueueType::GpuZoneBeginSerial, reinterpret_cast<uint64_t>(srcloc));
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline D3D11ZoneScope( D3D11Ctx* ctx, const SourceLocationData* srcloc, int depth, bool active )
|
||||||
|
: D3D11ZoneScope(ctx, active)
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerialCallstack(Callstack(depth));
|
||||||
|
WriteQueueItem(item, QueueType::GpuZoneBeginCallstackSerial, reinterpret_cast<uint64_t>(srcloc));
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline D3D11ZoneScope(D3D11Ctx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, bool active)
|
||||||
|
: D3D11ZoneScope(ctx, active)
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
|
||||||
|
const auto sourceLocation = Profiler::AllocSourceLocation(line, source, sourceSz, function, functionSz, name, nameSz);
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
WriteQueueItem(item, QueueType::GpuZoneBeginAllocSrcLocSerial, sourceLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline D3D11ZoneScope(D3D11Ctx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, int depth, bool active)
|
||||||
|
: D3D11ZoneScope(ctx, active)
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
|
||||||
|
const auto sourceLocation = Profiler::AllocSourceLocation(line, source, sourceSz, function, functionSz, name, nameSz);
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerialCallstack(Callstack(depth));
|
||||||
|
WriteQueueItem(item, QueueType::GpuZoneBeginAllocSrcLocCallstackSerial, sourceLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline ~D3D11ZoneScope()
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
|
||||||
|
const auto queryId = m_ctx->NextQueryId();
|
||||||
|
m_ctx->m_immediateDevCtx->End(m_ctx->GetQueryObjectFromId(queryId));
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuZoneEndSerial );
|
||||||
|
MemWrite( &item->gpuZoneEnd.cpuTime, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->gpuZoneEnd.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->gpuZoneEnd.queryId, uint16_t( queryId ) );
|
||||||
|
MemWrite( &item->gpuZoneEnd.context, m_ctx->GetContextId() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
tracy_force_inline D3D11ZoneScope( D3D11Ctx* ctx, bool active )
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active( is_active && GetProfiler().IsConnected() )
|
||||||
|
#else
|
||||||
|
: m_active( active )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
m_ctx = ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteQueueItem(tracy::QueueItem* item, tracy::QueueType queueItemType, uint64_t sourceLocation)
|
||||||
|
{
|
||||||
|
const auto queryId = m_ctx->NextQueryId();
|
||||||
|
m_ctx->m_immediateDevCtx->End(m_ctx->GetQueryObjectFromId(queryId));
|
||||||
|
|
||||||
|
MemWrite( &item->hdr.type, queueItemType);
|
||||||
|
MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.srcloc, sourceLocation );
|
||||||
|
MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) );
|
||||||
|
MemWrite( &item->gpuZoneBegin.context, m_ctx->GetContextId() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool m_active;
|
||||||
|
|
||||||
|
D3D11Ctx* m_ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline D3D11Ctx* CreateD3D11Context( ID3D11Device* device, ID3D11DeviceContext* devicectx )
|
||||||
|
{
|
||||||
|
auto ctx = (D3D11Ctx*)tracy_malloc( sizeof( D3D11Ctx ) );
|
||||||
|
new(ctx) D3D11Ctx( device, devicectx );
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void DestroyD3D11Context( D3D11Ctx* ctx )
|
||||||
|
{
|
||||||
|
ctx->~D3D11Ctx();
|
||||||
|
tracy_free( ctx );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef TracyD3D11Panic
|
||||||
|
|
||||||
|
using TracyD3D11Ctx = tracy::D3D11Ctx*;
|
||||||
|
|
||||||
|
#define TracyD3D11Context( device, devicectx ) tracy::CreateD3D11Context( device, devicectx );
|
||||||
|
#define TracyD3D11Destroy(ctx) tracy::DestroyD3D11Context(ctx);
|
||||||
|
#define TracyD3D11ContextName(ctx, name, size) ctx->Name(name, size);
|
||||||
|
|
||||||
|
#define TracyD3D11UnnamedZone ___tracy_gpu_d3d11_zone
|
||||||
|
#define TracyD3D11SrcLocSymbol TracyConcat(__tracy_gpu_d3d11_source_location,TracyLine)
|
||||||
|
#define TracyD3D11SrcLocObject(name, color) static constexpr tracy::SourceLocationData TracyD3D11SrcLocSymbol { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color };
|
||||||
|
|
||||||
|
#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK
|
||||||
|
# define TracyD3D11Zone( ctx, name ) TracyD3D11NamedZoneS( ctx, TracyD3D11UnnamedZone, name, TRACY_CALLSTACK, true )
|
||||||
|
# define TracyD3D11ZoneC( ctx, name, color ) TracyD3D11NamedZoneCS( ctx, TracyD3D11UnnamedZone, name, color, TRACY_CALLSTACK, true )
|
||||||
|
# define TracyD3D11NamedZone( ctx, varname, name, active ) TracyD3D11SrcLocObject(name, 0); tracy::D3D11ZoneScope varname( ctx, &TracyD3D11SrcLocSymbol, TRACY_CALLSTACK, active );
|
||||||
|
# define TracyD3D11NamedZoneC( ctx, varname, name, color, active ) TracyD3D11SrcLocObject(name, color); tracy::D3D11ZoneScope varname( ctx, &TracyD3D11SrcLocSymbol, TRACY_CALLSTACK, active );
|
||||||
|
# define TracyD3D11ZoneTransient(ctx, varname, name, active) TracyD3D11ZoneTransientS(ctx, varname, cmdList, name, TRACY_CALLSTACK, active)
|
||||||
|
#else
|
||||||
|
# define TracyD3D11Zone( ctx, name ) TracyD3D11NamedZone( ctx, TracyD3D11UnnamedZone, name, true )
|
||||||
|
# define TracyD3D11ZoneC( ctx, name, color ) TracyD3D11NamedZoneC( ctx, TracyD3D11UnnamedZone, name, color, true )
|
||||||
|
# define TracyD3D11NamedZone( ctx, varname, name, active ) TracyD3D11SrcLocObject(name, 0); tracy::D3D11ZoneScope varname( ctx, &TracyD3D11SrcLocSymbol, active );
|
||||||
|
# define TracyD3D11NamedZoneC( ctx, varname, name, color, active ) TracyD3D11SrcLocObject(name, color); tracy::D3D11ZoneScope varname( ctx, &TracyD3D11SrcLocSymbol, active );
|
||||||
|
# define TracyD3D11ZoneTransient(ctx, varname, name, active) tracy::D3D11ZoneScope varname{ ctx, TracyLine, TracyFile, strlen(TracyFile), TracyFunction, strlen(TracyFunction), name, strlen(name), active };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TRACY_HAS_CALLSTACK
|
||||||
|
# define TracyD3D11ZoneS( ctx, name, depth ) TracyD3D11NamedZoneS( ctx, TracyD3D11UnnamedZone, name, depth, true )
|
||||||
|
# define TracyD3D11ZoneCS( ctx, name, color, depth ) TracyD3D11NamedZoneCS( ctx, TracyD3D11UnnamedZone, name, color, depth, true )
|
||||||
|
# define TracyD3D11NamedZoneS( ctx, varname, name, depth, active ) TracyD3D11SrcLocObject(name, 0); tracy::D3D11ZoneScope varname( ctx, &TracyD3D11SrcLocSymbol, depth, active );
|
||||||
|
# define TracyD3D11NamedZoneCS( ctx, varname, name, color, depth, active ) TracyD3D11SrcLocObject(name, color); tracy::D3D11ZoneScope varname( ctx, &TracyD3D11SrcLocSymbol, depth, active );
|
||||||
|
# define TracyD3D11ZoneTransientS(ctx, varname, name, depth, active) tracy::D3D11ZoneScope varname{ ctx, TracyLine, TracyFile, strlen(TracyFile), TracyFunction, strlen(TracyFunction), name, strlen(name), depth, active };
|
||||||
|
#else
|
||||||
|
# define TracyD3D11ZoneS( ctx, name, depth, active ) TracyD3D11Zone( ctx, name )
|
||||||
|
# define TracyD3D11ZoneCS( ctx, name, color, depth, active ) TracyD3D11ZoneC( name, color )
|
||||||
|
# define TracyD3D11NamedZoneS( ctx, varname, name, depth, active ) TracyD3D11NamedZone( ctx, varname, name, active )
|
||||||
|
# define TracyD3D11NamedZoneCS( ctx, varname, name, color, depth, active ) TracyD3D11NamedZoneC( ctx, varname, name, color, active )
|
||||||
|
# define TracyD3D11ZoneTransientS(ctx, varname, name, depth, active) TracyD3D11ZoneTransient(ctx, varname, name, active)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TracyD3D11Collect( ctx ) ctx->Collect();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
500
externals/tracy/public/tracy/TracyD3D12.hpp
vendored
Normal file
500
externals/tracy/public/tracy/TracyD3D12.hpp
vendored
Normal file
@ -0,0 +1,500 @@
|
|||||||
|
#ifndef __TRACYD3D12_HPP__
|
||||||
|
#define __TRACYD3D12_HPP__
|
||||||
|
|
||||||
|
#ifndef TRACY_ENABLE
|
||||||
|
|
||||||
|
#define TracyD3D12Context(device, queue) nullptr
|
||||||
|
#define TracyD3D12Destroy(ctx)
|
||||||
|
#define TracyD3D12ContextName(ctx, name, size)
|
||||||
|
|
||||||
|
#define TracyD3D12NewFrame(ctx)
|
||||||
|
|
||||||
|
#define TracyD3D12Zone(ctx, cmdList, name)
|
||||||
|
#define TracyD3D12ZoneC(ctx, cmdList, name, color)
|
||||||
|
#define TracyD3D12NamedZone(ctx, varname, cmdList, name, active)
|
||||||
|
#define TracyD3D12NamedZoneC(ctx, varname, cmdList, name, color, active)
|
||||||
|
#define TracyD3D12ZoneTransient(ctx, varname, cmdList, name, active)
|
||||||
|
|
||||||
|
#define TracyD3D12ZoneS(ctx, cmdList, name, depth)
|
||||||
|
#define TracyD3D12ZoneCS(ctx, cmdList, name, color, depth)
|
||||||
|
#define TracyD3D12NamedZoneS(ctx, varname, cmdList, name, depth, active)
|
||||||
|
#define TracyD3D12NamedZoneCS(ctx, varname, cmdList, name, color, depth, active)
|
||||||
|
#define TracyD3D12ZoneTransientS(ctx, varname, cmdList, name, depth, active)
|
||||||
|
|
||||||
|
#define TracyD3D12Collect(ctx)
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
class D3D12ZoneScope {};
|
||||||
|
}
|
||||||
|
|
||||||
|
using TracyD3D12Ctx = void*;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include "Tracy.hpp"
|
||||||
|
#include "../client/TracyProfiler.hpp"
|
||||||
|
#include "../client/TracyCallstack.hpp"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cassert>
|
||||||
|
#include <d3d12.h>
|
||||||
|
#include <dxgi.h>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
#define TracyD3D12Panic(msg, ...) do { assert(false && "TracyD3D12: " msg); TracyMessageLC("TracyD3D12: " msg, tracy::Color::Red4); __VA_ARGS__; } while(false);
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
struct D3D12QueryPayload
|
||||||
|
{
|
||||||
|
uint32_t m_queryIdStart = 0;
|
||||||
|
uint32_t m_queryCount = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Command queue context.
|
||||||
|
class D3D12QueueCtx
|
||||||
|
{
|
||||||
|
friend class D3D12ZoneScope;
|
||||||
|
|
||||||
|
ID3D12Device* m_device = nullptr;
|
||||||
|
ID3D12CommandQueue* m_queue = nullptr;
|
||||||
|
uint8_t m_contextId = 255; // TODO: apparently, 255 means "invalid id"; is this documented somewhere?
|
||||||
|
ID3D12QueryHeap* m_queryHeap = nullptr;
|
||||||
|
ID3D12Resource* m_readbackBuffer = nullptr;
|
||||||
|
|
||||||
|
// In-progress payload.
|
||||||
|
uint32_t m_queryLimit = 0;
|
||||||
|
std::atomic<uint32_t> m_queryCounter = 0;
|
||||||
|
uint32_t m_previousQueryCounter = 0;
|
||||||
|
|
||||||
|
uint32_t m_activePayload = 0;
|
||||||
|
ID3D12Fence* m_payloadFence = nullptr;
|
||||||
|
std::queue<D3D12QueryPayload> m_payloadQueue;
|
||||||
|
|
||||||
|
UINT64 m_prevCalibrationTicksCPU = 0;
|
||||||
|
|
||||||
|
void RecalibrateClocks()
|
||||||
|
{
|
||||||
|
UINT64 cpuTimestamp;
|
||||||
|
UINT64 gpuTimestamp;
|
||||||
|
if (FAILED(m_queue->GetClockCalibration(&gpuTimestamp, &cpuTimestamp)))
|
||||||
|
{
|
||||||
|
TracyD3D12Panic("failed to obtain queue clock calibration counters.", return);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t cpuDeltaTicks = cpuTimestamp - m_prevCalibrationTicksCPU;
|
||||||
|
if (cpuDeltaTicks > 0)
|
||||||
|
{
|
||||||
|
static const int64_t nanosecodsPerTick = int64_t(1000000000) / GetFrequencyQpc();
|
||||||
|
int64_t cpuDeltaNS = cpuDeltaTicks * nanosecodsPerTick;
|
||||||
|
// Save the device cpu timestamp, not the Tracy profiler timestamp:
|
||||||
|
m_prevCalibrationTicksCPU = cpuTimestamp;
|
||||||
|
|
||||||
|
cpuTimestamp = Profiler::GetTime();
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
MemWrite(&item->hdr.type, QueueType::GpuCalibration);
|
||||||
|
MemWrite(&item->gpuCalibration.gpuTime, gpuTimestamp);
|
||||||
|
MemWrite(&item->gpuCalibration.cpuTime, cpuTimestamp);
|
||||||
|
MemWrite(&item->gpuCalibration.cpuDelta, cpuDeltaNS);
|
||||||
|
MemWrite(&item->gpuCalibration.context, GetId());
|
||||||
|
SubmitQueueItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void SubmitQueueItem(tracy::QueueItem* item)
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
GetProfiler().DeferItem(*item);
|
||||||
|
#endif
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
D3D12QueueCtx(ID3D12Device* device, ID3D12CommandQueue* queue)
|
||||||
|
: m_device(device)
|
||||||
|
, m_queue(queue)
|
||||||
|
{
|
||||||
|
// Verify we support timestamp queries on this queue.
|
||||||
|
|
||||||
|
if (queue->GetDesc().Type == D3D12_COMMAND_LIST_TYPE_COPY)
|
||||||
|
{
|
||||||
|
D3D12_FEATURE_DATA_D3D12_OPTIONS3 featureData{};
|
||||||
|
|
||||||
|
HRESULT hr = device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS3, &featureData, sizeof(featureData));
|
||||||
|
if (FAILED(hr) || (featureData.CopyQueueTimestampQueriesSupported == FALSE))
|
||||||
|
{
|
||||||
|
TracyD3D12Panic("Platform does not support profiling of copy queues.", return);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr uint32_t MaxQueries = 64 * 1024; // Must be even, because queries are (begin, end) pairs
|
||||||
|
m_queryLimit = MaxQueries;
|
||||||
|
|
||||||
|
D3D12_QUERY_HEAP_DESC heapDesc{};
|
||||||
|
heapDesc.Type = queue->GetDesc().Type == D3D12_COMMAND_LIST_TYPE_COPY ? D3D12_QUERY_HEAP_TYPE_COPY_QUEUE_TIMESTAMP : D3D12_QUERY_HEAP_TYPE_TIMESTAMP;
|
||||||
|
heapDesc.Count = m_queryLimit;
|
||||||
|
heapDesc.NodeMask = 0; // #TODO: Support multiple adapters.
|
||||||
|
|
||||||
|
while (FAILED(device->CreateQueryHeap(&heapDesc, IID_PPV_ARGS(&m_queryHeap))))
|
||||||
|
{
|
||||||
|
m_queryLimit /= 2;
|
||||||
|
heapDesc.Count = m_queryLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a readback buffer, which will be used as a destination for the query data.
|
||||||
|
|
||||||
|
D3D12_RESOURCE_DESC readbackBufferDesc{};
|
||||||
|
readbackBufferDesc.Alignment = 0;
|
||||||
|
readbackBufferDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||||
|
readbackBufferDesc.Width = m_queryLimit * sizeof(uint64_t);
|
||||||
|
readbackBufferDesc.Height = 1;
|
||||||
|
readbackBufferDesc.DepthOrArraySize = 1;
|
||||||
|
readbackBufferDesc.Format = DXGI_FORMAT_UNKNOWN;
|
||||||
|
readbackBufferDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; // Buffers are always row major.
|
||||||
|
readbackBufferDesc.MipLevels = 1;
|
||||||
|
readbackBufferDesc.SampleDesc.Count = 1;
|
||||||
|
readbackBufferDesc.SampleDesc.Quality = 0;
|
||||||
|
readbackBufferDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||||
|
|
||||||
|
D3D12_HEAP_PROPERTIES readbackHeapProps{};
|
||||||
|
readbackHeapProps.Type = D3D12_HEAP_TYPE_READBACK;
|
||||||
|
readbackHeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||||
|
readbackHeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||||
|
readbackHeapProps.CreationNodeMask = 0;
|
||||||
|
readbackHeapProps.VisibleNodeMask = 0; // #TODO: Support multiple adapters.
|
||||||
|
|
||||||
|
if (FAILED(device->CreateCommittedResource(&readbackHeapProps, D3D12_HEAP_FLAG_NONE, &readbackBufferDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_readbackBuffer))))
|
||||||
|
{
|
||||||
|
TracyD3D12Panic("Failed to create query readback buffer.", return);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_payloadFence))))
|
||||||
|
{
|
||||||
|
TracyD3D12Panic("Failed to create payload fence.", return);
|
||||||
|
}
|
||||||
|
|
||||||
|
float period = [queue]()
|
||||||
|
{
|
||||||
|
uint64_t timestampFrequency;
|
||||||
|
if (FAILED(queue->GetTimestampFrequency(×tampFrequency)))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
return static_cast<float>( 1E+09 / static_cast<double>(timestampFrequency) );
|
||||||
|
}();
|
||||||
|
|
||||||
|
if (period == 0.0f)
|
||||||
|
{
|
||||||
|
TracyD3D12Panic("Failed to get timestamp frequency.", return);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t cpuTimestamp;
|
||||||
|
uint64_t gpuTimestamp;
|
||||||
|
if (FAILED(queue->GetClockCalibration(&gpuTimestamp, &cpuTimestamp)))
|
||||||
|
{
|
||||||
|
TracyD3D12Panic("Failed to get queue clock calibration.", return);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the device cpu timestamp, not the profiler's timestamp.
|
||||||
|
m_prevCalibrationTicksCPU = cpuTimestamp;
|
||||||
|
|
||||||
|
cpuTimestamp = Profiler::GetTime();
|
||||||
|
|
||||||
|
// all checked: ready to roll
|
||||||
|
m_contextId = GetGpuCtxCounter().fetch_add(1);
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
MemWrite(&item->hdr.type, QueueType::GpuNewContext);
|
||||||
|
MemWrite(&item->gpuNewContext.cpuTime, cpuTimestamp);
|
||||||
|
MemWrite(&item->gpuNewContext.gpuTime, gpuTimestamp);
|
||||||
|
MemWrite(&item->gpuNewContext.thread, decltype(item->gpuNewContext.thread)(0)); // #TODO: why 0 instead of GetThreadHandle()?
|
||||||
|
MemWrite(&item->gpuNewContext.period, period);
|
||||||
|
MemWrite(&item->gpuNewContext.context, GetId());
|
||||||
|
MemWrite(&item->gpuNewContext.flags, GpuContextCalibration);
|
||||||
|
MemWrite(&item->gpuNewContext.type, GpuContextType::Direct3D12);
|
||||||
|
SubmitQueueItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
~D3D12QueueCtx()
|
||||||
|
{
|
||||||
|
ZoneScopedC(Color::Red4);
|
||||||
|
// collect all pending timestamps
|
||||||
|
while (m_payloadFence->GetCompletedValue() != m_activePayload)
|
||||||
|
/* busy-wait ... */;
|
||||||
|
Collect();
|
||||||
|
m_payloadFence->Release();
|
||||||
|
m_readbackBuffer->Release();
|
||||||
|
m_queryHeap->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NewFrame()
|
||||||
|
{
|
||||||
|
uint32_t queryCounter = m_queryCounter.exchange(0);
|
||||||
|
m_payloadQueue.emplace(D3D12QueryPayload{ m_previousQueryCounter, queryCounter });
|
||||||
|
m_previousQueryCounter += queryCounter;
|
||||||
|
|
||||||
|
if (m_previousQueryCounter >= m_queryLimit)
|
||||||
|
{
|
||||||
|
m_previousQueryCounter -= m_queryLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_queue->Signal(m_payloadFence, ++m_activePayload);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Name( const char* name, uint16_t len )
|
||||||
|
{
|
||||||
|
auto ptr = (char*)tracy_malloc( len );
|
||||||
|
memcpy( ptr, name, len );
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuContextName );
|
||||||
|
MemWrite( &item->gpuContextNameFat.context, GetId());
|
||||||
|
MemWrite( &item->gpuContextNameFat.ptr, (uint64_t)ptr );
|
||||||
|
MemWrite( &item->gpuContextNameFat.size, len );
|
||||||
|
SubmitQueueItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Collect()
|
||||||
|
{
|
||||||
|
ZoneScopedC(Color::Red4);
|
||||||
|
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if (!GetProfiler().IsConnected())
|
||||||
|
{
|
||||||
|
m_queryCounter = 0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Find out what payloads are available.
|
||||||
|
const auto newestReadyPayload = m_payloadFence->GetCompletedValue();
|
||||||
|
const auto payloadCount = m_payloadQueue.size() - (m_activePayload - newestReadyPayload);
|
||||||
|
|
||||||
|
if (!payloadCount)
|
||||||
|
{
|
||||||
|
return; // No payloads are available yet, exit out.
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12_RANGE mapRange{ 0, m_queryLimit * sizeof(uint64_t) };
|
||||||
|
|
||||||
|
// Map the readback buffer so we can fetch the query data from the GPU.
|
||||||
|
void* readbackBufferMapping = nullptr;
|
||||||
|
|
||||||
|
if (FAILED(m_readbackBuffer->Map(0, &mapRange, &readbackBufferMapping)))
|
||||||
|
{
|
||||||
|
TracyD3D12Panic("Failed to map readback buffer.", return);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* timestampData = static_cast<uint64_t*>(readbackBufferMapping);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < payloadCount; ++i)
|
||||||
|
{
|
||||||
|
const auto& payload = m_payloadQueue.front();
|
||||||
|
|
||||||
|
for (uint32_t j = 0; j < payload.m_queryCount; ++j)
|
||||||
|
{
|
||||||
|
const auto counter = (payload.m_queryIdStart + j) % m_queryLimit;
|
||||||
|
const auto timestamp = timestampData[counter];
|
||||||
|
const auto queryId = counter;
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
MemWrite(&item->hdr.type, QueueType::GpuTime);
|
||||||
|
MemWrite(&item->gpuTime.gpuTime, timestamp);
|
||||||
|
MemWrite(&item->gpuTime.queryId, static_cast<uint16_t>(queryId));
|
||||||
|
MemWrite(&item->gpuTime.context, GetId());
|
||||||
|
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_payloadQueue.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_readbackBuffer->Unmap(0, nullptr);
|
||||||
|
|
||||||
|
// Recalibrate to account for drift.
|
||||||
|
RecalibrateClocks();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
tracy_force_inline uint32_t NextQueryId()
|
||||||
|
{
|
||||||
|
uint32_t queryCounter = m_queryCounter.fetch_add(2);
|
||||||
|
if (queryCounter >= m_queryLimit)
|
||||||
|
{
|
||||||
|
TracyD3D12Panic("Submitted too many GPU queries! Consider increasing MaxQueries.");
|
||||||
|
// #TODO: consider returning an invalid id or sentinel value here
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t id = (m_previousQueryCounter + queryCounter) % m_queryLimit;
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline uint8_t GetId() const
|
||||||
|
{
|
||||||
|
return m_contextId;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class D3D12ZoneScope
|
||||||
|
{
|
||||||
|
const bool m_active;
|
||||||
|
D3D12QueueCtx* m_ctx = nullptr;
|
||||||
|
ID3D12GraphicsCommandList* m_cmdList = nullptr;
|
||||||
|
uint32_t m_queryId = 0; // Used for tracking in nested zones.
|
||||||
|
|
||||||
|
tracy_force_inline void WriteQueueItem(QueueItem* item, QueueType type, uint64_t srcLocation)
|
||||||
|
{
|
||||||
|
MemWrite(&item->hdr.type, type);
|
||||||
|
MemWrite(&item->gpuZoneBegin.cpuTime, Profiler::GetTime());
|
||||||
|
MemWrite(&item->gpuZoneBegin.srcloc, srcLocation);
|
||||||
|
MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle());
|
||||||
|
MemWrite(&item->gpuZoneBegin.queryId, static_cast<uint16_t>(m_queryId));
|
||||||
|
MemWrite(&item->gpuZoneBegin.context, m_ctx->GetId());
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline D3D12ZoneScope(D3D12QueueCtx* ctx, ID3D12GraphicsCommandList* cmdList, bool active)
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active(active&& GetProfiler().IsConnected())
|
||||||
|
#else
|
||||||
|
: m_active(active)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (!m_active) return;
|
||||||
|
|
||||||
|
m_ctx = ctx;
|
||||||
|
m_cmdList = cmdList;
|
||||||
|
|
||||||
|
m_queryId = m_ctx->NextQueryId();
|
||||||
|
m_cmdList->EndQuery(m_ctx->m_queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, m_queryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
tracy_force_inline D3D12ZoneScope(D3D12QueueCtx* ctx, ID3D12GraphicsCommandList* cmdList, const SourceLocationData* srcLocation, bool active)
|
||||||
|
: D3D12ZoneScope(ctx, cmdList, active)
|
||||||
|
{
|
||||||
|
if (!m_active) return;
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
WriteQueueItem(item, QueueType::GpuZoneBeginSerial, reinterpret_cast<uint64_t>(srcLocation));
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline D3D12ZoneScope(D3D12QueueCtx* ctx, ID3D12GraphicsCommandList* cmdList, const SourceLocationData* srcLocation, int depth, bool active)
|
||||||
|
: D3D12ZoneScope(ctx, cmdList, active)
|
||||||
|
{
|
||||||
|
if (!m_active) return;
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerialCallstack(Callstack(depth));
|
||||||
|
WriteQueueItem(item, QueueType::GpuZoneBeginCallstackSerial, reinterpret_cast<uint64_t>(srcLocation));
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline D3D12ZoneScope(D3D12QueueCtx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, ID3D12GraphicsCommandList* cmdList, bool active)
|
||||||
|
: D3D12ZoneScope(ctx, cmdList, active)
|
||||||
|
{
|
||||||
|
if (!m_active) return;
|
||||||
|
|
||||||
|
const auto sourceLocation = Profiler::AllocSourceLocation(line, source, sourceSz, function, functionSz, name, nameSz);
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
WriteQueueItem(item, QueueType::GpuZoneBeginAllocSrcLocSerial, sourceLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline D3D12ZoneScope(D3D12QueueCtx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, ID3D12GraphicsCommandList* cmdList, int depth, bool active)
|
||||||
|
: D3D12ZoneScope(ctx, cmdList, active)
|
||||||
|
{
|
||||||
|
if (!m_active) return;
|
||||||
|
|
||||||
|
const auto sourceLocation = Profiler::AllocSourceLocation(line, source, sourceSz, function, functionSz, name, nameSz);
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerialCallstack(Callstack(depth));
|
||||||
|
WriteQueueItem(item, QueueType::GpuZoneBeginAllocSrcLocCallstackSerial, sourceLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline ~D3D12ZoneScope()
|
||||||
|
{
|
||||||
|
if (!m_active) return;
|
||||||
|
|
||||||
|
const auto queryId = m_queryId + 1; // Our end query slot is immediately after the begin slot.
|
||||||
|
m_cmdList->EndQuery(m_ctx->m_queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, queryId);
|
||||||
|
|
||||||
|
auto* item = Profiler::QueueSerial();
|
||||||
|
MemWrite(&item->hdr.type, QueueType::GpuZoneEndSerial);
|
||||||
|
MemWrite(&item->gpuZoneEnd.cpuTime, Profiler::GetTime());
|
||||||
|
MemWrite(&item->gpuZoneEnd.thread, GetThreadHandle());
|
||||||
|
MemWrite(&item->gpuZoneEnd.queryId, static_cast<uint16_t>(queryId));
|
||||||
|
MemWrite(&item->gpuZoneEnd.context, m_ctx->GetId());
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
|
||||||
|
m_cmdList->ResolveQueryData(m_ctx->m_queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, m_queryId, 2, m_ctx->m_readbackBuffer, m_queryId * sizeof(uint64_t));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline D3D12QueueCtx* CreateD3D12Context(ID3D12Device* device, ID3D12CommandQueue* queue)
|
||||||
|
{
|
||||||
|
auto* ctx = static_cast<D3D12QueueCtx*>(tracy_malloc(sizeof(D3D12QueueCtx)));
|
||||||
|
new (ctx) D3D12QueueCtx{ device, queue };
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void DestroyD3D12Context(D3D12QueueCtx* ctx)
|
||||||
|
{
|
||||||
|
ctx->~D3D12QueueCtx();
|
||||||
|
tracy_free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef TracyD3D12Panic
|
||||||
|
|
||||||
|
using TracyD3D12Ctx = tracy::D3D12QueueCtx*;
|
||||||
|
|
||||||
|
#define TracyD3D12Context(device, queue) tracy::CreateD3D12Context(device, queue);
|
||||||
|
#define TracyD3D12Destroy(ctx) tracy::DestroyD3D12Context(ctx);
|
||||||
|
#define TracyD3D12ContextName(ctx, name, size) ctx->Name(name, size);
|
||||||
|
|
||||||
|
#define TracyD3D12NewFrame(ctx) ctx->NewFrame();
|
||||||
|
|
||||||
|
#define TracyD3D12UnnamedZone ___tracy_gpu_d3d12_zone
|
||||||
|
#define TracyD3D12SrcLocSymbol TracyConcat(__tracy_d3d12_source_location,TracyLine)
|
||||||
|
#define TracyD3D12SrcLocObject(name, color) static constexpr tracy::SourceLocationData TracyD3D12SrcLocSymbol { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color };
|
||||||
|
|
||||||
|
#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK
|
||||||
|
# define TracyD3D12Zone(ctx, cmdList, name) TracyD3D12NamedZoneS(ctx, TracyD3D12UnnamedZone, cmdList, name, TRACY_CALLSTACK, true)
|
||||||
|
# define TracyD3D12ZoneC(ctx, cmdList, name, color) TracyD3D12NamedZoneCS(ctx, TracyD3D12UnnamedZone, cmdList, name, color, TRACY_CALLSTACK, true)
|
||||||
|
# define TracyD3D12NamedZone(ctx, varname, cmdList, name, active) TracyD3D12SrcLocObject(name, 0); tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyD3D12SrcLocSymbol, TRACY_CALLSTACK, active };
|
||||||
|
# define TracyD3D12NamedZoneC(ctx, varname, cmdList, name, color, active) TracyD3D12SrcLocObject(name, color); tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyD3D12SrcLocSymbol, TRACY_CALLSTACK, active };
|
||||||
|
# define TracyD3D12ZoneTransient(ctx, varname, cmdList, name, active) TracyD3D12ZoneTransientS(ctx, varname, cmdList, name, TRACY_CALLSTACK, active)
|
||||||
|
#else
|
||||||
|
# define TracyD3D12Zone(ctx, cmdList, name) TracyD3D12NamedZone(ctx, TracyD3D12UnnamedZone, cmdList, name, true)
|
||||||
|
# define TracyD3D12ZoneC(ctx, cmdList, name, color) TracyD3D12NamedZoneC(ctx, TracyD3D12UnnamedZone, cmdList, name, color, true)
|
||||||
|
# define TracyD3D12NamedZone(ctx, varname, cmdList, name, active) TracyD3D12SrcLocObject(name, 0); tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyD3D12SrcLocSymbol, active };
|
||||||
|
# define TracyD3D12NamedZoneC(ctx, varname, cmdList, name, color, active) TracyD3D12SrcLocObject(name, color); tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyD3D12SrcLocSymbol, active };
|
||||||
|
# define TracyD3D12ZoneTransient(ctx, varname, cmdList, name, active) tracy::D3D12ZoneScope varname{ ctx, TracyLine, TracyFile, strlen(TracyFile), TracyFunction, strlen(TracyFunction), name, strlen(name), cmdList, active };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TRACY_HAS_CALLSTACK
|
||||||
|
# define TracyD3D12ZoneS(ctx, cmdList, name, depth) TracyD3D12NamedZoneS(ctx, TracyD3D12UnnamedZone, cmdList, name, depth, true)
|
||||||
|
# define TracyD3D12ZoneCS(ctx, cmdList, name, color, depth) TracyD3D12NamedZoneCS(ctx, TracyD3D12UnnamedZone, cmdList, name, color, depth, true)
|
||||||
|
# define TracyD3D12NamedZoneS(ctx, varname, cmdList, name, depth, active) TracyD3D12SrcLocObject(name, 0); tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyD3D12SrcLocSymbol, depth, active };
|
||||||
|
# define TracyD3D12NamedZoneCS(ctx, varname, cmdList, name, color, depth, active) TracyD3D12SrcLocObject(name, color); tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyD3D12SrcLocSymbol, depth, active };
|
||||||
|
# define TracyD3D12ZoneTransientS(ctx, varname, cmdList, name, depth, active) tracy::D3D12ZoneScope varname{ ctx, TracyLine, TracyFile, strlen(TracyFile), TracyFunction, strlen(TracyFunction), name, strlen(name), cmdList, depth, active };
|
||||||
|
#else
|
||||||
|
# define TracyD3D12ZoneS(ctx, cmdList, name, depth) TracyD3D12Zone(ctx, cmdList, name)
|
||||||
|
# define TracyD3D12ZoneCS(ctx, cmdList, name, color, depth) TracyD3D12Zone(ctx, cmdList, name, color)
|
||||||
|
# define TracyD3D12NamedZoneS(ctx, varname, cmdList, name, depth, active) TracyD3D12NamedZone(ctx, varname, cmdList, name, active)
|
||||||
|
# define TracyD3D12NamedZoneCS(ctx, varname, cmdList, name, color, depth, active) TracyD3D12NamedZoneC(ctx, varname, cmdList, name, color, active)
|
||||||
|
# define TracyD3D12ZoneTransientS(ctx, varname, cmdList, name, depth, active) TracyD3D12ZoneTransient(ctx, varname, cmdList, name, active)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TracyD3D12Collect(ctx) ctx->Collect();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
431
externals/tracy/public/tracy/TracyLua.hpp
vendored
Normal file
431
externals/tracy/public/tracy/TracyLua.hpp
vendored
Normal file
@ -0,0 +1,431 @@
|
|||||||
|
#ifndef __TRACYLUA_HPP__
|
||||||
|
#define __TRACYLUA_HPP__
|
||||||
|
|
||||||
|
// Include this file after you include lua headers.
|
||||||
|
|
||||||
|
#ifndef TRACY_ENABLE
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
static inline int noop( lua_State* L ) { return 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void LuaRegister( lua_State* L )
|
||||||
|
{
|
||||||
|
lua_newtable( L );
|
||||||
|
lua_pushcfunction( L, detail::noop );
|
||||||
|
lua_setfield( L, -2, "ZoneBegin" );
|
||||||
|
lua_pushcfunction( L, detail::noop );
|
||||||
|
lua_setfield( L, -2, "ZoneBeginN" );
|
||||||
|
lua_pushcfunction( L, detail::noop );
|
||||||
|
lua_setfield( L, -2, "ZoneBeginS" );
|
||||||
|
lua_pushcfunction( L, detail::noop );
|
||||||
|
lua_setfield( L, -2, "ZoneBeginNS" );
|
||||||
|
lua_pushcfunction( L, detail::noop );
|
||||||
|
lua_setfield( L, -2, "ZoneEnd" );
|
||||||
|
lua_pushcfunction( L, detail::noop );
|
||||||
|
lua_setfield( L, -2, "ZoneText" );
|
||||||
|
lua_pushcfunction( L, detail::noop );
|
||||||
|
lua_setfield( L, -2, "ZoneName" );
|
||||||
|
lua_pushcfunction( L, detail::noop );
|
||||||
|
lua_setfield( L, -2, "Message" );
|
||||||
|
lua_setglobal( L, "tracy" );
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char* FindEnd( char* ptr )
|
||||||
|
{
|
||||||
|
unsigned int cnt = 1;
|
||||||
|
while( cnt != 0 )
|
||||||
|
{
|
||||||
|
if( *ptr == '(' ) cnt++;
|
||||||
|
else if( *ptr == ')' ) cnt--;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void LuaRemove( char* script )
|
||||||
|
{
|
||||||
|
while( *script )
|
||||||
|
{
|
||||||
|
if( strncmp( script, "tracy.", 6 ) == 0 )
|
||||||
|
{
|
||||||
|
if( strncmp( script + 6, "Zone", 4 ) == 0 )
|
||||||
|
{
|
||||||
|
if( strncmp( script + 10, "End()", 5 ) == 0 )
|
||||||
|
{
|
||||||
|
memset( script, ' ', 15 );
|
||||||
|
script += 15;
|
||||||
|
}
|
||||||
|
else if( strncmp( script + 10, "Begin()", 7 ) == 0 )
|
||||||
|
{
|
||||||
|
memset( script, ' ', 17 );
|
||||||
|
script += 17;
|
||||||
|
}
|
||||||
|
else if( strncmp( script + 10, "Text(", 5 ) == 0 )
|
||||||
|
{
|
||||||
|
auto end = FindEnd( script + 15 );
|
||||||
|
memset( script, ' ', end - script );
|
||||||
|
script = end;
|
||||||
|
}
|
||||||
|
else if( strncmp( script + 10, "Name(", 5 ) == 0 )
|
||||||
|
{
|
||||||
|
auto end = FindEnd( script + 15 );
|
||||||
|
memset( script, ' ', end - script );
|
||||||
|
script = end;
|
||||||
|
}
|
||||||
|
else if( strncmp( script + 10, "BeginN(", 7 ) == 0 )
|
||||||
|
{
|
||||||
|
auto end = FindEnd( script + 17 );
|
||||||
|
memset( script, ' ', end - script );
|
||||||
|
script = end;
|
||||||
|
}
|
||||||
|
else if( strncmp( script + 10, "BeginS(", 7 ) == 0 )
|
||||||
|
{
|
||||||
|
auto end = FindEnd( script + 17 );
|
||||||
|
memset( script, ' ', end - script );
|
||||||
|
script = end;
|
||||||
|
}
|
||||||
|
else if( strncmp( script + 10, "BeginNS(", 8 ) == 0 )
|
||||||
|
{
|
||||||
|
auto end = FindEnd( script + 18 );
|
||||||
|
memset( script, ' ', end - script );
|
||||||
|
script = end;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
script += 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( strncmp( script + 6, "Message(", 8 ) == 0 )
|
||||||
|
{
|
||||||
|
auto end = FindEnd( script + 14 );
|
||||||
|
memset( script, ' ', end - script );
|
||||||
|
script = end;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
script += 6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
script++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#include "../common/TracyColor.hpp"
|
||||||
|
#include "../common/TracyAlign.hpp"
|
||||||
|
#include "../common/TracyForceInline.hpp"
|
||||||
|
#include "../common/TracySystem.hpp"
|
||||||
|
#include "../client/TracyProfiler.hpp"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
TRACY_API LuaZoneState& GetLuaZoneState();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef TRACY_HAS_CALLSTACK
|
||||||
|
static tracy_force_inline void SendLuaCallstack( lua_State* L, uint32_t depth )
|
||||||
|
{
|
||||||
|
assert( depth <= 64 );
|
||||||
|
lua_Debug dbg[64];
|
||||||
|
const char* func[64];
|
||||||
|
uint32_t fsz[64];
|
||||||
|
uint32_t ssz[64];
|
||||||
|
|
||||||
|
uint8_t cnt;
|
||||||
|
uint16_t spaceNeeded = sizeof( cnt );
|
||||||
|
for( cnt=0; cnt<depth; cnt++ )
|
||||||
|
{
|
||||||
|
if( lua_getstack( L, cnt+1, dbg+cnt ) == 0 ) break;
|
||||||
|
lua_getinfo( L, "Snl", dbg+cnt );
|
||||||
|
func[cnt] = dbg[cnt].name ? dbg[cnt].name : dbg[cnt].short_src;
|
||||||
|
fsz[cnt] = uint32_t( strlen( func[cnt] ) );
|
||||||
|
ssz[cnt] = uint32_t( strlen( dbg[cnt].source ) );
|
||||||
|
spaceNeeded += fsz[cnt] + ssz[cnt];
|
||||||
|
}
|
||||||
|
spaceNeeded += cnt * ( 4 + 2 + 2 ); // source line, function string length, source string length
|
||||||
|
|
||||||
|
auto ptr = (char*)tracy_malloc( spaceNeeded + 2 );
|
||||||
|
auto dst = ptr;
|
||||||
|
memcpy( dst, &spaceNeeded, 2 ); dst += 2;
|
||||||
|
memcpy( dst, &cnt, 1 ); dst++;
|
||||||
|
for( uint8_t i=0; i<cnt; i++ )
|
||||||
|
{
|
||||||
|
const uint32_t line = dbg[i].currentline;
|
||||||
|
memcpy( dst, &line, 4 ); dst += 4;
|
||||||
|
assert( fsz[i] <= (std::numeric_limits<uint16_t>::max)() );
|
||||||
|
memcpy( dst, fsz+i, 2 ); dst += 2;
|
||||||
|
memcpy( dst, func[i], fsz[i] ); dst += fsz[i];
|
||||||
|
assert( ssz[i] <= (std::numeric_limits<uint16_t>::max)() );
|
||||||
|
memcpy( dst, ssz+i, 2 ); dst += 2;
|
||||||
|
memcpy( dst, dbg[i].source, ssz[i] ), dst += ssz[i];
|
||||||
|
}
|
||||||
|
assert( dst - ptr == spaceNeeded + 2 );
|
||||||
|
|
||||||
|
TracyQueuePrepare( QueueType::CallstackAlloc );
|
||||||
|
MemWrite( &item->callstackAllocFat.ptr, (uint64_t)ptr );
|
||||||
|
MemWrite( &item->callstackAllocFat.nativePtr, (uint64_t)Callstack( depth ) );
|
||||||
|
TracyQueueCommit( callstackAllocFatThread );
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int LuaZoneBeginS( lua_State* L )
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
const auto zoneCnt = GetLuaZoneState().counter++;
|
||||||
|
if( zoneCnt != 0 && !GetLuaZoneState().active ) return 0;
|
||||||
|
GetLuaZoneState().active = GetProfiler().IsConnected();
|
||||||
|
if( !GetLuaZoneState().active ) return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TRACY_CALLSTACK
|
||||||
|
const uint32_t depth = TRACY_CALLSTACK;
|
||||||
|
#else
|
||||||
|
const auto depth = uint32_t( lua_tointeger( L, 1 ) );
|
||||||
|
#endif
|
||||||
|
SendLuaCallstack( L, depth );
|
||||||
|
|
||||||
|
lua_Debug dbg;
|
||||||
|
lua_getstack( L, 1, &dbg );
|
||||||
|
lua_getinfo( L, "Snl", &dbg );
|
||||||
|
const auto srcloc = Profiler::AllocSourceLocation( dbg.currentline, dbg.source, dbg.name ? dbg.name : dbg.short_src );
|
||||||
|
|
||||||
|
TracyQueuePrepare( QueueType::ZoneBeginAllocSrcLocCallstack );
|
||||||
|
MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->zoneBegin.srcloc, srcloc );
|
||||||
|
TracyQueueCommit( zoneBeginThread );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int LuaZoneBeginNS( lua_State* L )
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
const auto zoneCnt = GetLuaZoneState().counter++;
|
||||||
|
if( zoneCnt != 0 && !GetLuaZoneState().active ) return 0;
|
||||||
|
GetLuaZoneState().active = GetProfiler().IsConnected();
|
||||||
|
if( !GetLuaZoneState().active ) return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TRACY_CALLSTACK
|
||||||
|
const uint32_t depth = TRACY_CALLSTACK;
|
||||||
|
#else
|
||||||
|
const auto depth = uint32_t( lua_tointeger( L, 2 ) );
|
||||||
|
#endif
|
||||||
|
SendLuaCallstack( L, depth );
|
||||||
|
|
||||||
|
lua_Debug dbg;
|
||||||
|
lua_getstack( L, 1, &dbg );
|
||||||
|
lua_getinfo( L, "Snl", &dbg );
|
||||||
|
size_t nsz;
|
||||||
|
const auto name = lua_tolstring( L, 1, &nsz );
|
||||||
|
const auto srcloc = Profiler::AllocSourceLocation( dbg.currentline, dbg.source, dbg.name ? dbg.name : dbg.short_src, name, nsz );
|
||||||
|
|
||||||
|
TracyQueuePrepare( QueueType::ZoneBeginAllocSrcLocCallstack );
|
||||||
|
MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->zoneBegin.srcloc, srcloc );
|
||||||
|
TracyQueueCommit( zoneBeginThread );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline int LuaZoneBegin( lua_State* L )
|
||||||
|
{
|
||||||
|
#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK
|
||||||
|
return LuaZoneBeginS( L );
|
||||||
|
#else
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
const auto zoneCnt = GetLuaZoneState().counter++;
|
||||||
|
if( zoneCnt != 0 && !GetLuaZoneState().active ) return 0;
|
||||||
|
GetLuaZoneState().active = GetProfiler().IsConnected();
|
||||||
|
if( !GetLuaZoneState().active ) return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
lua_Debug dbg;
|
||||||
|
lua_getstack( L, 1, &dbg );
|
||||||
|
lua_getinfo( L, "Snl", &dbg );
|
||||||
|
const auto srcloc = Profiler::AllocSourceLocation( dbg.currentline, dbg.source, dbg.name ? dbg.name : dbg.short_src );
|
||||||
|
|
||||||
|
TracyQueuePrepare( QueueType::ZoneBeginAllocSrcLoc );
|
||||||
|
MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->zoneBegin.srcloc, srcloc );
|
||||||
|
TracyQueueCommit( zoneBeginThread );
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int LuaZoneBeginN( lua_State* L )
|
||||||
|
{
|
||||||
|
#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK
|
||||||
|
return LuaZoneBeginNS( L );
|
||||||
|
#else
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
const auto zoneCnt = GetLuaZoneState().counter++;
|
||||||
|
if( zoneCnt != 0 && !GetLuaZoneState().active ) return 0;
|
||||||
|
GetLuaZoneState().active = GetProfiler().IsConnected();
|
||||||
|
if( !GetLuaZoneState().active ) return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
lua_Debug dbg;
|
||||||
|
lua_getstack( L, 1, &dbg );
|
||||||
|
lua_getinfo( L, "Snl", &dbg );
|
||||||
|
size_t nsz;
|
||||||
|
const auto name = lua_tolstring( L, 1, &nsz );
|
||||||
|
const auto srcloc = Profiler::AllocSourceLocation( dbg.currentline, dbg.source, dbg.name ? dbg.name : dbg.short_src, name, nsz );
|
||||||
|
|
||||||
|
TracyQueuePrepare( QueueType::ZoneBeginAllocSrcLoc );
|
||||||
|
MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->zoneBegin.srcloc, srcloc );
|
||||||
|
TracyQueueCommit( zoneBeginThread );
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int LuaZoneEnd( lua_State* L )
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
assert( GetLuaZoneState().counter != 0 );
|
||||||
|
GetLuaZoneState().counter--;
|
||||||
|
if( !GetLuaZoneState().active ) return 0;
|
||||||
|
if( !GetProfiler().IsConnected() )
|
||||||
|
{
|
||||||
|
GetLuaZoneState().active = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TracyQueuePrepare( QueueType::ZoneEnd );
|
||||||
|
MemWrite( &item->zoneEnd.time, Profiler::GetTime() );
|
||||||
|
TracyQueueCommit( zoneEndThread );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int LuaZoneText( lua_State* L )
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if( !GetLuaZoneState().active ) return 0;
|
||||||
|
if( !GetProfiler().IsConnected() )
|
||||||
|
{
|
||||||
|
GetLuaZoneState().active = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto txt = lua_tostring( L, 1 );
|
||||||
|
const auto size = strlen( txt );
|
||||||
|
assert( size < (std::numeric_limits<uint16_t>::max)() );
|
||||||
|
|
||||||
|
auto ptr = (char*)tracy_malloc( size );
|
||||||
|
memcpy( ptr, txt, size );
|
||||||
|
|
||||||
|
TracyQueuePrepare( QueueType::ZoneText );
|
||||||
|
MemWrite( &item->zoneTextFat.text, (uint64_t)ptr );
|
||||||
|
MemWrite( &item->zoneTextFat.size, (uint16_t)size );
|
||||||
|
TracyQueueCommit( zoneTextFatThread );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int LuaZoneName( lua_State* L )
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if( !GetLuaZoneState().active ) return 0;
|
||||||
|
if( !GetProfiler().IsConnected() )
|
||||||
|
{
|
||||||
|
GetLuaZoneState().active = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto txt = lua_tostring( L, 1 );
|
||||||
|
const auto size = strlen( txt );
|
||||||
|
assert( size < (std::numeric_limits<uint16_t>::max)() );
|
||||||
|
|
||||||
|
auto ptr = (char*)tracy_malloc( size );
|
||||||
|
memcpy( ptr, txt, size );
|
||||||
|
|
||||||
|
TracyQueuePrepare( QueueType::ZoneName );
|
||||||
|
MemWrite( &item->zoneTextFat.text, (uint64_t)ptr );
|
||||||
|
MemWrite( &item->zoneTextFat.size, (uint16_t)size );
|
||||||
|
TracyQueueCommit( zoneTextFatThread );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int LuaMessage( lua_State* L )
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if( !GetProfiler().IsConnected() ) return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto txt = lua_tostring( L, 1 );
|
||||||
|
const auto size = strlen( txt );
|
||||||
|
assert( size < (std::numeric_limits<uint16_t>::max)() );
|
||||||
|
|
||||||
|
auto ptr = (char*)tracy_malloc( size );
|
||||||
|
memcpy( ptr, txt, size );
|
||||||
|
|
||||||
|
TracyQueuePrepare( QueueType::Message );
|
||||||
|
MemWrite( &item->messageFat.time, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->messageFat.text, (uint64_t)ptr );
|
||||||
|
MemWrite( &item->messageFat.size, (uint16_t)size );
|
||||||
|
TracyQueueCommit( messageFatThread );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void LuaRegister( lua_State* L )
|
||||||
|
{
|
||||||
|
lua_newtable( L );
|
||||||
|
lua_pushcfunction( L, detail::LuaZoneBegin );
|
||||||
|
lua_setfield( L, -2, "ZoneBegin" );
|
||||||
|
lua_pushcfunction( L, detail::LuaZoneBeginN );
|
||||||
|
lua_setfield( L, -2, "ZoneBeginN" );
|
||||||
|
#ifdef TRACY_HAS_CALLSTACK
|
||||||
|
lua_pushcfunction( L, detail::LuaZoneBeginS );
|
||||||
|
lua_setfield( L, -2, "ZoneBeginS" );
|
||||||
|
lua_pushcfunction( L, detail::LuaZoneBeginNS );
|
||||||
|
lua_setfield( L, -2, "ZoneBeginNS" );
|
||||||
|
#else
|
||||||
|
lua_pushcfunction( L, detail::LuaZoneBegin );
|
||||||
|
lua_setfield( L, -2, "ZoneBeginS" );
|
||||||
|
lua_pushcfunction( L, detail::LuaZoneBeginN );
|
||||||
|
lua_setfield( L, -2, "ZoneBeginNS" );
|
||||||
|
#endif
|
||||||
|
lua_pushcfunction( L, detail::LuaZoneEnd );
|
||||||
|
lua_setfield( L, -2, "ZoneEnd" );
|
||||||
|
lua_pushcfunction( L, detail::LuaZoneText );
|
||||||
|
lua_setfield( L, -2, "ZoneText" );
|
||||||
|
lua_pushcfunction( L, detail::LuaZoneName );
|
||||||
|
lua_setfield( L, -2, "ZoneName" );
|
||||||
|
lua_pushcfunction( L, detail::LuaMessage );
|
||||||
|
lua_setfield( L, -2, "Message" );
|
||||||
|
lua_setglobal( L, "tracy" );
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void LuaRemove( char* script ) {}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
414
externals/tracy/public/tracy/TracyOpenCL.hpp
vendored
Normal file
414
externals/tracy/public/tracy/TracyOpenCL.hpp
vendored
Normal file
@ -0,0 +1,414 @@
|
|||||||
|
#ifndef __TRACYOPENCL_HPP__
|
||||||
|
#define __TRACYOPENCL_HPP__
|
||||||
|
|
||||||
|
#if !defined TRACY_ENABLE
|
||||||
|
|
||||||
|
#define TracyCLContext(c, x) nullptr
|
||||||
|
#define TracyCLDestroy(c)
|
||||||
|
#define TracyCLContextName(c, x, y)
|
||||||
|
|
||||||
|
#define TracyCLNamedZone(c, x, y, z)
|
||||||
|
#define TracyCLNamedZoneC(c, x, y, z, w)
|
||||||
|
#define TracyCLZone(c, x)
|
||||||
|
#define TracyCLZoneC(c, x, y)
|
||||||
|
#define TracyCLZoneTransient(c,x,y,z)
|
||||||
|
|
||||||
|
#define TracyCLNamedZoneS(c, x, y, z, w)
|
||||||
|
#define TracyCLNamedZoneCS(c, x, y, z, w, v)
|
||||||
|
#define TracyCLZoneS(c, x, y)
|
||||||
|
#define TracyCLZoneCS(c, x, y, z)
|
||||||
|
#define TracyCLZoneTransientS(c,x,y,z,w)
|
||||||
|
|
||||||
|
#define TracyCLNamedZoneSetEvent(x, e)
|
||||||
|
#define TracyCLZoneSetEvent(e)
|
||||||
|
|
||||||
|
#define TracyCLCollect(c)
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
class OpenCLCtxScope {};
|
||||||
|
}
|
||||||
|
|
||||||
|
using TracyCLCtx = void*;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <CL/cl.h>
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <cassert>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "Tracy.hpp"
|
||||||
|
#include "../client/TracyCallstack.hpp"
|
||||||
|
#include "../client/TracyProfiler.hpp"
|
||||||
|
#include "../common/TracyAlloc.hpp"
|
||||||
|
|
||||||
|
#define TRACY_CL_TO_STRING_INDIRECT(T) #T
|
||||||
|
#define TRACY_CL_TO_STRING(T) TRACY_CL_TO_STRING_INDIRECT(T)
|
||||||
|
#define TRACY_CL_ASSERT(p) if(!(p)) { \
|
||||||
|
TracyMessageL( "TRACY_CL_ASSERT failed on " TracyFile ":" TRACY_CL_TO_STRING(TracyLine) ); \
|
||||||
|
assert(false && "TRACY_CL_ASSERT failed"); \
|
||||||
|
}
|
||||||
|
#define TRACY_CL_CHECK_ERROR(err) if(err != CL_SUCCESS) { \
|
||||||
|
std::ostringstream oss; \
|
||||||
|
oss << "TRACY_CL_CHECK_ERROR failed on " << TracyFile << ":" << TracyLine \
|
||||||
|
<< ": error code " << err; \
|
||||||
|
auto msg = oss.str(); \
|
||||||
|
TracyMessage(msg.data(), msg.size()); \
|
||||||
|
assert(false && "TRACY_CL_CHECK_ERROR failed"); \
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace tracy {
|
||||||
|
|
||||||
|
enum class EventPhase : uint8_t
|
||||||
|
{
|
||||||
|
Begin,
|
||||||
|
End
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EventInfo
|
||||||
|
{
|
||||||
|
cl_event event;
|
||||||
|
EventPhase phase;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OpenCLCtx
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum { QueryCount = 64 * 1024 };
|
||||||
|
|
||||||
|
OpenCLCtx(cl_context context, cl_device_id device)
|
||||||
|
: m_contextId(GetGpuCtxCounter().fetch_add(1, std::memory_order_relaxed))
|
||||||
|
, m_head(0)
|
||||||
|
, m_tail(0)
|
||||||
|
{
|
||||||
|
int64_t tcpu, tgpu;
|
||||||
|
TRACY_CL_ASSERT(m_contextId != 255);
|
||||||
|
|
||||||
|
cl_int err = CL_SUCCESS;
|
||||||
|
cl_command_queue queue = clCreateCommandQueue(context, device, CL_QUEUE_PROFILING_ENABLE, &err);
|
||||||
|
TRACY_CL_CHECK_ERROR(err)
|
||||||
|
uint32_t dummyValue = 42;
|
||||||
|
cl_mem dummyBuffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(uint32_t), nullptr, &err);
|
||||||
|
TRACY_CL_CHECK_ERROR(err)
|
||||||
|
cl_event writeBufferEvent;
|
||||||
|
TRACY_CL_CHECK_ERROR(clEnqueueWriteBuffer(queue, dummyBuffer, CL_FALSE, 0, sizeof(uint32_t), &dummyValue, 0, nullptr, &writeBufferEvent));
|
||||||
|
TRACY_CL_CHECK_ERROR(clWaitForEvents(1, &writeBufferEvent));
|
||||||
|
|
||||||
|
tcpu = Profiler::GetTime();
|
||||||
|
|
||||||
|
cl_int eventStatus;
|
||||||
|
TRACY_CL_CHECK_ERROR(clGetEventInfo(writeBufferEvent, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof(cl_int), &eventStatus, nullptr));
|
||||||
|
TRACY_CL_ASSERT(eventStatus == CL_COMPLETE);
|
||||||
|
TRACY_CL_CHECK_ERROR(clGetEventProfilingInfo(writeBufferEvent, CL_PROFILING_COMMAND_END, sizeof(cl_ulong), &tgpu, nullptr));
|
||||||
|
TRACY_CL_CHECK_ERROR(clReleaseEvent(writeBufferEvent));
|
||||||
|
TRACY_CL_CHECK_ERROR(clReleaseMemObject(dummyBuffer));
|
||||||
|
TRACY_CL_CHECK_ERROR(clReleaseCommandQueue(queue));
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite(&item->hdr.type, QueueType::GpuNewContext);
|
||||||
|
MemWrite(&item->gpuNewContext.cpuTime, tcpu);
|
||||||
|
MemWrite(&item->gpuNewContext.gpuTime, tgpu);
|
||||||
|
memset(&item->gpuNewContext.thread, 0, sizeof(item->gpuNewContext.thread));
|
||||||
|
MemWrite(&item->gpuNewContext.period, 1.0f);
|
||||||
|
MemWrite(&item->gpuNewContext.type, GpuContextType::OpenCL);
|
||||||
|
MemWrite(&item->gpuNewContext.context, (uint8_t) m_contextId);
|
||||||
|
MemWrite(&item->gpuNewContext.flags, (uint8_t)0);
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
GetProfiler().DeferItem(*item);
|
||||||
|
#endif
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Name( const char* name, uint16_t len )
|
||||||
|
{
|
||||||
|
auto ptr = (char*)tracy_malloc( len );
|
||||||
|
memcpy( ptr, name, len );
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuContextName );
|
||||||
|
MemWrite( &item->gpuContextNameFat.context, (uint8_t)m_contextId );
|
||||||
|
MemWrite( &item->gpuContextNameFat.ptr, (uint64_t)ptr );
|
||||||
|
MemWrite( &item->gpuContextNameFat.size, len );
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
GetProfiler().DeferItem( *item );
|
||||||
|
#endif
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Collect()
|
||||||
|
{
|
||||||
|
ZoneScopedC(Color::Red4);
|
||||||
|
|
||||||
|
if (m_tail == m_head) return;
|
||||||
|
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if (!GetProfiler().IsConnected())
|
||||||
|
{
|
||||||
|
m_head = m_tail = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (; m_tail != m_head; m_tail = (m_tail + 1) % QueryCount)
|
||||||
|
{
|
||||||
|
EventInfo eventInfo = GetQuery(m_tail);
|
||||||
|
cl_int eventStatus;
|
||||||
|
cl_int err = clGetEventInfo(eventInfo.event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof(cl_int), &eventStatus, nullptr);
|
||||||
|
if (err != CL_SUCCESS)
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "clGetEventInfo falied with error code " << err << ", on event " << eventInfo.event << ", skipping...";
|
||||||
|
auto msg = oss.str();
|
||||||
|
TracyMessage(msg.data(), msg.size());
|
||||||
|
if (eventInfo.event == nullptr) {
|
||||||
|
TracyMessageL("A TracyCLZone must be paird with a TracyCLZoneSetEvent, check your code!");
|
||||||
|
}
|
||||||
|
assert(false && "clGetEventInfo failed, maybe a TracyCLZone is not paired with TracyCLZoneSetEvent");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (eventStatus != CL_COMPLETE) return;
|
||||||
|
|
||||||
|
cl_int eventInfoQuery = (eventInfo.phase == EventPhase::Begin)
|
||||||
|
? CL_PROFILING_COMMAND_START
|
||||||
|
: CL_PROFILING_COMMAND_END;
|
||||||
|
|
||||||
|
cl_ulong eventTimeStamp = 0;
|
||||||
|
err = clGetEventProfilingInfo(eventInfo.event, eventInfoQuery, sizeof(cl_ulong), &eventTimeStamp, nullptr);
|
||||||
|
if (err == CL_PROFILING_INFO_NOT_AVAILABLE)
|
||||||
|
{
|
||||||
|
TracyMessageL("command queue is not created with CL_QUEUE_PROFILING_ENABLE flag, check your code!");
|
||||||
|
assert(false && "command queue is not created with CL_QUEUE_PROFILING_ENABLE flag");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
TRACY_CL_CHECK_ERROR(err);
|
||||||
|
|
||||||
|
TRACY_CL_ASSERT(eventTimeStamp != 0);
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite(&item->hdr.type, QueueType::GpuTime);
|
||||||
|
MemWrite(&item->gpuTime.gpuTime, (int64_t)eventTimeStamp);
|
||||||
|
MemWrite(&item->gpuTime.queryId, (uint16_t)m_tail);
|
||||||
|
MemWrite(&item->gpuTime.context, m_contextId);
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
|
||||||
|
if (eventInfo.phase == EventPhase::End)
|
||||||
|
{
|
||||||
|
// Done with the event, so release it
|
||||||
|
TRACY_CL_CHECK_ERROR(clReleaseEvent(eventInfo.event));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline uint8_t GetId() const
|
||||||
|
{
|
||||||
|
return m_contextId;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline unsigned int NextQueryId(EventInfo eventInfo)
|
||||||
|
{
|
||||||
|
const auto id = m_head;
|
||||||
|
m_head = (m_head + 1) % QueryCount;
|
||||||
|
TRACY_CL_ASSERT(m_head != m_tail);
|
||||||
|
m_query[id] = eventInfo;
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline EventInfo& GetQuery(unsigned int id)
|
||||||
|
{
|
||||||
|
TRACY_CL_ASSERT(id < QueryCount);
|
||||||
|
return m_query[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
unsigned int m_contextId;
|
||||||
|
|
||||||
|
EventInfo m_query[QueryCount];
|
||||||
|
unsigned int m_head; // index at which a new event should be inserted
|
||||||
|
unsigned int m_tail; // oldest event
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class OpenCLCtxScope {
|
||||||
|
public:
|
||||||
|
tracy_force_inline OpenCLCtxScope(OpenCLCtx* ctx, const SourceLocationData* srcLoc, bool is_active)
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active(is_active&& GetProfiler().IsConnected())
|
||||||
|
#else
|
||||||
|
: m_active(is_active)
|
||||||
|
#endif
|
||||||
|
, m_ctx(ctx)
|
||||||
|
, m_event(nullptr)
|
||||||
|
{
|
||||||
|
if (!m_active) return;
|
||||||
|
|
||||||
|
m_beginQueryId = ctx->NextQueryId(EventInfo{ nullptr, EventPhase::Begin });
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite(&item->hdr.type, QueueType::GpuZoneBeginSerial);
|
||||||
|
MemWrite(&item->gpuZoneBegin.cpuTime, Profiler::GetTime());
|
||||||
|
MemWrite(&item->gpuZoneBegin.srcloc, (uint64_t)srcLoc);
|
||||||
|
MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle());
|
||||||
|
MemWrite(&item->gpuZoneBegin.queryId, (uint16_t)m_beginQueryId);
|
||||||
|
MemWrite(&item->gpuZoneBegin.context, ctx->GetId());
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline OpenCLCtxScope(OpenCLCtx* ctx, const SourceLocationData* srcLoc, int depth, bool is_active)
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active(is_active&& GetProfiler().IsConnected())
|
||||||
|
#else
|
||||||
|
: m_active(is_active)
|
||||||
|
#endif
|
||||||
|
, m_ctx(ctx)
|
||||||
|
, m_event(nullptr)
|
||||||
|
{
|
||||||
|
if (!m_active) return;
|
||||||
|
|
||||||
|
m_beginQueryId = ctx->NextQueryId(EventInfo{ nullptr, EventPhase::Begin });
|
||||||
|
|
||||||
|
GetProfiler().SendCallstack(depth);
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite(&item->hdr.type, QueueType::GpuZoneBeginCallstackSerial);
|
||||||
|
MemWrite(&item->gpuZoneBegin.cpuTime, Profiler::GetTime());
|
||||||
|
MemWrite(&item->gpuZoneBegin.srcloc, (uint64_t)srcLoc);
|
||||||
|
MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle());
|
||||||
|
MemWrite(&item->gpuZoneBegin.queryId, (uint16_t)m_beginQueryId);
|
||||||
|
MemWrite(&item->gpuZoneBegin.context, ctx->GetId());
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline OpenCLCtxScope(OpenCLCtx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, bool is_active)
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active(is_active && GetProfiler().IsConnected())
|
||||||
|
#else
|
||||||
|
: m_active(is_active)
|
||||||
|
#endif
|
||||||
|
, m_ctx(ctx)
|
||||||
|
, m_event(nullptr)
|
||||||
|
{
|
||||||
|
if (!m_active) return;
|
||||||
|
|
||||||
|
m_beginQueryId = ctx->NextQueryId(EventInfo{ nullptr, EventPhase::Begin });
|
||||||
|
|
||||||
|
const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz );
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuZoneBeginAllocSrcLocSerial );
|
||||||
|
MemWrite(&item->gpuZoneBegin.cpuTime, Profiler::GetTime());
|
||||||
|
MemWrite(&item->gpuZoneBegin.srcloc, srcloc);
|
||||||
|
MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle());
|
||||||
|
MemWrite(&item->gpuZoneBegin.queryId, (uint16_t)m_beginQueryId);
|
||||||
|
MemWrite(&item->gpuZoneBegin.context, ctx->GetId());
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline OpenCLCtxScope(OpenCLCtx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, int depth, bool is_active)
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active(is_active && GetProfiler().IsConnected())
|
||||||
|
#else
|
||||||
|
: m_active(is_active)
|
||||||
|
#endif
|
||||||
|
, m_ctx(ctx)
|
||||||
|
, m_event(nullptr)
|
||||||
|
{
|
||||||
|
if (!m_active) return;
|
||||||
|
|
||||||
|
m_beginQueryId = ctx->NextQueryId(EventInfo{ nullptr, EventPhase::Begin });
|
||||||
|
|
||||||
|
const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz );
|
||||||
|
auto item = Profiler::QueueSerialCallstack( Callstack( depth ) );
|
||||||
|
MemWrite(&item->hdr.type, QueueType::GpuZoneBeginAllocSrcLocCallstackSerial);
|
||||||
|
MemWrite(&item->gpuZoneBegin.cpuTime, Profiler::GetTime());
|
||||||
|
MemWrite(&item->gpuZoneBegin.srcloc, srcloc);
|
||||||
|
MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle());
|
||||||
|
MemWrite(&item->gpuZoneBegin.queryId, (uint16_t)m_beginQueryId);
|
||||||
|
MemWrite(&item->gpuZoneBegin.context, ctx->GetId());
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void SetEvent(cl_event event)
|
||||||
|
{
|
||||||
|
if (!m_active) return;
|
||||||
|
m_event = event;
|
||||||
|
TRACY_CL_CHECK_ERROR(clRetainEvent(m_event));
|
||||||
|
m_ctx->GetQuery(m_beginQueryId).event = m_event;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline ~OpenCLCtxScope()
|
||||||
|
{
|
||||||
|
if (!m_active) return;
|
||||||
|
const auto queryId = m_ctx->NextQueryId(EventInfo{ m_event, EventPhase::End });
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite(&item->hdr.type, QueueType::GpuZoneEndSerial);
|
||||||
|
MemWrite(&item->gpuZoneEnd.cpuTime, Profiler::GetTime());
|
||||||
|
MemWrite(&item->gpuZoneEnd.thread, GetThreadHandle());
|
||||||
|
MemWrite(&item->gpuZoneEnd.queryId, (uint16_t)queryId);
|
||||||
|
MemWrite(&item->gpuZoneEnd.context, m_ctx->GetId());
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool m_active;
|
||||||
|
OpenCLCtx* m_ctx;
|
||||||
|
cl_event m_event;
|
||||||
|
unsigned int m_beginQueryId;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline OpenCLCtx* CreateCLContext(cl_context context, cl_device_id device)
|
||||||
|
{
|
||||||
|
auto ctx = (OpenCLCtx*)tracy_malloc(sizeof(OpenCLCtx));
|
||||||
|
new (ctx) OpenCLCtx(context, device);
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void DestroyCLContext(OpenCLCtx* ctx)
|
||||||
|
{
|
||||||
|
ctx->~OpenCLCtx();
|
||||||
|
tracy_free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace tracy
|
||||||
|
|
||||||
|
using TracyCLCtx = tracy::OpenCLCtx*;
|
||||||
|
|
||||||
|
#define TracyCLContext(context, device) tracy::CreateCLContext(context, device);
|
||||||
|
#define TracyCLDestroy(ctx) tracy::DestroyCLContext(ctx);
|
||||||
|
#define TracyCLContextName(context, name, size) ctx->Name(name, size);
|
||||||
|
#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK
|
||||||
|
# define TracyCLNamedZone(ctx, varname, name, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::OpenCLCtxScope varname(ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), TRACY_CALLSTACK, active );
|
||||||
|
# define TracyCLNamedZoneC(ctx, varname, name, color, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::OpenCLCtxScope varname(ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), TRACY_CALLSTACK, active );
|
||||||
|
# define TracyCLZone(ctx, name) TracyCLNamedZoneS(ctx, __tracy_gpu_zone, name, TRACY_CALLSTACK, true)
|
||||||
|
# define TracyCLZoneC(ctx, name, color) TracyCLNamedZoneCS(ctx, __tracy_gpu_zone, name, color, TRACY_CALLSTACK, true)
|
||||||
|
# define TracyCLZoneTransient( ctx, varname, name, active ) tracy::OpenCLCtxScope varname( ctx, TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), TRACY_CALLSTACK, active );
|
||||||
|
#else
|
||||||
|
# define TracyCLNamedZone(ctx, varname, name, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine){ name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::OpenCLCtxScope varname(ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), active);
|
||||||
|
# define TracyCLNamedZoneC(ctx, varname, name, color, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine){ name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::OpenCLCtxScope varname(ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), active);
|
||||||
|
# define TracyCLZone(ctx, name) TracyCLNamedZone(ctx, __tracy_gpu_zone, name, true)
|
||||||
|
# define TracyCLZoneC(ctx, name, color) TracyCLNamedZoneC(ctx, __tracy_gpu_zone, name, color, true )
|
||||||
|
# define TracyCLZoneTransient( ctx, varname, name, active ) tracy::OpenCLCtxScope varname( ctx, TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), active );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TRACY_HAS_CALLSTACK
|
||||||
|
# define TracyCLNamedZoneS(ctx, varname, name, depth, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine){ name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::OpenCLCtxScope varname(ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), depth, active);
|
||||||
|
# define TracyCLNamedZoneCS(ctx, varname, name, color, depth, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine){ name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::OpenCLCtxScope varname(ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), depth, active);
|
||||||
|
# define TracyCLZoneS(ctx, name, depth) TracyCLNamedZoneS(ctx, __tracy_gpu_zone, name, depth, true)
|
||||||
|
# define TracyCLZoneCS(ctx, name, color, depth) TracyCLNamedZoneCS(ctx, __tracy_gpu_zone, name, color, depth, true)
|
||||||
|
# define TracyCLZoneTransientS( ctx, varname, name, depth, active ) tracy::OpenCLCtxScope varname( ctx, TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), depth, active );
|
||||||
|
#else
|
||||||
|
# define TracyCLNamedZoneS(ctx, varname, name, depth, active) TracyCLNamedZone(ctx, varname, name, active)
|
||||||
|
# define TracyCLNamedZoneCS(ctx, varname, name, color, depth, active) TracyCLNamedZoneC(ctx, varname, name, color, active)
|
||||||
|
# define TracyCLZoneS(ctx, name, depth) TracyCLZone(ctx, name)
|
||||||
|
# define TracyCLZoneCS(ctx, name, color, depth) TracyCLZoneC(ctx, name, color)
|
||||||
|
# define TracyCLZoneTransientS( ctx, varname, name, depth, active ) TracyCLZoneTransient( ctx, varname, name, active )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TracyCLNamedZoneSetEvent(varname, event) varname.SetEvent(event)
|
||||||
|
#define TracyCLZoneSetEvent(event) __tracy_gpu_zone.SetEvent(event)
|
||||||
|
|
||||||
|
#define TracyCLCollect(ctx) ctx->Collect()
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
325
externals/tracy/public/tracy/TracyOpenGL.hpp
vendored
Normal file
325
externals/tracy/public/tracy/TracyOpenGL.hpp
vendored
Normal file
@ -0,0 +1,325 @@
|
|||||||
|
#ifndef __TRACYOPENGL_HPP__
|
||||||
|
#define __TRACYOPENGL_HPP__
|
||||||
|
|
||||||
|
#if !defined TRACY_ENABLE || defined __APPLE__
|
||||||
|
|
||||||
|
#define TracyGpuContext
|
||||||
|
#define TracyGpuContextName(x,y)
|
||||||
|
#define TracyGpuNamedZone(x,y,z)
|
||||||
|
#define TracyGpuNamedZoneC(x,y,z,w)
|
||||||
|
#define TracyGpuZone(x)
|
||||||
|
#define TracyGpuZoneC(x,y)
|
||||||
|
#define TracyGpuZoneTransient(x,y,z)
|
||||||
|
#define TracyGpuCollect
|
||||||
|
|
||||||
|
#define TracyGpuNamedZoneS(x,y,z,w)
|
||||||
|
#define TracyGpuNamedZoneCS(x,y,z,w,a)
|
||||||
|
#define TracyGpuZoneS(x,y)
|
||||||
|
#define TracyGpuZoneCS(x,y,z)
|
||||||
|
#define TracyGpuZoneTransientS(x,y,z,w)
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
struct SourceLocationData;
|
||||||
|
class GpuCtxScope
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GpuCtxScope( const SourceLocationData*, bool ) {}
|
||||||
|
GpuCtxScope( const SourceLocationData*, int, bool ) {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "Tracy.hpp"
|
||||||
|
#include "../client/TracyProfiler.hpp"
|
||||||
|
#include "../client/TracyCallstack.hpp"
|
||||||
|
#include "../common/TracyAlign.hpp"
|
||||||
|
#include "../common/TracyAlloc.hpp"
|
||||||
|
|
||||||
|
#if !defined GL_TIMESTAMP && defined GL_TIMESTAMP_EXT
|
||||||
|
# define GL_TIMESTAMP GL_TIMESTAMP_EXT
|
||||||
|
# define GL_QUERY_COUNTER_BITS GL_QUERY_COUNTER_BITS_EXT
|
||||||
|
# define glGetQueryObjectiv glGetQueryObjectivEXT
|
||||||
|
# define glGetQueryObjectui64v glGetQueryObjectui64vEXT
|
||||||
|
# define glQueryCounter glQueryCounterEXT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TracyGpuContext tracy::GetGpuCtx().ptr = (tracy::GpuCtx*)tracy::tracy_malloc( sizeof( tracy::GpuCtx ) ); new(tracy::GetGpuCtx().ptr) tracy::GpuCtx;
|
||||||
|
#define TracyGpuContextName( name, size ) tracy::GetGpuCtx().ptr->Name( name, size );
|
||||||
|
#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK
|
||||||
|
# define TracyGpuNamedZone( varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::GpuCtxScope varname( &TracyConcat(__tracy_gpu_source_location,TracyLine), TRACY_CALLSTACK, active );
|
||||||
|
# define TracyGpuNamedZoneC( varname, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::GpuCtxScope varname( &TracyConcat(__tracy_gpu_source_location,TracyLine), TRACY_CALLSTACK, active );
|
||||||
|
# define TracyGpuZone( name ) TracyGpuNamedZoneS( ___tracy_gpu_zone, name, TRACY_CALLSTACK, true )
|
||||||
|
# define TracyGpuZoneC( name, color ) TracyGpuNamedZoneCS( ___tracy_gpu_zone, name, color, TRACY_CALLSTACK, true )
|
||||||
|
# define TracyGpuZoneTransient( varname, name, active ) tracy::GpuCtxScope varname( TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), TRACY_CALLSTACK, active );
|
||||||
|
#else
|
||||||
|
# define TracyGpuNamedZone( varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::GpuCtxScope varname( &TracyConcat(__tracy_gpu_source_location,TracyLine), active );
|
||||||
|
# define TracyGpuNamedZoneC( varname, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::GpuCtxScope varname( &TracyConcat(__tracy_gpu_source_location,TracyLine), active );
|
||||||
|
# define TracyGpuZone( name ) TracyGpuNamedZone( ___tracy_gpu_zone, name, true )
|
||||||
|
# define TracyGpuZoneC( name, color ) TracyGpuNamedZoneC( ___tracy_gpu_zone, name, color, true )
|
||||||
|
# define TracyGpuZoneTransient( varname, name, active ) tracy::GpuCtxScope varname( TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), active );
|
||||||
|
#endif
|
||||||
|
#define TracyGpuCollect tracy::GetGpuCtx().ptr->Collect();
|
||||||
|
|
||||||
|
#ifdef TRACY_HAS_CALLSTACK
|
||||||
|
# define TracyGpuNamedZoneS( varname, name, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::GpuCtxScope varname( &TracyConcat(__tracy_gpu_source_location,TracyLine), depth, active );
|
||||||
|
# define TracyGpuNamedZoneCS( varname, name, color, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::GpuCtxScope varname( &TracyConcat(__tracy_gpu_source_location,TracyLine), depth, active );
|
||||||
|
# define TracyGpuZoneS( name, depth ) TracyGpuNamedZoneS( ___tracy_gpu_zone, name, depth, true )
|
||||||
|
# define TracyGpuZoneCS( name, color, depth ) TracyGpuNamedZoneCS( ___tracy_gpu_zone, name, color, depth, true )
|
||||||
|
# define TracyGpuZoneTransientS( varname, name, depth, active ) tracy::GpuCtxScope varname( TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), depth, active );
|
||||||
|
#else
|
||||||
|
# define TracyGpuNamedZoneS( varname, name, depth, active ) TracyGpuNamedZone( varname, name, active )
|
||||||
|
# define TracyGpuNamedZoneCS( varname, name, color, depth, active ) TracyGpuNamedZoneC( varname, name, color, active )
|
||||||
|
# define TracyGpuZoneS( name, depth ) TracyGpuZone( name )
|
||||||
|
# define TracyGpuZoneCS( name, color, depth ) TracyGpuZoneC( name, color )
|
||||||
|
# define TracyGpuZoneTransientS( varname, name, depth, active ) TracyGpuZoneTransient( varname, name, active )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
class GpuCtx
|
||||||
|
{
|
||||||
|
friend class GpuCtxScope;
|
||||||
|
|
||||||
|
enum { QueryCount = 64 * 1024 };
|
||||||
|
|
||||||
|
public:
|
||||||
|
GpuCtx()
|
||||||
|
: m_context( GetGpuCtxCounter().fetch_add( 1, std::memory_order_relaxed ) )
|
||||||
|
, m_head( 0 )
|
||||||
|
, m_tail( 0 )
|
||||||
|
{
|
||||||
|
assert( m_context != 255 );
|
||||||
|
|
||||||
|
glGenQueries( QueryCount, m_query );
|
||||||
|
|
||||||
|
int64_t tgpu;
|
||||||
|
glGetInteger64v( GL_TIMESTAMP, &tgpu );
|
||||||
|
int64_t tcpu = Profiler::GetTime();
|
||||||
|
|
||||||
|
GLint bits;
|
||||||
|
glGetQueryiv( GL_TIMESTAMP, GL_QUERY_COUNTER_BITS, &bits );
|
||||||
|
|
||||||
|
const float period = 1.f;
|
||||||
|
const auto thread = GetThreadHandle();
|
||||||
|
TracyLfqPrepare( QueueType::GpuNewContext );
|
||||||
|
MemWrite( &item->gpuNewContext.cpuTime, tcpu );
|
||||||
|
MemWrite( &item->gpuNewContext.gpuTime, tgpu );
|
||||||
|
MemWrite( &item->gpuNewContext.thread, thread );
|
||||||
|
MemWrite( &item->gpuNewContext.period, period );
|
||||||
|
MemWrite( &item->gpuNewContext.context, m_context );
|
||||||
|
MemWrite( &item->gpuNewContext.flags, uint8_t( 0 ) );
|
||||||
|
MemWrite( &item->gpuNewContext.type, GpuContextType::OpenGl );
|
||||||
|
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
GetProfiler().DeferItem( *item );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TracyLfqCommit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Name( const char* name, uint16_t len )
|
||||||
|
{
|
||||||
|
auto ptr = (char*)tracy_malloc( len );
|
||||||
|
memcpy( ptr, name, len );
|
||||||
|
|
||||||
|
TracyLfqPrepare( QueueType::GpuContextName );
|
||||||
|
MemWrite( &item->gpuContextNameFat.context, m_context );
|
||||||
|
MemWrite( &item->gpuContextNameFat.ptr, (uint64_t)ptr );
|
||||||
|
MemWrite( &item->gpuContextNameFat.size, len );
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
GetProfiler().DeferItem( *item );
|
||||||
|
#endif
|
||||||
|
TracyLfqCommit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Collect()
|
||||||
|
{
|
||||||
|
ZoneScopedC( Color::Red4 );
|
||||||
|
|
||||||
|
if( m_tail == m_head ) return;
|
||||||
|
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if( !GetProfiler().IsConnected() )
|
||||||
|
{
|
||||||
|
m_head = m_tail = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while( m_tail != m_head )
|
||||||
|
{
|
||||||
|
GLint available;
|
||||||
|
glGetQueryObjectiv( m_query[m_tail], GL_QUERY_RESULT_AVAILABLE, &available );
|
||||||
|
if( !available ) return;
|
||||||
|
|
||||||
|
uint64_t time;
|
||||||
|
glGetQueryObjectui64v( m_query[m_tail], GL_QUERY_RESULT, &time );
|
||||||
|
|
||||||
|
TracyLfqPrepare( QueueType::GpuTime );
|
||||||
|
MemWrite( &item->gpuTime.gpuTime, (int64_t)time );
|
||||||
|
MemWrite( &item->gpuTime.queryId, (uint16_t)m_tail );
|
||||||
|
MemWrite( &item->gpuTime.context, m_context );
|
||||||
|
TracyLfqCommit;
|
||||||
|
|
||||||
|
m_tail = ( m_tail + 1 ) % QueryCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
tracy_force_inline unsigned int NextQueryId()
|
||||||
|
{
|
||||||
|
const auto id = m_head;
|
||||||
|
m_head = ( m_head + 1 ) % QueryCount;
|
||||||
|
assert( m_head != m_tail );
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline unsigned int TranslateOpenGlQueryId( unsigned int id )
|
||||||
|
{
|
||||||
|
return m_query[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline uint8_t GetId() const
|
||||||
|
{
|
||||||
|
return m_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int m_query[QueryCount];
|
||||||
|
uint8_t m_context;
|
||||||
|
|
||||||
|
unsigned int m_head;
|
||||||
|
unsigned int m_tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GpuCtxScope
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
tracy_force_inline GpuCtxScope( const SourceLocationData* srcloc, bool is_active )
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active( is_active && GetProfiler().IsConnected() )
|
||||||
|
#else
|
||||||
|
: m_active( is_active )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
|
||||||
|
const auto queryId = GetGpuCtx().ptr->NextQueryId();
|
||||||
|
glQueryCounter( GetGpuCtx().ptr->TranslateOpenGlQueryId( queryId ), GL_TIMESTAMP );
|
||||||
|
|
||||||
|
TracyLfqPrepare( QueueType::GpuZoneBegin );
|
||||||
|
MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() );
|
||||||
|
memset( &item->gpuZoneBegin.thread, 0, sizeof( item->gpuZoneBegin.thread ) );
|
||||||
|
MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) );
|
||||||
|
MemWrite( &item->gpuZoneBegin.context, GetGpuCtx().ptr->GetId() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.srcloc, (uint64_t)srcloc );
|
||||||
|
TracyLfqCommit;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline GpuCtxScope( const SourceLocationData* srcloc, int depth, bool is_active )
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active( is_active && GetProfiler().IsConnected() )
|
||||||
|
#else
|
||||||
|
: m_active( is_active )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
|
||||||
|
const auto queryId = GetGpuCtx().ptr->NextQueryId();
|
||||||
|
glQueryCounter( GetGpuCtx().ptr->TranslateOpenGlQueryId( queryId ), GL_TIMESTAMP );
|
||||||
|
|
||||||
|
#ifdef TRACY_FIBERS
|
||||||
|
TracyLfqPrepare( QueueType::GpuZoneBegin );
|
||||||
|
memset( &item->gpuZoneBegin.thread, 0, sizeof( item->gpuZoneBegin.thread ) );
|
||||||
|
#else
|
||||||
|
GetProfiler().SendCallstack( depth );
|
||||||
|
TracyLfqPrepare( QueueType::GpuZoneBeginCallstack );
|
||||||
|
MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() );
|
||||||
|
#endif
|
||||||
|
MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) );
|
||||||
|
MemWrite( &item->gpuZoneBegin.context, GetGpuCtx().ptr->GetId() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.srcloc, (uint64_t)srcloc );
|
||||||
|
TracyLfqCommit;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline GpuCtxScope( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, bool is_active )
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active( is_active && GetProfiler().IsConnected() )
|
||||||
|
#else
|
||||||
|
: m_active( is_active )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
|
||||||
|
const auto queryId = GetGpuCtx().ptr->NextQueryId();
|
||||||
|
glQueryCounter( GetGpuCtx().ptr->TranslateOpenGlQueryId( queryId ), GL_TIMESTAMP );
|
||||||
|
|
||||||
|
TracyLfqPrepare( QueueType::GpuZoneBeginAllocSrcLoc );
|
||||||
|
const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz );
|
||||||
|
MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() );
|
||||||
|
memset( &item->gpuZoneBegin.thread, 0, sizeof( item->gpuZoneBegin.thread ) );
|
||||||
|
MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) );
|
||||||
|
MemWrite( &item->gpuZoneBegin.context, GetGpuCtx().ptr->GetId() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.srcloc, (uint64_t)srcloc );
|
||||||
|
TracyLfqCommit;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline GpuCtxScope( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, int depth, bool is_active )
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active( is_active && GetProfiler().IsConnected() )
|
||||||
|
#else
|
||||||
|
: m_active( is_active )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
|
||||||
|
const auto queryId = GetGpuCtx().ptr->NextQueryId();
|
||||||
|
glQueryCounter( GetGpuCtx().ptr->TranslateOpenGlQueryId( queryId ), GL_TIMESTAMP );
|
||||||
|
|
||||||
|
#ifdef TRACY_FIBERS
|
||||||
|
TracyLfqPrepare( QueueType::GpuZoneBeginAllocSrcLoc );
|
||||||
|
memset( &item->gpuZoneBegin.thread, 0, sizeof( item->gpuZoneBegin.thread ) );
|
||||||
|
#else
|
||||||
|
GetProfiler().SendCallstack( depth );
|
||||||
|
TracyLfqPrepare( QueueType::GpuZoneBeginAllocSrcLocCallstack );
|
||||||
|
MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() );
|
||||||
|
#endif
|
||||||
|
const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz );
|
||||||
|
MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) );
|
||||||
|
MemWrite( &item->gpuZoneBegin.context, GetGpuCtx().ptr->GetId() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.srcloc, (uint64_t)srcloc );
|
||||||
|
TracyLfqCommit;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline ~GpuCtxScope()
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
|
||||||
|
const auto queryId = GetGpuCtx().ptr->NextQueryId();
|
||||||
|
glQueryCounter( GetGpuCtx().ptr->TranslateOpenGlQueryId( queryId ), GL_TIMESTAMP );
|
||||||
|
|
||||||
|
TracyLfqPrepare( QueueType::GpuZoneEnd );
|
||||||
|
MemWrite( &item->gpuZoneEnd.cpuTime, Profiler::GetTime() );
|
||||||
|
memset( &item->gpuZoneEnd.thread, 0, sizeof( item->gpuZoneEnd.thread ) );
|
||||||
|
MemWrite( &item->gpuZoneEnd.queryId, uint16_t( queryId ) );
|
||||||
|
MemWrite( &item->gpuZoneEnd.context, GetGpuCtx().ptr->GetId() );
|
||||||
|
TracyLfqCommit;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const bool m_active;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
714
externals/tracy/public/tracy/TracyVulkan.hpp
vendored
Normal file
714
externals/tracy/public/tracy/TracyVulkan.hpp
vendored
Normal file
@ -0,0 +1,714 @@
|
|||||||
|
#ifndef __TRACYVULKAN_HPP__
|
||||||
|
#define __TRACYVULKAN_HPP__
|
||||||
|
|
||||||
|
#if !defined TRACY_ENABLE
|
||||||
|
|
||||||
|
#define TracyVkContext(x,y,z,w) nullptr
|
||||||
|
#define TracyVkContextCalibrated(x,y,z,w,a,b) nullptr
|
||||||
|
#if defined VK_EXT_host_query_reset
|
||||||
|
#define TracyVkContextHostCalibrated(x,y,z,w,a) nullptr
|
||||||
|
#endif
|
||||||
|
#define TracyVkDestroy(x)
|
||||||
|
#define TracyVkContextName(c,x,y)
|
||||||
|
#define TracyVkNamedZone(c,x,y,z,w)
|
||||||
|
#define TracyVkNamedZoneC(c,x,y,z,w,a)
|
||||||
|
#define TracyVkZone(c,x,y)
|
||||||
|
#define TracyVkZoneC(c,x,y,z)
|
||||||
|
#define TracyVkZoneTransient(c,x,y,z,w)
|
||||||
|
#define TracyVkCollect(c,x)
|
||||||
|
|
||||||
|
#define TracyVkNamedZoneS(c,x,y,z,w,a)
|
||||||
|
#define TracyVkNamedZoneCS(c,x,y,z,w,v,a)
|
||||||
|
#define TracyVkZoneS(c,x,y,z)
|
||||||
|
#define TracyVkZoneCS(c,x,y,z,w)
|
||||||
|
#define TracyVkZoneTransientS(c,x,y,z,w,a)
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
class VkCtxScope {};
|
||||||
|
}
|
||||||
|
|
||||||
|
using TracyVkCtx = void*;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if !defined VK_NULL_HANDLE
|
||||||
|
# error "You must include Vulkan headers before including TracyVulkan.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "Tracy.hpp"
|
||||||
|
#include "../client/TracyProfiler.hpp"
|
||||||
|
#include "../client/TracyCallstack.hpp"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
#define LoadVkDeviceCoreSymbols(Operation) \
|
||||||
|
Operation(vkBeginCommandBuffer) \
|
||||||
|
Operation(vkCmdResetQueryPool) \
|
||||||
|
Operation(vkCmdWriteTimestamp) \
|
||||||
|
Operation(vkCreateQueryPool) \
|
||||||
|
Operation(vkDestroyQueryPool) \
|
||||||
|
Operation(vkEndCommandBuffer) \
|
||||||
|
Operation(vkGetQueryPoolResults) \
|
||||||
|
Operation(vkQueueSubmit) \
|
||||||
|
Operation(vkQueueWaitIdle) \
|
||||||
|
Operation(vkResetQueryPool)
|
||||||
|
|
||||||
|
#define LoadVkDeviceExtensionSymbols(Operation) \
|
||||||
|
Operation(vkGetCalibratedTimestampsEXT)
|
||||||
|
|
||||||
|
#define LoadVkInstanceExtensionSymbols(Operation) \
|
||||||
|
Operation(vkGetPhysicalDeviceCalibrateableTimeDomainsEXT)
|
||||||
|
|
||||||
|
#define LoadVkInstanceCoreSymbols(Operation) \
|
||||||
|
Operation(vkGetPhysicalDeviceProperties)
|
||||||
|
|
||||||
|
struct VkSymbolTable
|
||||||
|
{
|
||||||
|
#define MAKE_PFN(name) PFN_##name name;
|
||||||
|
LoadVkDeviceCoreSymbols(MAKE_PFN)
|
||||||
|
LoadVkDeviceExtensionSymbols(MAKE_PFN)
|
||||||
|
LoadVkInstanceExtensionSymbols(MAKE_PFN)
|
||||||
|
LoadVkInstanceCoreSymbols(MAKE_PFN)
|
||||||
|
#undef MAKE_PFN
|
||||||
|
};
|
||||||
|
|
||||||
|
#define VK_FUNCTION_WRAPPER(callSignature) m_symbols.callSignature
|
||||||
|
#define CONTEXT_VK_FUNCTION_WRAPPER(callSignature) m_ctx->m_symbols.callSignature
|
||||||
|
#else
|
||||||
|
#define VK_FUNCTION_WRAPPER(callSignature) callSignature
|
||||||
|
#define CONTEXT_VK_FUNCTION_WRAPPER(callSignature) callSignature
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class VkCtx
|
||||||
|
{
|
||||||
|
friend class VkCtxScope;
|
||||||
|
|
||||||
|
enum { QueryCount = 64 * 1024 };
|
||||||
|
|
||||||
|
public:
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
VkCtx( VkInstance instance, VkPhysicalDevice physdev, VkDevice device, VkQueue queue, VkCommandBuffer cmdbuf, PFN_vkGetInstanceProcAddr instanceProcAddr, PFN_vkGetDeviceProcAddr deviceProcAddr, bool calibrated )
|
||||||
|
#else
|
||||||
|
VkCtx( VkPhysicalDevice physdev, VkDevice device, VkQueue queue, VkCommandBuffer cmdbuf, PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT vkGetPhysicalDeviceCalibrateableTimeDomainsEXT, PFN_vkGetCalibratedTimestampsEXT vkGetCalibratedTimestampsEXT)
|
||||||
|
#endif
|
||||||
|
: m_device( device )
|
||||||
|
, m_timeDomain( VK_TIME_DOMAIN_DEVICE_EXT )
|
||||||
|
, m_context( GetGpuCtxCounter().fetch_add( 1, std::memory_order_relaxed ) )
|
||||||
|
, m_head( 0 )
|
||||||
|
, m_tail( 0 )
|
||||||
|
, m_oldCnt( 0 )
|
||||||
|
, m_queryCount( QueryCount )
|
||||||
|
#if !defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
, m_vkGetCalibratedTimestampsEXT( vkGetCalibratedTimestampsEXT )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
assert( m_context != 255 );
|
||||||
|
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
PopulateSymbolTable(instance, instanceProcAddr, deviceProcAddr);
|
||||||
|
if ( calibrated )
|
||||||
|
{
|
||||||
|
m_vkGetCalibratedTimestampsEXT = m_symbols.vkGetCalibratedTimestampsEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if( VK_FUNCTION_WRAPPER( vkGetPhysicalDeviceCalibrateableTimeDomainsEXT ) && m_vkGetCalibratedTimestampsEXT )
|
||||||
|
{
|
||||||
|
FindAvailableTimeDomains( physdev, VK_FUNCTION_WRAPPER( vkGetPhysicalDeviceCalibrateableTimeDomainsEXT ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateQueryPool();
|
||||||
|
|
||||||
|
VkCommandBufferBeginInfo beginInfo = {};
|
||||||
|
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
|
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||||
|
|
||||||
|
VkSubmitInfo submitInfo = {};
|
||||||
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
submitInfo.commandBufferCount = 1;
|
||||||
|
submitInfo.pCommandBuffers = &cmdbuf;
|
||||||
|
|
||||||
|
VK_FUNCTION_WRAPPER( vkBeginCommandBuffer( cmdbuf, &beginInfo ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkCmdResetQueryPool( cmdbuf, m_query, 0, m_queryCount ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkEndCommandBuffer( cmdbuf ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkQueueSubmit( queue, 1, &submitInfo, VK_NULL_HANDLE ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkQueueWaitIdle( queue ) );
|
||||||
|
|
||||||
|
int64_t tcpu, tgpu;
|
||||||
|
if( m_timeDomain == VK_TIME_DOMAIN_DEVICE_EXT )
|
||||||
|
{
|
||||||
|
VK_FUNCTION_WRAPPER( vkBeginCommandBuffer( cmdbuf, &beginInfo ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkCmdWriteTimestamp( cmdbuf, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, m_query, 0 ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkEndCommandBuffer( cmdbuf ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkQueueSubmit( queue, 1, &submitInfo, VK_NULL_HANDLE ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkQueueWaitIdle( queue ) );
|
||||||
|
|
||||||
|
tcpu = Profiler::GetTime();
|
||||||
|
VK_FUNCTION_WRAPPER( vkGetQueryPoolResults( device, m_query, 0, 1, sizeof( tgpu ), &tgpu, sizeof( tgpu ), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT ) );
|
||||||
|
|
||||||
|
VK_FUNCTION_WRAPPER( vkBeginCommandBuffer( cmdbuf, &beginInfo ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkCmdResetQueryPool( cmdbuf, m_query, 0, 1 ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkEndCommandBuffer( cmdbuf ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkQueueSubmit( queue, 1, &submitInfo, VK_NULL_HANDLE ) );
|
||||||
|
VK_FUNCTION_WRAPPER( vkQueueWaitIdle( queue ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FindCalibratedTimestampDeviation();
|
||||||
|
Calibrate( device, m_prevCalibration, tgpu );
|
||||||
|
tcpu = Profiler::GetTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteInitialItem( physdev, tcpu, tgpu );
|
||||||
|
|
||||||
|
m_res = (int64_t*)tracy_malloc( sizeof( int64_t ) * m_queryCount );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined VK_EXT_host_query_reset
|
||||||
|
/**
|
||||||
|
* This alternative constructor does not use command buffers and instead uses functionality from
|
||||||
|
* VK_EXT_host_query_reset (core with 1.2 and non-optional) and VK_EXT_calibrated_timestamps. This requires
|
||||||
|
* the physical device to have another time domain apart from DEVICE to be calibrateable.
|
||||||
|
*/
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
VkCtx( VkInstance instance, VkPhysicalDevice physdev, VkDevice device, PFN_vkGetInstanceProcAddr instanceProcAddr, PFN_vkGetDeviceProcAddr deviceProcAddr )
|
||||||
|
#else
|
||||||
|
VkCtx( VkPhysicalDevice physdev, VkDevice device, PFN_vkResetQueryPoolEXT vkResetQueryPool, PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT vkGetPhysicalDeviceCalibrateableTimeDomainsEXT, PFN_vkGetCalibratedTimestampsEXT vkGetCalibratedTimestampsEXT )
|
||||||
|
#endif
|
||||||
|
: m_device( device )
|
||||||
|
, m_timeDomain( VK_TIME_DOMAIN_DEVICE_EXT )
|
||||||
|
, m_context( GetGpuCtxCounter().fetch_add(1, std::memory_order_relaxed) )
|
||||||
|
, m_head( 0 )
|
||||||
|
, m_tail( 0 )
|
||||||
|
, m_oldCnt( 0 )
|
||||||
|
, m_queryCount( QueryCount )
|
||||||
|
#if !defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
, m_vkGetCalibratedTimestampsEXT( vkGetCalibratedTimestampsEXT )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
assert( m_context != 255);
|
||||||
|
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
PopulateSymbolTable(instance, instanceProcAddr, deviceProcAddr);
|
||||||
|
m_vkGetCalibratedTimestampsEXT = m_symbols.vkGetCalibratedTimestampsEXT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
assert( VK_FUNCTION_WRAPPER( vkResetQueryPool ) != nullptr );
|
||||||
|
assert( VK_FUNCTION_WRAPPER( vkGetPhysicalDeviceCalibrateableTimeDomainsEXT ) != nullptr );
|
||||||
|
assert( VK_FUNCTION_WRAPPER( vkGetCalibratedTimestampsEXT ) != nullptr );
|
||||||
|
|
||||||
|
FindAvailableTimeDomains( physdev, VK_FUNCTION_WRAPPER( vkGetPhysicalDeviceCalibrateableTimeDomainsEXT ) );
|
||||||
|
|
||||||
|
// We require a host time domain to be available to properly calibrate.
|
||||||
|
FindCalibratedTimestampDeviation();
|
||||||
|
int64_t tgpu;
|
||||||
|
Calibrate( device, m_prevCalibration, tgpu );
|
||||||
|
int64_t tcpu = Profiler::GetTime();
|
||||||
|
|
||||||
|
CreateQueryPool();
|
||||||
|
VK_FUNCTION_WRAPPER( vkResetQueryPool( device, m_query, 0, m_queryCount ) );
|
||||||
|
|
||||||
|
WriteInitialItem( physdev, tcpu, tgpu );
|
||||||
|
|
||||||
|
m_res = (int64_t*)tracy_malloc( sizeof( int64_t ) * m_queryCount );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
~VkCtx()
|
||||||
|
{
|
||||||
|
tracy_free( m_res );
|
||||||
|
VK_FUNCTION_WRAPPER( vkDestroyQueryPool( m_device, m_query, nullptr ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Name( const char* name, uint16_t len )
|
||||||
|
{
|
||||||
|
auto ptr = (char*)tracy_malloc( len );
|
||||||
|
memcpy( ptr, name, len );
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuContextName );
|
||||||
|
MemWrite( &item->gpuContextNameFat.context, m_context );
|
||||||
|
MemWrite( &item->gpuContextNameFat.ptr, (uint64_t)ptr );
|
||||||
|
MemWrite( &item->gpuContextNameFat.size, len );
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
GetProfiler().DeferItem( *item );
|
||||||
|
#endif
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Collect( VkCommandBuffer cmdbuf )
|
||||||
|
{
|
||||||
|
ZoneScopedC( Color::Red4 );
|
||||||
|
|
||||||
|
const uint64_t head = m_head.load(std::memory_order_relaxed);
|
||||||
|
if( m_tail == head ) return;
|
||||||
|
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if( !GetProfiler().IsConnected() )
|
||||||
|
{
|
||||||
|
VK_FUNCTION_WRAPPER( vkCmdResetQueryPool( cmdbuf, m_query, 0, m_queryCount ) );
|
||||||
|
m_tail = head;
|
||||||
|
m_oldCnt = 0;
|
||||||
|
int64_t tgpu;
|
||||||
|
if( m_timeDomain != VK_TIME_DOMAIN_DEVICE_EXT ) Calibrate( m_device, m_prevCalibration, tgpu );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
assert( head > m_tail );
|
||||||
|
|
||||||
|
const unsigned int wrappedTail = (unsigned int)( m_tail % m_queryCount );
|
||||||
|
|
||||||
|
unsigned int cnt;
|
||||||
|
if( m_oldCnt != 0 )
|
||||||
|
{
|
||||||
|
cnt = m_oldCnt;
|
||||||
|
m_oldCnt = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cnt = (unsigned int)( head - m_tail );
|
||||||
|
assert( cnt <= m_queryCount );
|
||||||
|
if( wrappedTail + cnt > m_queryCount )
|
||||||
|
{
|
||||||
|
cnt = m_queryCount - wrappedTail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if( VK_FUNCTION_WRAPPER( vkGetQueryPoolResults( m_device, m_query, wrappedTail, cnt, sizeof( int64_t ) * m_queryCount, m_res, sizeof( int64_t ), VK_QUERY_RESULT_64_BIT ) == VK_NOT_READY ) )
|
||||||
|
{
|
||||||
|
m_oldCnt = cnt;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( unsigned int idx=0; idx<cnt; idx++ )
|
||||||
|
{
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuTime );
|
||||||
|
MemWrite( &item->gpuTime.gpuTime, m_res[idx] );
|
||||||
|
MemWrite( &item->gpuTime.queryId, uint16_t( wrappedTail + idx ) );
|
||||||
|
MemWrite( &item->gpuTime.context, m_context );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_timeDomain != VK_TIME_DOMAIN_DEVICE_EXT )
|
||||||
|
{
|
||||||
|
int64_t tgpu, tcpu;
|
||||||
|
Calibrate( m_device, tcpu, tgpu );
|
||||||
|
const auto refCpu = Profiler::GetTime();
|
||||||
|
const auto delta = tcpu - m_prevCalibration;
|
||||||
|
if( delta > 0 )
|
||||||
|
{
|
||||||
|
m_prevCalibration = tcpu;
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuCalibration );
|
||||||
|
MemWrite( &item->gpuCalibration.gpuTime, tgpu );
|
||||||
|
MemWrite( &item->gpuCalibration.cpuTime, refCpu );
|
||||||
|
MemWrite( &item->gpuCalibration.cpuDelta, delta );
|
||||||
|
MemWrite( &item->gpuCalibration.context, m_context );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VK_FUNCTION_WRAPPER( vkCmdResetQueryPool( cmdbuf, m_query, wrappedTail, cnt ) );
|
||||||
|
|
||||||
|
m_tail += cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline unsigned int NextQueryId()
|
||||||
|
{
|
||||||
|
const uint64_t id = m_head.fetch_add(1, std::memory_order_relaxed);
|
||||||
|
return id % m_queryCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline uint8_t GetId() const
|
||||||
|
{
|
||||||
|
return m_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline VkQueryPool GetQueryPool() const
|
||||||
|
{
|
||||||
|
return m_query;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
tracy_force_inline void Calibrate( VkDevice device, int64_t& tCpu, int64_t& tGpu )
|
||||||
|
{
|
||||||
|
assert( m_timeDomain != VK_TIME_DOMAIN_DEVICE_EXT );
|
||||||
|
VkCalibratedTimestampInfoEXT spec[2] = {
|
||||||
|
{ VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT, nullptr, VK_TIME_DOMAIN_DEVICE_EXT },
|
||||||
|
{ VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT, nullptr, m_timeDomain },
|
||||||
|
};
|
||||||
|
uint64_t ts[2];
|
||||||
|
uint64_t deviation;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
m_vkGetCalibratedTimestampsEXT( device, 2, spec, ts, &deviation );
|
||||||
|
}
|
||||||
|
while( deviation > m_deviation );
|
||||||
|
|
||||||
|
#if defined _WIN32
|
||||||
|
tGpu = ts[0];
|
||||||
|
tCpu = ts[1] * m_qpcToNs;
|
||||||
|
#elif defined __linux__ && defined CLOCK_MONOTONIC_RAW
|
||||||
|
tGpu = ts[0];
|
||||||
|
tCpu = ts[1];
|
||||||
|
#else
|
||||||
|
assert( false );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void CreateQueryPool()
|
||||||
|
{
|
||||||
|
VkQueryPoolCreateInfo poolInfo = {};
|
||||||
|
poolInfo.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
|
||||||
|
poolInfo.queryCount = m_queryCount;
|
||||||
|
poolInfo.queryType = VK_QUERY_TYPE_TIMESTAMP;
|
||||||
|
while ( VK_FUNCTION_WRAPPER( vkCreateQueryPool( m_device, &poolInfo, nullptr, &m_query ) != VK_SUCCESS ) )
|
||||||
|
{
|
||||||
|
m_queryCount /= 2;
|
||||||
|
poolInfo.queryCount = m_queryCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void FindAvailableTimeDomains( VkPhysicalDevice physicalDevice, PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT _vkGetPhysicalDeviceCalibrateableTimeDomainsEXT )
|
||||||
|
{
|
||||||
|
uint32_t num;
|
||||||
|
_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT( physicalDevice, &num, nullptr );
|
||||||
|
if(num > 4) num = 4;
|
||||||
|
VkTimeDomainEXT data[4];
|
||||||
|
_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT( physicalDevice, &num, data );
|
||||||
|
VkTimeDomainEXT supportedDomain = (VkTimeDomainEXT)-1;
|
||||||
|
#if defined _WIN32
|
||||||
|
supportedDomain = VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT;
|
||||||
|
#elif defined __linux__ && defined CLOCK_MONOTONIC_RAW
|
||||||
|
supportedDomain = VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT;
|
||||||
|
#endif
|
||||||
|
for( uint32_t i=0; i<num; i++ ) {
|
||||||
|
if(data[i] == supportedDomain) {
|
||||||
|
m_timeDomain = data[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void FindCalibratedTimestampDeviation()
|
||||||
|
{
|
||||||
|
assert( m_timeDomain != VK_TIME_DOMAIN_DEVICE_EXT );
|
||||||
|
constexpr size_t NumProbes = 32;
|
||||||
|
VkCalibratedTimestampInfoEXT spec[2] = {
|
||||||
|
{ VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT, nullptr, VK_TIME_DOMAIN_DEVICE_EXT },
|
||||||
|
{ VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT, nullptr, m_timeDomain },
|
||||||
|
};
|
||||||
|
uint64_t ts[2];
|
||||||
|
uint64_t deviation[NumProbes];
|
||||||
|
for( int i=0; i<NumProbes; i++ ) {
|
||||||
|
m_vkGetCalibratedTimestampsEXT( m_device, 2, spec, ts, deviation + i );
|
||||||
|
}
|
||||||
|
uint64_t minDeviation = deviation[0];
|
||||||
|
for( int i=1; i<NumProbes; i++ ) {
|
||||||
|
if ( minDeviation > deviation[i] ) {
|
||||||
|
minDeviation = deviation[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_deviation = minDeviation * 3 / 2;
|
||||||
|
|
||||||
|
#if defined _WIN32
|
||||||
|
m_qpcToNs = int64_t( 1000000000. / GetFrequencyQpc() );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline void WriteInitialItem( VkPhysicalDevice physdev, int64_t tcpu, int64_t tgpu )
|
||||||
|
{
|
||||||
|
uint8_t flags = 0;
|
||||||
|
if( m_timeDomain != VK_TIME_DOMAIN_DEVICE_EXT ) flags |= GpuContextCalibration;
|
||||||
|
|
||||||
|
VkPhysicalDeviceProperties prop;
|
||||||
|
VK_FUNCTION_WRAPPER( vkGetPhysicalDeviceProperties( physdev, &prop ) );
|
||||||
|
const float period = prop.limits.timestampPeriod;
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuNewContext );
|
||||||
|
MemWrite( &item->gpuNewContext.cpuTime, tcpu );
|
||||||
|
MemWrite( &item->gpuNewContext.gpuTime, tgpu );
|
||||||
|
memset( &item->gpuNewContext.thread, 0, sizeof( item->gpuNewContext.thread ) );
|
||||||
|
MemWrite( &item->gpuNewContext.period, period );
|
||||||
|
MemWrite( &item->gpuNewContext.context, m_context );
|
||||||
|
MemWrite( &item->gpuNewContext.flags, flags );
|
||||||
|
MemWrite( &item->gpuNewContext.type, GpuContextType::Vulkan );
|
||||||
|
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
GetProfiler().DeferItem( *item );
|
||||||
|
#endif
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
void PopulateSymbolTable( VkInstance instance, PFN_vkGetInstanceProcAddr instanceProcAddr, PFN_vkGetDeviceProcAddr deviceProcAddr )
|
||||||
|
{
|
||||||
|
#define VK_GET_DEVICE_SYMBOL( name ) \
|
||||||
|
(PFN_##name)deviceProcAddr( m_device, #name );
|
||||||
|
#define VK_LOAD_DEVICE_SYMBOL( name ) \
|
||||||
|
m_symbols.name = VK_GET_DEVICE_SYMBOL( name );
|
||||||
|
#define VK_GET_INSTANCE_SYMBOL( name ) \
|
||||||
|
(PFN_##name)instanceProcAddr( instance, #name );
|
||||||
|
#define VK_LOAD_INSTANCE_SYMBOL( name ) \
|
||||||
|
m_symbols.name = VK_GET_INSTANCE_SYMBOL( name );
|
||||||
|
|
||||||
|
LoadVkDeviceCoreSymbols( VK_LOAD_DEVICE_SYMBOL )
|
||||||
|
LoadVkDeviceExtensionSymbols( VK_LOAD_DEVICE_SYMBOL )
|
||||||
|
LoadVkInstanceExtensionSymbols( VK_LOAD_INSTANCE_SYMBOL )
|
||||||
|
LoadVkInstanceCoreSymbols( VK_LOAD_INSTANCE_SYMBOL )
|
||||||
|
#undef VK_GET_DEVICE_SYMBOL
|
||||||
|
#undef VK_LOAD_DEVICE_SYMBOL
|
||||||
|
#undef VK_GET_INSTANCE_SYMBOL
|
||||||
|
#undef VK_LOAD_INSTANCE_SYMBOL
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
VkDevice m_device;
|
||||||
|
VkQueryPool m_query;
|
||||||
|
VkTimeDomainEXT m_timeDomain;
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
VkSymbolTable m_symbols;
|
||||||
|
#endif
|
||||||
|
uint64_t m_deviation;
|
||||||
|
int64_t m_qpcToNs;
|
||||||
|
int64_t m_prevCalibration;
|
||||||
|
uint8_t m_context;
|
||||||
|
|
||||||
|
std::atomic<uint64_t> m_head;
|
||||||
|
uint64_t m_tail;
|
||||||
|
unsigned int m_oldCnt;
|
||||||
|
unsigned int m_queryCount;
|
||||||
|
|
||||||
|
int64_t* m_res;
|
||||||
|
|
||||||
|
PFN_vkGetCalibratedTimestampsEXT m_vkGetCalibratedTimestampsEXT;
|
||||||
|
};
|
||||||
|
|
||||||
|
class VkCtxScope
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
tracy_force_inline VkCtxScope( VkCtx* ctx, const SourceLocationData* srcloc, VkCommandBuffer cmdbuf, bool is_active )
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active( is_active && GetProfiler().IsConnected() )
|
||||||
|
#else
|
||||||
|
: m_active( is_active )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
m_cmdbuf = cmdbuf;
|
||||||
|
m_ctx = ctx;
|
||||||
|
|
||||||
|
const auto queryId = ctx->NextQueryId();
|
||||||
|
CONTEXT_VK_FUNCTION_WRAPPER( vkCmdWriteTimestamp( cmdbuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, ctx->m_query, queryId ) );
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuZoneBeginSerial );
|
||||||
|
MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.srcloc, (uint64_t)srcloc );
|
||||||
|
MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) );
|
||||||
|
MemWrite( &item->gpuZoneBegin.context, ctx->GetId() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline VkCtxScope( VkCtx* ctx, const SourceLocationData* srcloc, VkCommandBuffer cmdbuf, int depth, bool is_active )
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active( is_active && GetProfiler().IsConnected() )
|
||||||
|
#else
|
||||||
|
: m_active( is_active )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
m_cmdbuf = cmdbuf;
|
||||||
|
m_ctx = ctx;
|
||||||
|
|
||||||
|
const auto queryId = ctx->NextQueryId();
|
||||||
|
CONTEXT_VK_FUNCTION_WRAPPER( vkCmdWriteTimestamp( cmdbuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, ctx->m_query, queryId ) );
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerialCallstack( Callstack( depth ) );
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuZoneBeginCallstackSerial );
|
||||||
|
MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.srcloc, (uint64_t)srcloc );
|
||||||
|
MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) );
|
||||||
|
MemWrite( &item->gpuZoneBegin.context, ctx->GetId() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline VkCtxScope( VkCtx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, VkCommandBuffer cmdbuf, bool is_active )
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active( is_active && GetProfiler().IsConnected() )
|
||||||
|
#else
|
||||||
|
: m_active( is_active )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
m_cmdbuf = cmdbuf;
|
||||||
|
m_ctx = ctx;
|
||||||
|
|
||||||
|
const auto queryId = ctx->NextQueryId();
|
||||||
|
CONTEXT_VK_FUNCTION_WRAPPER( vkCmdWriteTimestamp( cmdbuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, ctx->m_query, queryId ) );
|
||||||
|
|
||||||
|
const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz );
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuZoneBeginAllocSrcLocSerial );
|
||||||
|
MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.srcloc, srcloc );
|
||||||
|
MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) );
|
||||||
|
MemWrite( &item->gpuZoneBegin.context, ctx->GetId() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline VkCtxScope( VkCtx* ctx, uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, VkCommandBuffer cmdbuf, int depth, bool is_active )
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
: m_active( is_active && GetProfiler().IsConnected() )
|
||||||
|
#else
|
||||||
|
: m_active( is_active )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
m_cmdbuf = cmdbuf;
|
||||||
|
m_ctx = ctx;
|
||||||
|
|
||||||
|
const auto queryId = ctx->NextQueryId();
|
||||||
|
CONTEXT_VK_FUNCTION_WRAPPER( vkCmdWriteTimestamp( cmdbuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, ctx->m_query, queryId ) );
|
||||||
|
|
||||||
|
const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz );
|
||||||
|
auto item = Profiler::QueueSerialCallstack( Callstack( depth ) );
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuZoneBeginAllocSrcLocCallstackSerial );
|
||||||
|
MemWrite( &item->gpuZoneBegin.cpuTime, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.srcloc, srcloc );
|
||||||
|
MemWrite( &item->gpuZoneBegin.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->gpuZoneBegin.queryId, uint16_t( queryId ) );
|
||||||
|
MemWrite( &item->gpuZoneBegin.context, ctx->GetId() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracy_force_inline ~VkCtxScope()
|
||||||
|
{
|
||||||
|
if( !m_active ) return;
|
||||||
|
|
||||||
|
const auto queryId = m_ctx->NextQueryId();
|
||||||
|
CONTEXT_VK_FUNCTION_WRAPPER( vkCmdWriteTimestamp( m_cmdbuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, m_ctx->m_query, queryId ) );
|
||||||
|
|
||||||
|
auto item = Profiler::QueueSerial();
|
||||||
|
MemWrite( &item->hdr.type, QueueType::GpuZoneEndSerial );
|
||||||
|
MemWrite( &item->gpuZoneEnd.cpuTime, Profiler::GetTime() );
|
||||||
|
MemWrite( &item->gpuZoneEnd.thread, GetThreadHandle() );
|
||||||
|
MemWrite( &item->gpuZoneEnd.queryId, uint16_t( queryId ) );
|
||||||
|
MemWrite( &item->gpuZoneEnd.context, m_ctx->GetId() );
|
||||||
|
Profiler::QueueSerialFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const bool m_active;
|
||||||
|
|
||||||
|
VkCommandBuffer m_cmdbuf;
|
||||||
|
VkCtx* m_ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
static inline VkCtx* CreateVkContext( VkInstance instance, VkPhysicalDevice physdev, VkDevice device, VkQueue queue, VkCommandBuffer cmdbuf, PFN_vkGetInstanceProcAddr instanceProcAddr, PFN_vkGetDeviceProcAddr getDeviceProcAddr, bool calibrated = false )
|
||||||
|
#else
|
||||||
|
static inline VkCtx* CreateVkContext( VkPhysicalDevice physdev, VkDevice device, VkQueue queue, VkCommandBuffer cmdbuf, PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT gpdctd, PFN_vkGetCalibratedTimestampsEXT gct )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
auto ctx = (VkCtx*)tracy_malloc( sizeof( VkCtx ) );
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
new(ctx) VkCtx( instance, physdev, device, queue, cmdbuf, instanceProcAddr, getDeviceProcAddr, calibrated );
|
||||||
|
#else
|
||||||
|
new(ctx) VkCtx( physdev, device, queue, cmdbuf, gpdctd, gct );
|
||||||
|
#endif
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined VK_EXT_host_query_reset
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
static inline VkCtx* CreateVkContext( VkInstance instance, VkPhysicalDevice physdev, VkDevice device, PFN_vkGetInstanceProcAddr instanceProcAddr, PFN_vkGetDeviceProcAddr getDeviceProcAddr )
|
||||||
|
#else
|
||||||
|
static inline VkCtx* CreateVkContext( VkPhysicalDevice physdev, VkDevice device, PFN_vkResetQueryPoolEXT qpreset, PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT gpdctd, PFN_vkGetCalibratedTimestampsEXT gct )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
auto ctx = (VkCtx*)tracy_malloc( sizeof( VkCtx ) );
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
new(ctx) VkCtx( instance, physdev, device, instanceProcAddr, getDeviceProcAddr );
|
||||||
|
#else
|
||||||
|
new(ctx) VkCtx( physdev, device, qpreset, gpdctd, gct );
|
||||||
|
#endif
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline void DestroyVkContext( VkCtx* ctx )
|
||||||
|
{
|
||||||
|
ctx->~VkCtx();
|
||||||
|
tracy_free( ctx );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
using TracyVkCtx = tracy::VkCtx*;
|
||||||
|
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
#define TracyVkContext( instance, physdev, device, queue, cmdbuf, instanceProcAddr, deviceProcAddr ) tracy::CreateVkContext( instance, physdev, device, queue, cmdbuf, instanceProcAddr, deviceProcAddr );
|
||||||
|
#else
|
||||||
|
#define TracyVkContext( physdev, device, queue, cmdbuf ) tracy::CreateVkContext( physdev, device, queue, cmdbuf, nullptr, nullptr );
|
||||||
|
#endif
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
#define TracyVkContextCalibrated( instance, physdev, device, queue, cmdbuf, instanceProcAddr, deviceProcAddr ) tracy::CreateVkContext( instance, physdev, device, queue, cmdbuf, instanceProcAddr, deviceProcAddr, true );
|
||||||
|
#else
|
||||||
|
#define TracyVkContextCalibrated( physdev, device, queue, cmdbuf, gpdctd, gct ) tracy::CreateVkContext( physdev, device, queue, cmdbuf, gpdctd, gct );
|
||||||
|
#endif
|
||||||
|
#if defined VK_EXT_host_query_reset
|
||||||
|
#if defined TRACY_VK_USE_SYMBOL_TABLE
|
||||||
|
#define TracyVkContextHostCalibrated( instance, physdev, device, instanceProcAddr, deviceProcAddr ) tracy::CreateVkContext( instance, physdev, device, instanceProcAddr, deviceProcAddr );
|
||||||
|
#else
|
||||||
|
#define TracyVkContextHostCalibrated( physdev, device, qpreset, gpdctd, gct ) tracy::CreateVkContext( physdev, device, qpreset, gpdctd, gct );
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#define TracyVkDestroy( ctx ) tracy::DestroyVkContext( ctx );
|
||||||
|
#define TracyVkContextName( ctx, name, size ) ctx->Name( name, size );
|
||||||
|
#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK
|
||||||
|
# define TracyVkNamedZone( ctx, varname, cmdbuf, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), cmdbuf, TRACY_CALLSTACK, active );
|
||||||
|
# define TracyVkNamedZoneC( ctx, varname, cmdbuf, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), cmdbuf, TRACY_CALLSTACK, active );
|
||||||
|
# define TracyVkZone( ctx, cmdbuf, name ) TracyVkNamedZoneS( ctx, ___tracy_gpu_zone, cmdbuf, name, TRACY_CALLSTACK, true )
|
||||||
|
# define TracyVkZoneC( ctx, cmdbuf, name, color ) TracyVkNamedZoneCS( ctx, ___tracy_gpu_zone, cmdbuf, name, color, TRACY_CALLSTACK, true )
|
||||||
|
# define TracyVkZoneTransient( ctx, varname, cmdbuf, name, active ) TracyVkZoneTransientS( ctx, varname, cmdbuf, name, TRACY_CALLSTACK, active )
|
||||||
|
#else
|
||||||
|
# define TracyVkNamedZone( ctx, varname, cmdbuf, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), cmdbuf, active );
|
||||||
|
# define TracyVkNamedZoneC( ctx, varname, cmdbuf, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), cmdbuf, active );
|
||||||
|
# define TracyVkZone( ctx, cmdbuf, name ) TracyVkNamedZone( ctx, ___tracy_gpu_zone, cmdbuf, name, true )
|
||||||
|
# define TracyVkZoneC( ctx, cmdbuf, name, color ) TracyVkNamedZoneC( ctx, ___tracy_gpu_zone, cmdbuf, name, color, true )
|
||||||
|
# define TracyVkZoneTransient( ctx, varname, cmdbuf, name, active ) tracy::VkCtxScope varname( ctx, TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), cmdbuf, active );
|
||||||
|
#endif
|
||||||
|
#define TracyVkCollect( ctx, cmdbuf ) ctx->Collect( cmdbuf );
|
||||||
|
|
||||||
|
#ifdef TRACY_HAS_CALLSTACK
|
||||||
|
# define TracyVkNamedZoneS( ctx, varname, cmdbuf, name, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, 0 }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), cmdbuf, depth, active );
|
||||||
|
# define TracyVkNamedZoneCS( ctx, varname, cmdbuf, name, color, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,TracyLine) { name, TracyFunction, TracyFile, (uint32_t)TracyLine, color }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,TracyLine), cmdbuf, depth, active );
|
||||||
|
# define TracyVkZoneS( ctx, cmdbuf, name, depth ) TracyVkNamedZoneS( ctx, ___tracy_gpu_zone, cmdbuf, name, depth, true )
|
||||||
|
# define TracyVkZoneCS( ctx, cmdbuf, name, color, depth ) TracyVkNamedZoneCS( ctx, ___tracy_gpu_zone, cmdbuf, name, color, depth, true )
|
||||||
|
# define TracyVkZoneTransientS( ctx, varname, cmdbuf, name, depth, active ) tracy::VkCtxScope varname( ctx, TracyLine, TracyFile, strlen( TracyFile ), TracyFunction, strlen( TracyFunction ), name, strlen( name ), cmdbuf, depth, active );
|
||||||
|
#else
|
||||||
|
# define TracyVkNamedZoneS( ctx, varname, cmdbuf, name, depth, active ) TracyVkNamedZone( ctx, varname, cmdbuf, name, active )
|
||||||
|
# define TracyVkNamedZoneCS( ctx, varname, cmdbuf, name, color, depth, active ) TracyVkNamedZoneC( ctx, varname, cmdbuf, name, color, active )
|
||||||
|
# define TracyVkZoneS( ctx, cmdbuf, name, depth ) TracyVkZone( ctx, cmdbuf, name )
|
||||||
|
# define TracyVkZoneCS( ctx, cmdbuf, name, color, depth ) TracyVkZoneC( ctx, cmdbuf, name, color )
|
||||||
|
# define TracyVkZoneTransientS( ctx, varname, cmdbuf, name, depth, active ) TracyVkZoneTransient( ctx, varname, cmdbuf, name, active )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -9,6 +9,10 @@ if (ENABLE_LTO)
|
|||||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (ENABLE_PROFILING)
|
||||||
|
add_definitions(-DTRACY_ENABLE -DTRACY_ON_DEMAND)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Set compilation flags
|
# Set compilation flags
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
set(CMAKE_CONFIGURATION_TYPES Debug Release CACHE STRING "" FORCE)
|
set(CMAKE_CONFIGURATION_TYPES Debug Release CACHE STRING "" FORCE)
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/backend.h"
|
#include "common/logging/backend.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/microprofile.h"
|
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
#include "common/scope_exit.h"
|
#include "common/scope_exit.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
@ -121,7 +120,6 @@ static void TryShutdown() {
|
|||||||
Core::System::GetInstance().Shutdown();
|
Core::System::GetInstance().Shutdown();
|
||||||
window.reset();
|
window.reset();
|
||||||
InputManager::Shutdown();
|
InputManager::Shutdown();
|
||||||
MicroProfileShutdown();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool CheckMicPermission() {
|
static bool CheckMicPermission() {
|
||||||
@ -135,8 +133,6 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) {
|
|||||||
|
|
||||||
LOG_INFO(Frontend, "Citra starting...");
|
LOG_INFO(Frontend, "Citra starting...");
|
||||||
|
|
||||||
MicroProfileOnThreadCreate("EmuThread");
|
|
||||||
|
|
||||||
if (filepath.empty()) {
|
if (filepath.empty()) {
|
||||||
LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified");
|
LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified");
|
||||||
return Core::System::ResultStatus::ErrorLoader;
|
return Core::System::ResultStatus::ErrorLoader;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "audio_core/lle/lle.h"
|
#include "audio_core/lle/lle.h"
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/bit_field.h"
|
#include "common/bit_field.h"
|
||||||
|
#include "common/profiling.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
#include "common/thread.h"
|
#include "common/thread.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
@ -151,6 +152,7 @@ struct DspLle::Impl final {
|
|||||||
|
|
||||||
void TeakraThread() {
|
void TeakraThread() {
|
||||||
while (true) {
|
while (true) {
|
||||||
|
CITRA_PROFILE("Audio", "Teakra");
|
||||||
teakra.Run(TeakraSlice);
|
teakra.Run(TeakraSlice);
|
||||||
teakra_slice_barrier.Sync();
|
teakra_slice_barrier.Sync();
|
||||||
if (stop_signal) {
|
if (stop_signal) {
|
||||||
@ -174,6 +176,7 @@ struct DspLle::Impl final {
|
|||||||
if (multithread) {
|
if (multithread) {
|
||||||
teakra_slice_barrier.Sync();
|
teakra_slice_barrier.Sync();
|
||||||
} else {
|
} else {
|
||||||
|
CITRA_PROFILE("Audio", "Teakra");
|
||||||
teakra.Run(TeakraSlice);
|
teakra.Run(TeakraSlice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,6 @@
|
|||||||
#include <regex>
|
#include <regex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
// This needs to be included before getopt.h because the latter #defines symbols used by it
|
|
||||||
#include "common/microprofile.h"
|
|
||||||
|
|
||||||
#include "citra/config.h"
|
#include "citra/config.h"
|
||||||
#include "citra/emu_window/emu_window_sdl2.h"
|
#include "citra/emu_window/emu_window_sdl2.h"
|
||||||
#ifdef ENABLE_OPENGL
|
#ifdef ENABLE_OPENGL
|
||||||
@ -325,9 +321,6 @@ int main(int argc, char** argv) {
|
|||||||
LocalFree(argv_w);
|
LocalFree(argv_w);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MicroProfileOnThreadCreate("EmuThread");
|
|
||||||
SCOPE_EXIT({ MicroProfileShutdown(); });
|
|
||||||
|
|
||||||
if (filepath.empty()) {
|
if (filepath.empty()) {
|
||||||
LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified");
|
LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -112,8 +112,6 @@ add_executable(citra-qt
|
|||||||
debugger/ipc/recorder.ui
|
debugger/ipc/recorder.ui
|
||||||
debugger/lle_service_modules.cpp
|
debugger/lle_service_modules.cpp
|
||||||
debugger/lle_service_modules.h
|
debugger/lle_service_modules.h
|
||||||
debugger/profiler.cpp
|
|
||||||
debugger/profiler.h
|
|
||||||
debugger/registers.cpp
|
debugger/registers.cpp
|
||||||
debugger/registers.h
|
debugger/registers.h
|
||||||
debugger/registers.ui
|
debugger/registers.ui
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#include "citra_qt/bootmanager.h"
|
#include "citra_qt/bootmanager.h"
|
||||||
#include "citra_qt/main.h"
|
#include "citra_qt/main.h"
|
||||||
#include "common/color.h"
|
#include "common/color.h"
|
||||||
#include "common/microprofile.h"
|
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "core/3ds.h"
|
#include "core/3ds.h"
|
||||||
@ -61,7 +60,6 @@ static GMainWindow* GetMainWindow() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EmuThread::run() {
|
void EmuThread::run() {
|
||||||
MicroProfileOnThreadCreate("EmuThread");
|
|
||||||
const auto scope = core_context.Acquire();
|
const auto scope = core_context.Acquire();
|
||||||
|
|
||||||
if (Settings::values.preload_textures) {
|
if (Settings::values.preload_textures) {
|
||||||
@ -131,10 +129,6 @@ void EmuThread::run() {
|
|||||||
|
|
||||||
// Shutdown the core emulation
|
// Shutdown the core emulation
|
||||||
system.Shutdown();
|
system.Shutdown();
|
||||||
|
|
||||||
#if MICROPROFILE_ENABLED
|
|
||||||
MicroProfileOnThreadExit();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_OPENGL
|
#ifdef ENABLE_OPENGL
|
||||||
|
@ -803,9 +803,6 @@ void Config::ReadUILayoutValues() {
|
|||||||
ReadSetting(QStringLiteral("geometryRenderWindow")).toByteArray();
|
ReadSetting(QStringLiteral("geometryRenderWindow")).toByteArray();
|
||||||
UISettings::values.gamelist_header_state =
|
UISettings::values.gamelist_header_state =
|
||||||
ReadSetting(QStringLiteral("gameListHeaderState")).toByteArray();
|
ReadSetting(QStringLiteral("gameListHeaderState")).toByteArray();
|
||||||
UISettings::values.microprofile_geometry =
|
|
||||||
ReadSetting(QStringLiteral("microProfileDialogGeometry")).toByteArray();
|
|
||||||
ReadBasicSetting(UISettings::values.microprofile_visible);
|
|
||||||
|
|
||||||
qt_config->endGroup();
|
qt_config->endGroup();
|
||||||
}
|
}
|
||||||
@ -1275,9 +1272,6 @@ void Config::SaveUILayoutValues() {
|
|||||||
WriteSetting(QStringLiteral("state"), UISettings::values.state);
|
WriteSetting(QStringLiteral("state"), UISettings::values.state);
|
||||||
WriteSetting(QStringLiteral("geometryRenderWindow"), UISettings::values.renderwindow_geometry);
|
WriteSetting(QStringLiteral("geometryRenderWindow"), UISettings::values.renderwindow_geometry);
|
||||||
WriteSetting(QStringLiteral("gameListHeaderState"), UISettings::values.gamelist_header_state);
|
WriteSetting(QStringLiteral("gameListHeaderState"), UISettings::values.gamelist_header_state);
|
||||||
WriteSetting(QStringLiteral("microProfileDialogGeometry"),
|
|
||||||
UISettings::values.microprofile_geometry);
|
|
||||||
WriteBasicSetting(UISettings::values.microprofile_visible);
|
|
||||||
|
|
||||||
qt_config->endGroup();
|
qt_config->endGroup();
|
||||||
}
|
}
|
||||||
|
@ -1,231 +0,0 @@
|
|||||||
// Copyright 2015 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include <QAction>
|
|
||||||
#include <QLayout>
|
|
||||||
#include <QMouseEvent>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QString>
|
|
||||||
#include <QTimer>
|
|
||||||
#include "citra_qt/debugger/profiler.h"
|
|
||||||
#include "citra_qt/util/util.h"
|
|
||||||
#include "common/common_types.h"
|
|
||||||
#include "common/microprofile.h"
|
|
||||||
|
|
||||||
// Include the implementation of the UI in this file. This isn't in microprofile.cpp because the
|
|
||||||
// non-Qt frontends don't need it (and don't implement the UI drawing hooks either).
|
|
||||||
#if MICROPROFILE_ENABLED
|
|
||||||
#define MICROPROFILEUI_IMPL 1
|
|
||||||
#include "common/microprofileui.h"
|
|
||||||
|
|
||||||
class MicroProfileWidget : public QWidget {
|
|
||||||
public:
|
|
||||||
MicroProfileWidget(QWidget* parent = nullptr);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void paintEvent(QPaintEvent* event) override;
|
|
||||||
void showEvent(QShowEvent* event) override;
|
|
||||||
void hideEvent(QHideEvent* event) override;
|
|
||||||
|
|
||||||
void mouseMoveEvent(QMouseEvent* event) override;
|
|
||||||
void mousePressEvent(QMouseEvent* event) override;
|
|
||||||
void mouseReleaseEvent(QMouseEvent* event) override;
|
|
||||||
void wheelEvent(QWheelEvent* event) override;
|
|
||||||
|
|
||||||
void keyPressEvent(QKeyEvent* event) override;
|
|
||||||
void keyReleaseEvent(QKeyEvent* event) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// This timer is used to redraw the widget's contents continuously. To save resources, it only
|
|
||||||
/// runs while the widget is visible.
|
|
||||||
QTimer update_timer;
|
|
||||||
/// Scale the coordinate system appropriately when dpi != 96.
|
|
||||||
qreal x_scale = 1.0, y_scale = 1.0;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MicroProfileDialog::MicroProfileDialog(QWidget* parent) : QWidget(parent, Qt::Dialog) {
|
|
||||||
setObjectName(QStringLiteral("MicroProfile"));
|
|
||||||
setWindowTitle(tr("MicroProfile"));
|
|
||||||
resize(1000, 600);
|
|
||||||
// Enable the maximize button
|
|
||||||
setWindowFlags(windowFlags() | Qt::WindowMaximizeButtonHint);
|
|
||||||
|
|
||||||
#if MICROPROFILE_ENABLED
|
|
||||||
|
|
||||||
MicroProfileWidget* widget = new MicroProfileWidget(this);
|
|
||||||
|
|
||||||
QLayout* layout = new QVBoxLayout(this);
|
|
||||||
layout->setContentsMargins(0, 0, 0, 0);
|
|
||||||
layout->addWidget(widget);
|
|
||||||
setLayout(layout);
|
|
||||||
|
|
||||||
// Configure focus so that widget is focusable and the dialog automatically forwards focus to
|
|
||||||
// it.
|
|
||||||
setFocusProxy(widget);
|
|
||||||
widget->setFocusPolicy(Qt::StrongFocus);
|
|
||||||
widget->setFocus();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* MicroProfileDialog::toggleViewAction() {
|
|
||||||
if (toggle_view_action == nullptr) {
|
|
||||||
toggle_view_action = new QAction(windowTitle(), this);
|
|
||||||
toggle_view_action->setCheckable(true);
|
|
||||||
toggle_view_action->setChecked(isVisible());
|
|
||||||
connect(toggle_view_action, &QAction::toggled, this, &MicroProfileDialog::setVisible);
|
|
||||||
}
|
|
||||||
|
|
||||||
return toggle_view_action;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MicroProfileDialog::showEvent(QShowEvent* event) {
|
|
||||||
if (toggle_view_action) {
|
|
||||||
toggle_view_action->setChecked(isVisible());
|
|
||||||
}
|
|
||||||
QWidget::showEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MicroProfileDialog::hideEvent(QHideEvent* event) {
|
|
||||||
if (toggle_view_action) {
|
|
||||||
toggle_view_action->setChecked(isVisible());
|
|
||||||
}
|
|
||||||
QWidget::hideEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if MICROPROFILE_ENABLED
|
|
||||||
|
|
||||||
/// There's no way to pass a user pointer to MicroProfile, so this variable is used to make the
|
|
||||||
/// QPainter available inside the drawing callbacks.
|
|
||||||
static QPainter* mp_painter = nullptr;
|
|
||||||
|
|
||||||
MicroProfileWidget::MicroProfileWidget(QWidget* parent) : QWidget(parent) {
|
|
||||||
// Send mouse motion events even when not dragging.
|
|
||||||
setMouseTracking(true);
|
|
||||||
|
|
||||||
MicroProfileSetDisplayMode(1); // Timers screen
|
|
||||||
MicroProfileInitUI();
|
|
||||||
|
|
||||||
connect(&update_timer, &QTimer::timeout, this, qOverload<>(&MicroProfileWidget::update));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MicroProfileWidget::paintEvent([[maybe_unused]] QPaintEvent* event) {
|
|
||||||
QPainter painter(this);
|
|
||||||
|
|
||||||
// The units used by Microprofile for drawing are based in pixels on a 96 dpi display.
|
|
||||||
x_scale = qreal(painter.device()->logicalDpiX()) / 96.0;
|
|
||||||
y_scale = qreal(painter.device()->logicalDpiY()) / 96.0;
|
|
||||||
painter.scale(x_scale, y_scale);
|
|
||||||
|
|
||||||
painter.setBackground(Qt::black);
|
|
||||||
painter.eraseRect(rect());
|
|
||||||
|
|
||||||
QFont font = GetMonospaceFont();
|
|
||||||
font.setPixelSize(MICROPROFILE_TEXT_HEIGHT);
|
|
||||||
painter.setFont(font);
|
|
||||||
|
|
||||||
mp_painter = &painter;
|
|
||||||
MicroProfileDraw(rect().width() / x_scale, rect().height() / y_scale);
|
|
||||||
mp_painter = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MicroProfileWidget::showEvent(QShowEvent* event) {
|
|
||||||
update_timer.start(15); // ~60 Hz
|
|
||||||
QWidget::showEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MicroProfileWidget::hideEvent(QHideEvent* event) {
|
|
||||||
update_timer.stop();
|
|
||||||
QWidget::hideEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MicroProfileWidget::mouseMoveEvent(QMouseEvent* event) {
|
|
||||||
const auto point = event->position().toPoint();
|
|
||||||
MicroProfileMousePosition(point.x() / x_scale, point.y() / y_scale, 0);
|
|
||||||
event->accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MicroProfileWidget::mousePressEvent(QMouseEvent* event) {
|
|
||||||
const auto point = event->position().toPoint();
|
|
||||||
MicroProfileMousePosition(point.x() / x_scale, point.y() / y_scale, 0);
|
|
||||||
MicroProfileMouseButton(event->buttons() & Qt::LeftButton, event->buttons() & Qt::RightButton);
|
|
||||||
event->accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MicroProfileWidget::mouseReleaseEvent(QMouseEvent* event) {
|
|
||||||
const auto point = event->position().toPoint();
|
|
||||||
MicroProfileMousePosition(point.x() / x_scale, point.y() / y_scale, 0);
|
|
||||||
MicroProfileMouseButton(event->buttons() & Qt::LeftButton, event->buttons() & Qt::RightButton);
|
|
||||||
event->accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MicroProfileWidget::wheelEvent(QWheelEvent* event) {
|
|
||||||
const auto point = event->position().toPoint();
|
|
||||||
MicroProfileMousePosition(point.x() / x_scale, point.y() / y_scale,
|
|
||||||
event->angleDelta().y() / 120);
|
|
||||||
event->accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MicroProfileWidget::keyPressEvent(QKeyEvent* event) {
|
|
||||||
if (event->key() == Qt::Key_Control) {
|
|
||||||
// Inform MicroProfile that the user is holding Ctrl.
|
|
||||||
MicroProfileModKey(1);
|
|
||||||
}
|
|
||||||
QWidget::keyPressEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MicroProfileWidget::keyReleaseEvent(QKeyEvent* event) {
|
|
||||||
if (event->key() == Qt::Key_Control) {
|
|
||||||
MicroProfileModKey(0);
|
|
||||||
}
|
|
||||||
QWidget::keyReleaseEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
// These functions are called by MicroProfileDraw to draw the interface elements on the screen.
|
|
||||||
|
|
||||||
void MicroProfileDrawText(int x, int y, u32 hex_color, const char* text, u32 text_length) {
|
|
||||||
// hex_color does not include an alpha, so it must be assumed to be 255
|
|
||||||
mp_painter->setPen(QColor::fromRgb(hex_color));
|
|
||||||
|
|
||||||
// It's impossible to draw a string using a monospaced font with a fixed width per cell in a
|
|
||||||
// way that's reliable across different platforms and fonts as far as I (yuriks) can tell, so
|
|
||||||
// draw each character individually in order to precisely control the text advance.
|
|
||||||
for (u32 i = 0; i < text_length; ++i) {
|
|
||||||
// Position the text baseline 1 pixel above the bottom of the text cell, this gives nice
|
|
||||||
// vertical alignment of text for a wide range of tested fonts.
|
|
||||||
mp_painter->drawText(x, y + MICROPROFILE_TEXT_HEIGHT - 2, QString{QLatin1Char{text[i]}});
|
|
||||||
x += MICROPROFILE_TEXT_WIDTH + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MicroProfileDrawBox(int left, int top, int right, int bottom, u32 hex_color,
|
|
||||||
MicroProfileBoxType type) {
|
|
||||||
QColor color = QColor::fromRgba(hex_color);
|
|
||||||
QBrush brush = color;
|
|
||||||
if (type == MicroProfileBoxTypeBar) {
|
|
||||||
QLinearGradient gradient(left, top, left, bottom);
|
|
||||||
gradient.setColorAt(0.f, color.lighter(125));
|
|
||||||
gradient.setColorAt(1.f, color.darker(125));
|
|
||||||
brush = gradient;
|
|
||||||
}
|
|
||||||
mp_painter->fillRect(left, top, right - left, bottom - top, brush);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MicroProfileDrawLine2D(u32 vertices_length, float* vertices, u32 hex_color) {
|
|
||||||
// Temporary vector used to convert between the float array and QPointF. Marked static to reuse
|
|
||||||
// the allocation across calls.
|
|
||||||
static std::vector<QPointF> point_buf;
|
|
||||||
|
|
||||||
point_buf.reserve(vertices_length);
|
|
||||||
for (u32 i = 0; i < vertices_length; ++i) {
|
|
||||||
point_buf.emplace_back(vertices[i * 2 + 0], vertices[i * 2 + 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// hex_color does not include an alpha, so it must be assumed to be 255
|
|
||||||
mp_painter->setPen(QColor::fromRgb(hex_color));
|
|
||||||
mp_painter->drawPolyline(point_buf.data(), vertices_length);
|
|
||||||
point_buf.clear();
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,25 +0,0 @@
|
|||||||
// Copyright 2015 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
#include "common/microprofile.h"
|
|
||||||
|
|
||||||
class MicroProfileDialog : public QWidget {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit MicroProfileDialog(QWidget* parent = nullptr);
|
|
||||||
|
|
||||||
/// Returns a QAction that can be used to toggle visibility of this dialog.
|
|
||||||
QAction* toggleViewAction();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void showEvent(QShowEvent* event) override;
|
|
||||||
void hideEvent(QHideEvent* event) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
QAction* toggle_view_action = nullptr;
|
|
||||||
};
|
|
@ -48,7 +48,6 @@
|
|||||||
#include "citra_qt/debugger/graphics/graphics_vertex_shader.h"
|
#include "citra_qt/debugger/graphics/graphics_vertex_shader.h"
|
||||||
#include "citra_qt/debugger/ipc/recorder.h"
|
#include "citra_qt/debugger/ipc/recorder.h"
|
||||||
#include "citra_qt/debugger/lle_service_modules.h"
|
#include "citra_qt/debugger/lle_service_modules.h"
|
||||||
#include "citra_qt/debugger/profiler.h"
|
|
||||||
#include "citra_qt/debugger/registers.h"
|
#include "citra_qt/debugger/registers.h"
|
||||||
#include "citra_qt/debugger/wait_tree.h"
|
#include "citra_qt/debugger/wait_tree.h"
|
||||||
#include "citra_qt/discord.h"
|
#include "citra_qt/discord.h"
|
||||||
@ -489,12 +488,6 @@ void GMainWindow::InitializeDebugWidgets() {
|
|||||||
|
|
||||||
QMenu* debug_menu = ui->menu_View_Debugging;
|
QMenu* debug_menu = ui->menu_View_Debugging;
|
||||||
|
|
||||||
#if MICROPROFILE_ENABLED
|
|
||||||
microProfileDialog = new MicroProfileDialog(this);
|
|
||||||
microProfileDialog->hide();
|
|
||||||
debug_menu->addAction(microProfileDialog->toggleViewAction());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
registersWidget = new RegistersWidget(system, this);
|
registersWidget = new RegistersWidget(system, this);
|
||||||
addDockWidget(Qt::RightDockWidgetArea, registersWidget);
|
addDockWidget(Qt::RightDockWidgetArea, registersWidget);
|
||||||
registersWidget->hide();
|
registersWidget->hide();
|
||||||
@ -767,10 +760,6 @@ void GMainWindow::RestoreUIState() {
|
|||||||
restoreGeometry(UISettings::values.geometry);
|
restoreGeometry(UISettings::values.geometry);
|
||||||
restoreState(UISettings::values.state);
|
restoreState(UISettings::values.state);
|
||||||
render_window->restoreGeometry(UISettings::values.renderwindow_geometry);
|
render_window->restoreGeometry(UISettings::values.renderwindow_geometry);
|
||||||
#if MICROPROFILE_ENABLED
|
|
||||||
microProfileDialog->restoreGeometry(UISettings::values.microprofile_geometry);
|
|
||||||
microProfileDialog->setVisible(UISettings::values.microprofile_visible.GetValue());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
game_list->LoadInterfaceLayout();
|
game_list->LoadInterfaceLayout();
|
||||||
|
|
||||||
@ -3064,10 +3053,6 @@ void GMainWindow::UpdateUISettings() {
|
|||||||
UISettings::values.renderwindow_geometry = render_window->saveGeometry();
|
UISettings::values.renderwindow_geometry = render_window->saveGeometry();
|
||||||
}
|
}
|
||||||
UISettings::values.state = saveState();
|
UISettings::values.state = saveState();
|
||||||
#if MICROPROFILE_ENABLED
|
|
||||||
UISettings::values.microprofile_geometry = microProfileDialog->saveGeometry();
|
|
||||||
UISettings::values.microprofile_visible = microProfileDialog->isVisible();
|
|
||||||
#endif
|
|
||||||
UISettings::values.single_window_mode = ui->action_Single_Window_Mode->isChecked();
|
UISettings::values.single_window_mode = ui->action_Single_Window_Mode->isChecked();
|
||||||
UISettings::values.fullscreen = ui->action_Fullscreen->isChecked();
|
UISettings::values.fullscreen = ui->action_Fullscreen->isChecked();
|
||||||
UISettings::values.display_titlebar = ui->action_Display_Dock_Widget_Headers->isChecked();
|
UISettings::values.display_titlebar = ui->action_Display_Dock_Widget_Headers->isChecked();
|
||||||
@ -3179,8 +3164,6 @@ static Qt::HighDpiScaleFactorRoundingPolicy GetHighDpiRoundingPolicy() {
|
|||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
Common::DetachedTasks detached_tasks;
|
Common::DetachedTasks detached_tasks;
|
||||||
MicroProfileOnThreadCreate("Frontend");
|
|
||||||
SCOPE_EXIT({ MicroProfileShutdown(); });
|
|
||||||
|
|
||||||
// Init settings params
|
// Init settings params
|
||||||
QCoreApplication::setOrganizationName(QStringLiteral("Citra team"));
|
QCoreApplication::setOrganizationName(QStringLiteral("Citra team"));
|
||||||
|
@ -38,7 +38,6 @@ class GRenderWindow;
|
|||||||
class IPCRecorderWidget;
|
class IPCRecorderWidget;
|
||||||
class LLEServiceModulesWidget;
|
class LLEServiceModulesWidget;
|
||||||
class LoadingScreen;
|
class LoadingScreen;
|
||||||
class MicroProfileDialog;
|
|
||||||
class MultiplayerState;
|
class MultiplayerState;
|
||||||
class ProfilerWidget;
|
class ProfilerWidget;
|
||||||
class QFileOpenEvent;
|
class QFileOpenEvent;
|
||||||
@ -349,7 +348,6 @@ private:
|
|||||||
|
|
||||||
// Debugger panes
|
// Debugger panes
|
||||||
ProfilerWidget* profilerWidget;
|
ProfilerWidget* profilerWidget;
|
||||||
MicroProfileDialog* microProfileDialog;
|
|
||||||
RegistersWidget* registersWidget;
|
RegistersWidget* registersWidget;
|
||||||
GPUCommandStreamWidget* graphicsWidget;
|
GPUCommandStreamWidget* graphicsWidget;
|
||||||
GPUCommandListWidget* graphicsCommandsWidget;
|
GPUCommandListWidget* graphicsCommandsWidget;
|
||||||
|
@ -67,9 +67,6 @@ struct Values {
|
|||||||
|
|
||||||
QByteArray gamelist_header_state;
|
QByteArray gamelist_header_state;
|
||||||
|
|
||||||
QByteArray microprofile_geometry;
|
|
||||||
Settings::Setting<bool> microprofile_visible{false, "microProfileDialogVisible"};
|
|
||||||
|
|
||||||
Settings::Setting<bool> single_window_mode{true, "singleWindowMode"};
|
Settings::Setting<bool> single_window_mode{true, "singleWindowMode"};
|
||||||
Settings::Setting<bool> fullscreen{false, "fullscreen"};
|
Settings::Setting<bool> fullscreen{false, "fullscreen"};
|
||||||
Settings::Setting<bool> display_titlebar{true, "displayTitleBars"};
|
Settings::Setting<bool> display_titlebar{true, "displayTitleBars"};
|
||||||
|
@ -104,9 +104,6 @@ add_library(citra_common STATIC
|
|||||||
memory_detect.h
|
memory_detect.h
|
||||||
memory_ref.h
|
memory_ref.h
|
||||||
memory_ref.cpp
|
memory_ref.cpp
|
||||||
microprofile.cpp
|
|
||||||
microprofile.h
|
|
||||||
microprofileui.h
|
|
||||||
param_package.cpp
|
param_package.cpp
|
||||||
param_package.h
|
param_package.h
|
||||||
polyfill_thread.h
|
polyfill_thread.h
|
||||||
@ -150,6 +147,7 @@ add_library(citra_common STATIC
|
|||||||
x64/xbyak_util.h
|
x64/xbyak_util.h
|
||||||
zstd_compression.cpp
|
zstd_compression.cpp
|
||||||
zstd_compression.h
|
zstd_compression.h
|
||||||
|
profiling.h
|
||||||
)
|
)
|
||||||
|
|
||||||
if (UNIX AND NOT APPLE)
|
if (UNIX AND NOT APPLE)
|
||||||
@ -184,9 +182,14 @@ endif()
|
|||||||
|
|
||||||
create_target_directory_groups(citra_common)
|
create_target_directory_groups(citra_common)
|
||||||
|
|
||||||
target_link_libraries(citra_common PUBLIC fmt library-headers microprofile Boost::boost Boost::serialization Boost::iostreams)
|
target_link_libraries(citra_common PUBLIC fmt library-headers Boost::boost Boost::serialization Boost::iostreams)
|
||||||
target_link_libraries(citra_common PRIVATE zstd)
|
target_link_libraries(citra_common PRIVATE zstd)
|
||||||
|
|
||||||
|
if (ENABLE_PROFILING)
|
||||||
|
target_link_libraries(citra_common PUBLIC tracy)
|
||||||
|
target_compile_definitions(citra_common PUBLIC -DENABLE_PROFILING)
|
||||||
|
endif()
|
||||||
|
|
||||||
if ("x86_64" IN_LIST ARCHITECTURE)
|
if ("x86_64" IN_LIST ARCHITECTURE)
|
||||||
target_link_libraries(citra_common PRIVATE xbyak)
|
target_link_libraries(citra_common PRIVATE xbyak)
|
||||||
endif()
|
endif()
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
// Copyright 2015 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
// Includes the MicroProfile implementation in this file for compilation
|
|
||||||
#define MICROPROFILE_IMPL 1
|
|
||||||
#include "common/microprofile.h"
|
|
@ -1,25 +0,0 @@
|
|||||||
// Copyright 2015 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// Uncomment this to disable microprofile. This will get you cleaner profiles when using
|
|
||||||
// external sampling profilers like "Very Sleepy", and will improve performance somewhat.
|
|
||||||
// #define MICROPROFILE_ENABLED 0
|
|
||||||
|
|
||||||
// Customized Citra settings.
|
|
||||||
// This file wraps the MicroProfile header so that these are consistent everywhere.
|
|
||||||
#define MICROPROFILE_WEBSERVER 0
|
|
||||||
#define MICROPROFILE_GPU_TIMERS 0 // TODO: Implement timer queries when we upgrade to OpenGL 3.3
|
|
||||||
#define MICROPROFILE_CONTEXT_SWITCH_TRACE 0
|
|
||||||
#define MICROPROFILE_PER_THREAD_BUFFER_SIZE (2048 << 13) // 16 MB
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
// This isn't defined by the standard library in MSVC2015
|
|
||||||
typedef void* HANDLE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <microprofile.h>
|
|
||||||
|
|
||||||
#define MP_RGB(r, g, b) ((r) << 16 | (g) << 8 | (b) << 0)
|
|
@ -1,19 +0,0 @@
|
|||||||
// Copyright 2015 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common/microprofile.h"
|
|
||||||
|
|
||||||
// Customized Citra settings.
|
|
||||||
// This file wraps the MicroProfile header so that these are consistent everywhere.
|
|
||||||
#define MICROPROFILE_TEXT_WIDTH 6
|
|
||||||
#define MICROPROFILE_TEXT_HEIGHT 12
|
|
||||||
#define MICROPROFILE_HELP_ALT "Right-Click"
|
|
||||||
#define MICROPROFILE_HELP_MOD "Ctrl"
|
|
||||||
|
|
||||||
// This isn't included by microprofileui.h :(
|
|
||||||
#include <cstdlib> // For std::abs
|
|
||||||
|
|
||||||
#include <microprofileui.h>
|
|
30
src/common/profiling.h
Normal file
30
src/common/profiling.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright 2024 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef ENABLE_PROFILING
|
||||||
|
#include <tracy/Tracy.hpp>
|
||||||
|
#include "common/scope_exit.h"
|
||||||
|
|
||||||
|
#define CITRA_PROFILE(scope, text) \
|
||||||
|
ZoneScopedN(text); \
|
||||||
|
ZoneText(scope, std::string::traits_type::length(scope));
|
||||||
|
|
||||||
|
#define CITRA_SCOPED_FRAME(text) \
|
||||||
|
constexpr const char* CONCAT2(FrameTitle, __LINE__) = text; \
|
||||||
|
detail::ScopeHelper([&]() { FrameMarkStart(CONCAT2(FrameTitle, __LINE__)); }, \
|
||||||
|
[&]() { FrameMarkEnd(CONCAT2(FrameTitle, __LINE__)); })
|
||||||
|
|
||||||
|
#define CITRA_FRAME_BEGIN(text) FrameMarkStart(text)
|
||||||
|
|
||||||
|
#define CITRA_FRAME_END(text) FrameMarkEnd(text)
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define CITRA_PROFILE(scope, text)
|
||||||
|
#define CITRA_SCOPED_FRAME(text)
|
||||||
|
#define CITRA_FRAME_BEGIN(text)
|
||||||
|
#define CITRA_FRAME_END(text)
|
||||||
|
|
||||||
|
#endif
|
@ -9,19 +9,16 @@
|
|||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template <typename Func>
|
template <typename Func>
|
||||||
struct ScopeExitHelper {
|
struct ScopeHelper {
|
||||||
explicit ScopeExitHelper(Func&& func) : func(std::move(func)) {}
|
explicit ScopeHelper(auto&& enter_func, Func&& exit_func) : exit_func(std::move(exit_func)) {
|
||||||
~ScopeExitHelper() {
|
enter_func();
|
||||||
func();
|
}
|
||||||
|
~ScopeHelper() {
|
||||||
|
exit_func();
|
||||||
}
|
}
|
||||||
|
|
||||||
Func func;
|
Func exit_func;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Func>
|
|
||||||
ScopeExitHelper<Func> ScopeExit(Func&& func) {
|
|
||||||
return ScopeExitHelper<Func>(std::forward<Func>(func));
|
|
||||||
}
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,4 +38,5 @@ ScopeExitHelper<Func> ScopeExit(Func&& func) {
|
|||||||
* }
|
* }
|
||||||
* \endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
#define SCOPE_EXIT(body) auto CONCAT2(scope_exit_helper_, __LINE__) = detail::ScopeExit([&]() body)
|
#define SCOPE_EXIT(body) \
|
||||||
|
auto CONCAT2(scope_exit_helper_, __LINE__) = detail::ScopeHelper([]() {}, [&]() body)
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <dynarmic/interface/A32/a32.h>
|
#include <dynarmic/interface/A32/a32.h>
|
||||||
#include <dynarmic/interface/optimization_flags.h>
|
#include <dynarmic/interface/optimization_flags.h>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/microprofile.h"
|
#include "common/profiling.h"
|
||||||
#include "core/arm/dynarmic/arm_dynarmic.h"
|
#include "core/arm/dynarmic/arm_dynarmic.h"
|
||||||
#include "core/arm/dynarmic/arm_dynarmic_cp15.h"
|
#include "core/arm/dynarmic/arm_dynarmic_cp15.h"
|
||||||
#include "core/arm/dynarmic/arm_exclusive_monitor.h"
|
#include "core/arm/dynarmic/arm_exclusive_monitor.h"
|
||||||
@ -130,11 +130,9 @@ ARM_Dynarmic::ARM_Dynarmic(Core::System& system_, Memory::MemorySystem& memory_,
|
|||||||
|
|
||||||
ARM_Dynarmic::~ARM_Dynarmic() = default;
|
ARM_Dynarmic::~ARM_Dynarmic() = default;
|
||||||
|
|
||||||
MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64));
|
|
||||||
|
|
||||||
void ARM_Dynarmic::Run() {
|
void ARM_Dynarmic::Run() {
|
||||||
ASSERT(memory.GetCurrentPageTable() == current_page_table);
|
ASSERT(memory.GetCurrentPageTable() == current_page_table);
|
||||||
MICROPROFILE_SCOPE(ARM_Jit);
|
CITRA_PROFILE("Dynarmic", "ARM JIT");
|
||||||
|
|
||||||
jit->Run();
|
jit->Run();
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/microprofile.h"
|
#include "common/profiling.h"
|
||||||
#include "core/arm/dyncom/arm_dyncom_dec.h"
|
#include "core/arm/dyncom/arm_dyncom_dec.h"
|
||||||
#include "core/arm/dyncom/arm_dyncom_interpreter.h"
|
#include "core/arm/dyncom/arm_dyncom_interpreter.h"
|
||||||
#include "core/arm/dyncom/arm_dyncom_run.h"
|
#include "core/arm/dyncom/arm_dyncom_run.h"
|
||||||
@ -805,8 +805,6 @@ static ThumbDecodeStatus DecodeThumbInstruction(u32 inst, u32 addr, u32* arm_ins
|
|||||||
|
|
||||||
enum { KEEP_GOING, FETCH_EXCEPTION };
|
enum { KEEP_GOING, FETCH_EXCEPTION };
|
||||||
|
|
||||||
MICROPROFILE_DEFINE(DynCom_Decode, "DynCom", "Decode", MP_RGB(255, 64, 64));
|
|
||||||
|
|
||||||
static unsigned int InterpreterTranslateInstruction(const ARMul_State* cpu, const u32 phys_addr,
|
static unsigned int InterpreterTranslateInstruction(const ARMul_State* cpu, const u32 phys_addr,
|
||||||
ARM_INST_PTR& inst_base) {
|
ARM_INST_PTR& inst_base) {
|
||||||
u32 inst_size = 4;
|
u32 inst_size = 4;
|
||||||
@ -840,7 +838,7 @@ static unsigned int InterpreterTranslateInstruction(const ARMul_State* cpu, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int InterpreterTranslateBlock(ARMul_State* cpu, std::size_t& bb_start, u32 addr) {
|
static int InterpreterTranslateBlock(ARMul_State* cpu, std::size_t& bb_start, u32 addr) {
|
||||||
MICROPROFILE_SCOPE(DynCom_Decode);
|
CITRA_PROFILE("DynCom", "Decode");
|
||||||
|
|
||||||
// Decode instruction, get index
|
// Decode instruction, get index
|
||||||
// Allocate memory and init InsCream
|
// Allocate memory and init InsCream
|
||||||
@ -869,7 +867,7 @@ static int InterpreterTranslateBlock(ARMul_State* cpu, std::size_t& bb_start, u3
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int InterpreterTranslateSingle(ARMul_State* cpu, std::size_t& bb_start, u32 addr) {
|
static int InterpreterTranslateSingle(ARMul_State* cpu, std::size_t& bb_start, u32 addr) {
|
||||||
MICROPROFILE_SCOPE(DynCom_Decode);
|
CITRA_PROFILE("DynCom", "Decode");
|
||||||
|
|
||||||
ARM_INST_PTR inst_base = nullptr;
|
ARM_INST_PTR inst_base = nullptr;
|
||||||
bb_start = trans_cache_buf_top;
|
bb_start = trans_cache_buf_top;
|
||||||
@ -913,10 +911,8 @@ static int clz(unsigned int x) {
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
MICROPROFILE_DEFINE(DynCom_Execute, "DynCom", "Execute", MP_RGB(255, 0, 0));
|
|
||||||
|
|
||||||
unsigned InterpreterMainLoop(ARMul_State* cpu) {
|
unsigned InterpreterMainLoop(ARMul_State* cpu) {
|
||||||
MICROPROFILE_SCOPE(DynCom_Execute);
|
CITRA_PROFILE("DynCom", "Execute");
|
||||||
|
|
||||||
/// Nearest upcoming GDB code execution breakpoint, relative to the last dispatch's address.
|
/// Nearest upcoming GDB code execution breakpoint, relative to the last dispatch's address.
|
||||||
GDBStub::BreakpointAddress breakpoint_data;
|
GDBStub::BreakpointAddress breakpoint_data;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include "common/archives.h"
|
#include "common/archives.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/microprofile.h"
|
#include "common/profiling.h"
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
#include "core/arm/arm_interface.h"
|
#include "core/arm/arm_interface.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
@ -2233,10 +2233,8 @@ const SVC::FunctionDef* SVC::GetSVCInfo(u32 func_num) {
|
|||||||
return &SVC_Table[func_num];
|
return &SVC_Table[func_num];
|
||||||
}
|
}
|
||||||
|
|
||||||
MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
|
|
||||||
|
|
||||||
void SVC::CallSVC(u32 immediate) {
|
void SVC::CallSVC(u32 immediate) {
|
||||||
MICROPROFILE_SCOPE(Kernel_SVC);
|
CITRA_PROFILE("Kernel", "SVC");
|
||||||
|
|
||||||
// Lock the kernel mutex when we enter the kernel HLE.
|
// Lock the kernel mutex when we enter the kernel HLE.
|
||||||
std::scoped_lock lock{kernel.GetHLELock()};
|
std::scoped_lock lock{kernel.GetHLELock()};
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user