1
0
mirror of https://github.com/wolfpld/tracy synced 2025-04-29 20:33:52 +00:00

Compare commits

..

No commits in common. "master" and "v0.8.2.1" have entirely different histories.

493 changed files with 324161 additions and 260315 deletions

View File

@ -1,18 +0,0 @@
# Empirical format config, based on observed style guide
# Use this only as an help to fit the surrounding code style - don't reformat whole files at once
---
BasedOnStyle: LLVM
AllowShortIfStatementsOnASingleLine: WithoutElse
AllowShortLoopsOnASingleLine: true
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBraces: Allman
BreakConstructorInitializers: BeforeComma
BreakStringLiterals: false
ColumnLimit: 120
FixNamespaceComments: false
IndentPPDirectives: AfterHash
IndentWidth: 4
PointerAlignment: Left
SpaceBeforeParens: Never
SpacesInParentheses: true
TabWidth: 4

View File

@ -1,61 +0,0 @@
---
Checks:
'
clang-diagnostic-*,
clang-analyzer-*,
bugprone-*,
google-*,
misc-*,
modernize-*,
performance-*,
readability-*,
-bugprone-easily-swappable-parameters,
-bugprone-implicit-widening-of-multiplication-result,
-bugprone-narrowing-conversions,
-bugprone-reserved-identifier,
-google-readability-braces-around-statements,
-google-readability-casting,
-google-readability-function-size,
-google-readability-todo,
-google-readability-namespace-comments,
-misc-confusable-identifiers,
-misc-no-recursion,
-modernize-avoid-c-arrays,
-modernize-deprecated-headers,
-modernize-use-default-member-init,
-modernize-use-trailing-return-type,
-performance-no-int-to-ptr,
-readability-braces-around-statements,
-readability-else-after-return,
-readability-function-cognitive-complexity,
-readability-identifier-length,
-readability-implicit-bool-conversion,
-readability-isolate-declaration,
-readability-magic-numbers,
-readability-qualified-auto,
-readability-uppercase-literal-suffix
'
WarningsAsErrors: ''
HeaderFilterRegex: ''
FormatStyle: none
CheckOptions:
llvm-else-after-return.WarnOnConditionVariables: 'false'
modernize-loop-convert.MinConfidence: reasonable
modernize-replace-auto-ptr.IncludeStyle: llvm
modernize-pass-by-value.IncludeStyle: llvm
google-readability-namespace-comments.ShortNamespaceLines: '10'
google-readability-namespace-comments.SpacesBeforeComments: '2'
cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic: 'true'
google-readability-braces-around-statements.ShortStatementLines: '1'
cert-err33-c.CheckedFunctions: '::aligned_alloc;::asctime_s;::at_quick_exit;::atexit;::bsearch;::bsearch_s;::btowc;::c16rtomb;::c32rtomb;::calloc;::clock;::cnd_broadcast;::cnd_init;::cnd_signal;::cnd_timedwait;::cnd_wait;::ctime_s;::fclose;::fflush;::fgetc;::fgetpos;::fgets;::fgetwc;::fopen;::fopen_s;::fprintf;::fprintf_s;::fputc;::fputs;::fputwc;::fputws;::fread;::freopen;::freopen_s;::fscanf;::fscanf_s;::fseek;::fsetpos;::ftell;::fwprintf;::fwprintf_s;::fwrite;::fwscanf;::fwscanf_s;::getc;::getchar;::getenv;::getenv_s;::gets_s;::getwc;::getwchar;::gmtime;::gmtime_s;::localtime;::localtime_s;::malloc;::mbrtoc16;::mbrtoc32;::mbsrtowcs;::mbsrtowcs_s;::mbstowcs;::mbstowcs_s;::memchr;::mktime;::mtx_init;::mtx_lock;::mtx_timedlock;::mtx_trylock;::mtx_unlock;::printf_s;::putc;::putwc;::raise;::realloc;::remove;::rename;::scanf;::scanf_s;::setlocale;::setvbuf;::signal;::snprintf;::snprintf_s;::sprintf;::sprintf_s;::sscanf;::sscanf_s;::strchr;::strerror_s;::strftime;::strpbrk;::strrchr;::strstr;::strtod;::strtof;::strtoimax;::strtok;::strtok_s;::strtol;::strtold;::strtoll;::strtoul;::strtoull;::strtoumax;::strxfrm;::swprintf;::swprintf_s;::swscanf;::swscanf_s;::thrd_create;::thrd_detach;::thrd_join;::thrd_sleep;::time;::timespec_get;::tmpfile;::tmpfile_s;::tmpnam;::tmpnam_s;::tss_create;::tss_get;::tss_set;::ungetc;::ungetwc;::vfprintf;::vfprintf_s;::vfscanf;::vfscanf_s;::vfwprintf;::vfwprintf_s;::vfwscanf;::vfwscanf_s;::vprintf_s;::vscanf;::vscanf_s;::vsnprintf;::vsnprintf_s;::vsprintf;::vsprintf_s;::vsscanf;::vsscanf_s;::vswprintf;::vswprintf_s;::vswscanf;::vswscanf_s;::vwprintf_s;::vwscanf;::vwscanf_s;::wcrtomb;::wcschr;::wcsftime;::wcspbrk;::wcsrchr;::wcsrtombs;::wcsrtombs_s;::wcsstr;::wcstod;::wcstof;::wcstoimax;::wcstok;::wcstok_s;::wcstol;::wcstold;::wcstoll;::wcstombs;::wcstombs_s;::wcstoul;::wcstoull;::wcstoumax;::wcsxfrm;::wctob;::wctrans;::wctype;::wmemchr;::wprintf_s;::wscanf;::wscanf_s;'
modernize-loop-convert.MaxCopySize: '16'
cert-dcl16-c.NewSuffixes: 'L;LL;LU;LLU'
cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField: 'false'
cert-str34-c.DiagnoseSignedUnsignedCharComparisons: 'false'
modernize-use-nullptr.NullMacros: 'NULL'
llvm-qualified-auto.AddConstToQualified: 'false'
modernize-loop-convert.NamingStyle: CamelCase
llvm-else-after-return.WarnOnUnfixable: 'false'
google-readability-function-size.StatementThreshold: '800'
...

View File

@ -1,83 +0,0 @@
name: build
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
env:
CPM_SOURCE_CACHE: ${{ github.workspace }}/cpm-cache
jobs:
build:
strategy:
matrix:
os: [ windows-latest, macos-15 ]
runs-on: ${{ matrix.os }}
continue-on-error: true
steps:
- uses: actions/checkout@v4
- if: startsWith(matrix.os, 'windows')
uses: microsoft/setup-msbuild@v2
- if: startsWith(matrix.os, 'windows')
uses: actions/setup-python@v2
with:
python-version: '3.x'
- if: startsWith(matrix.os, 'windows')
run: pip install meson ninja
- if: startsWith(matrix.os, 'macos')
name: Install macos dependencies
run: brew install pkg-config glfw meson
- name: Trust git repo
run: git config --global --add safe.directory '*'
- name: Profiler GUI
run: |
cmake -B profiler/build -S profiler -DCMAKE_BUILD_TYPE=Release -DGIT_REV=${{ github.sha }}
cmake --build profiler/build --parallel --config Release
- name: Update utility
run: |
cmake -B update/build -S update -DCMAKE_BUILD_TYPE=Release
cmake --build update/build --parallel --config Release
- name: Capture utility
run: |
cmake -B capture/build -S capture -DCMAKE_BUILD_TYPE=Release
cmake --build capture/build --parallel --config Release
- name: Csvexport utility
run: |
cmake -B csvexport/build -S csvexport -DCMAKE_BUILD_TYPE=Release
cmake --build csvexport/build --parallel --config Release
- name: Import utilities
run: |
cmake -B import/build -S import -DCMAKE_BUILD_TYPE=Release
cmake --build import/build --parallel --config Release
- if: ${{ !startsWith(matrix.os, 'windows') }}
name: Library
run: meson setup -Dprefix=$GITHUB_WORKSPACE/bin/lib build && meson compile -C build && meson install -C build
- if: ${{ !startsWith(matrix.os, 'windows') }}
name: Find Artifacts
id: find_artifacts
run: |
mkdir -p bin
cp profiler/build/tracy-profiler bin
cp update/build/tracy-update bin
cp capture/build/tracy-capture bin
cp csvexport/build/tracy-csvexport bin
cp import/build/tracy-import-chrome bin
cp import/build/tracy-import-fuchsia bin
- if: startsWith(matrix.os, 'windows')
name: Find Artifacts
id: find_artifacts_windows
run: |
mkdir bin
copy profiler\build\Release\tracy-profiler.exe bin
copy update\build\Release\tracy-update.exe bin
copy capture\build\Release\tracy-capture.exe bin
copy csvexport\build\Release\tracy-csvexport.exe bin
copy import\build\Release\tracy-import-chrome.exe bin
copy import\build\Release\tracy-import-fuchsia.exe bin
- uses: actions/upload-artifact@v4
with:
name: ${{ matrix.os }}
path: bin

View File

@ -1,63 +0,0 @@
name: emscripten
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
env:
CPM_SOURCE_CACHE: ${{ github.workspace }}/cpm-cache
jobs:
build:
runs-on: ubuntu-latest
container: archlinux:base-devel
steps:
- name: Install dependencies
run: pacman -Syu --noconfirm && pacman -S --noconfirm --needed cmake git unzip python ninja zstd
- name: Setup emscripten
uses: mymindstorm/setup-emsdk@v14
with:
version: 3.1.67
- name: Trust git repo
run: git config --global --add safe.directory '*'
- uses: actions/checkout@v4
- name: Profiler GUI
run: |
cmake -G Ninja -B profiler/build -S profiler -DCMAKE_BUILD_TYPE=MinSizeRel -DGIT_REV=${{ github.sha }} -DCMAKE_TOOLCHAIN_FILE=${{env.EMSDK}}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake
cmake --build profiler/build --parallel
- name: Compress artifacts
run: |
zstd -18 profiler/build/tracy-profiler.js profiler/build/tracy-profiler.wasm
gzip -9 profiler/build/tracy-profiler.js profiler/build/tracy-profiler.wasm
- name: Find Artifacts
id: find_artifacts
run: |
mkdir -p bin
cp profiler/build/index.html bin
cp profiler/build/favicon.svg bin
cp profiler/build/tracy-profiler.data bin
cp profiler/build/tracy-profiler.js.gz bin
cp profiler/build/tracy-profiler.js.zst bin
cp profiler/build/tracy-profiler.wasm.gz bin
cp profiler/build/tracy-profiler.wasm.zst bin
- uses: actions/upload-artifact@v4
with:
name: emscripten
path: bin
deploy:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/master'
steps:
- uses: actions/download-artifact@v4
- uses: wlixcc/SFTP-Deploy-Action@v1.2.4
with:
username: ${{ secrets.USERNAME }}
server: ${{ secrets.SERVER }}
port: ${{ secrets.PORT }}
ssh_private_key: ${{ secrets.PRIVATE_KEY }}
local_path: './emscripten/*'
remote_path: ${{ secrets.REMOTE_PATH }}
sftp_only: true

44
.github/workflows/gcc.yml vendored Normal file
View File

@ -0,0 +1,44 @@
name: gcc
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, macOS-latest]
steps:
- uses: actions/checkout@v2
- name: Install linux libraries
if: ${{ matrix.os == 'ubuntu-22.04' }}
run: sudo apt-get update && sudo apt-get -y install libglfw3-dev libdbus-1-dev libcapstone-dev libtbb-dev libdebuginfod-dev
- name: Install macos libraries
if: ${{ matrix.os == 'macOS-latest' }}
run: brew install capstone tbb pkg-config glfw
- name: Profiler GUI
run: make -j -C profiler/build/unix debug release
- name: Update utility
run: make -j -C update/build/unix debug release
- name: Capture utility
run: make -j -C capture/build/unix debug release
- name: Csvexport utility
run: make -j -C csvexport/build/unix debug release
- name: Import-chrome utility
run: make -j -C import-chrome/build/unix debug release
- name: Library
run: make -j -C library/unix debug release
- name: Test application
run: |
make -j -C test
make -j -C test clean
make -j -C test TRACYFLAGS=-DTRACY_ON_DEMAND
make -j -C test clean
make -j -C test TRACYFLAGS="-DTRACY_DELAYED_INIT -DTRACY_MANUAL_LIFETIME"

View File

@ -12,16 +12,17 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
- name: Fix stupidity
run: |
cp AUTHORS AUTHORS.
cp LICENSE LICENSE.
- name: Compile LaTeX
uses: xu-cheng/latex-action@v3
uses: xu-cheng/latex-action@v2
with:
working_directory: manual
root_file: tracy.tex
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v2
with:
name: manual
path: manual/tracy.pdf

View File

@ -1,80 +0,0 @@
name: linux
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
env:
CPM_SOURCE_CACHE: ${{ github.workspace }}/cpm-cache
jobs:
build:
runs-on: ubuntu-latest
container: archlinux:base-devel
steps:
- name: Install dependencies
run: pacman -Syu --noconfirm && pacman -S --noconfirm --needed freetype2 debuginfod wayland dbus libxkbcommon libglvnd meson cmake git wayland-protocols nodejs
- name: Trust git repo
run: git config --global --add safe.directory '*'
- uses: actions/checkout@v4
- name: Profiler GUI
run: |
cmake -B profiler/build -S profiler -DCMAKE_BUILD_TYPE=Release -DGIT_REV=${{ github.sha }}
cmake --build profiler/build --parallel
- name: Update utility
run: |
cmake -B update/build -S update -DCMAKE_BUILD_TYPE=Release
cmake --build update/build --parallel
- name: Capture utility
run: |
cmake -B capture/build -S capture -DCMAKE_BUILD_TYPE=Release
cmake --build capture/build --parallel
- name: Csvexport utility
run: |
cmake -B csvexport/build -S csvexport -DCMAKE_BUILD_TYPE=Release
cmake --build csvexport/build --parallel
- name: Import utilities
run: |
cmake -B import/build -S import -DCMAKE_BUILD_TYPE=Release
cmake --build import/build --parallel
- name: Library
run: meson setup -Dprefix=$GITHUB_WORKSPACE/bin/lib build && meson compile -C build && meson install -C build
- name: Test application
run: |
# test compilation with different flags
# we clean the build folder to reset cached variables between runs
cmake -B test/build -S test -DCMAKE_BUILD_TYPE=Release
cmake --build test/build --parallel
rm -rf test/build
# same with TRACY_ON_DEMAND
cmake -B test/build -S test -DCMAKE_BUILD_TYPE=Release -DTRACY_ON_DEMAND=ON .
cmake --build test/build --parallel
rm -rf test/build
# same with TRACY_DELAYED_INIT TRACY_MANUAL_LIFETIME
cmake -B test/build -S test -DCMAKE_BUILD_TYPE=Release -DTRACY_DELAYED_INIT=ON -DTRACY_MANUAL_LIFETIME=ON .
cmake --build test/build --parallel
rm -rf test/build
# same with TRACY_DEMANGLE
cmake -B test/build -S test -DCMAKE_BUILD_TYPE=Release -DTRACY_DEMANGLE=ON .
cmake --build test/build --parallel
rm -rf test/build
- name: Find Artifacts
id: find_artifacts
run: |
mkdir -p bin
cp profiler/build/tracy-profiler bin
cp update/build/tracy-update bin
cp capture/build/tracy-capture bin
cp csvexport/build/tracy-csvexport bin
cp import/build/tracy-import-chrome bin
cp import/build/tracy-import-fuchsia bin
strip bin/tracy-*
- uses: actions/upload-artifact@v4
with:
name: arch-linux
path: bin

72
.github/workflows/msvc.yml vendored Normal file
View File

@ -0,0 +1,72 @@
name: MSVC
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build-with-vcpkg-integration:
runs-on: windows-2022
steps:
- uses: actions/checkout@v2
- uses: microsoft/setup-msbuild@v1.0.2
- name: Integrate vcpkg
run: vcpkg integrate install
- name: Profiler GUI Debug
run: msbuild .\profiler\build\win32\Tracy.vcxproj /property:Configuration=Debug /property:Platform=x64
- name: Profiler GUI Release
run: msbuild .\profiler\build\win32\Tracy.vcxproj /property:Configuration=Release /property:Platform=x64
- name: Update utility Debug
run: msbuild .\update\build\win32\update.vcxproj /property:Configuration=Debug /property:Platform=x64
- name: Update utility Release
run: msbuild .\update\build\win32\update.vcxproj /property:Configuration=Release /property:Platform=x64
- name: Capture utility Debug
run: msbuild .\capture\build\win32\capture.vcxproj /property:Configuration=Debug /property:Platform=x64
- name: Capture utility Release
run: msbuild .\capture\build\win32\capture.vcxproj /property:Configuration=Release /property:Platform=x64
- name: Csvexport utility Debug
run: msbuild .\csvexport\build\win32\csvexport.vcxproj /property:Configuration=Debug /property:Platform=x64
- name: Csvexport utility Release
run: msbuild .\csvexport\build\win32\csvexport.vcxproj /property:Configuration=Release /property:Platform=x64
- name: Import-chrome utility Debug
run: msbuild .\import-chrome\build\win32\import-chrome.vcxproj /property:Configuration=Debug /property:Platform=x64
- name: Import-chrome utility Release
run: msbuild .\import-chrome\build\win32\import-chrome.vcxproj /property:Configuration=Release /property:Platform=x64
- name: Library
run: msbuild .\library\win32\TracyProfiler.vcxproj /property:Configuration=Release /property:Platform=x64
- name: Package binaries
run: |
mkdir bin
mkdir bin\dev
copy profiler\build\win32\x64\Release\Tracy.exe bin
copy update\build\win32\x64\Release\update.exe bin
copy capture\build\win32\x64\Release\capture.exe bin
copy import-chrome\build\win32\x64\Release\import-chrome.exe bin
copy csvexport\build\win32\x64\Release\csvexport.exe bin
copy library\win32\x64\Release\TracyProfiler.dll bin\dev
copy library\win32\x64\Release\TracyProfiler.lib bin\dev
7z a Tracy.7z bin
- uses: actions/upload-artifact@v2
with:
path: Tracy.7z
build-without-vcpkg-integration:
runs-on: windows-2022
env:
VCPKG_ROOT: ''
steps:
- uses: actions/checkout@v2
- uses: microsoft/setup-msbuild@v1.0.2
- name: Install vcpkg dependencies
run: vcpkg/install_vcpkg_dependencies.bat
- name: Profiler GUI Release
run: msbuild .\profiler\build\win32\Tracy.vcxproj /property:Configuration=Release /property:Platform=x64
- name: Capture utility Release
run: msbuild .\capture\build\win32\capture.vcxproj /property:Configuration=Release /property:Platform=x64

20
.gitignore vendored
View File

@ -1,4 +1,10 @@
.vs
*.opendb
*.db
*.vcxproj.user
x64
Release
Debug
_build
_compiler
tools/*
@ -6,7 +12,6 @@ tools/*
*.o
*.so
*.swp
*.obj
imgui.ini
test/tracy_test
test/tracy_test.exe
@ -19,18 +24,19 @@ manual/t*.synctex.gz
manual/t*.toc
manual/t*.bbl
manual/t*.blg
manual/t*.fdb_latexmk
manual/t*.fls
profiler/build/win32/packages
profiler/build/win32/Tracy.aps
# include the vcpkg install script but not the files it produces
vcpkg/*
!vcpkg/install_vcpkg_dependencies.bat
/vcpkg_installed
.deps/
.dirstamp
.vscode/
/_*/**
/**/__pycache__/**
extra/vswhere.exe
extra/tracy-build
.cache
/.cache
compile_commands.json
profiler/build/wasm/Tracy-release.*
profiler/build/wasm/Tracy-debug.*
profiler/build/wasm/embed.tracy

View File

@ -1,2 +0,0 @@
<wolf@nereid.pl> <wolf.pld@gmail.com>
<wolf@nereid.pl> <bartosz.taudul@game-lion.com>

17
.vscode/c_cpp_properties.json vendored Normal file
View File

@ -0,0 +1,17 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/usr/include/freetype2"
],
"defines": [],
"compilerPath": "/usr/bin/clang++",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "clang-x64"
}
],
"version": 4
}

View File

@ -1,7 +0,0 @@
{
"recommendations": [
"llvm-vs-code-extensions.vscode-clangd",
"vadimcn.vscode-lldb",
"ms-vscode.cmake-tools"
]
}

55
.vscode/launch.json vendored
View File

@ -1,13 +1,58 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch",
"name": "Launch Profiler GUI",
"type": "lldb",
"request": "launch",
"program": "${command:cmake.launchTargetPath}",
"program": "${workspaceFolder}/profiler/build/unix/Tracy-debug",
"args": [],
"cwd": "${workspaceFolder}"
}
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"preLaunchTask": "Build Profiler GUI",
"console": "internalConsole",
"internalConsoleOptions": "neverOpen"
},
{
"name": "Launch capture tool",
"type": "lldb",
"request": "launch",
"program": "${workspaceFolder}/capture/build/unix/capture-debug",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"preLaunchTask": "Build capture tool"
},
{
"name": "Launch update tool",
"type": "lldb",
"request": "launch",
"program": "${workspaceFolder}/update/build/unix/update-debug",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"preLaunchTask": "Build update tool"
},
{
"name": "Launch test application",
"type": "lldb",
"request": "launch",
"program": "${workspaceFolder}/test/tracy_test",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/test",
"environment": [],
"externalConsole": false,
"preLaunchTask": "Build test application"
},
]
}
}

20
.vscode/settings.json vendored
View File

@ -1,20 +0,0 @@
{
"cmake.configureOnOpen": true,
"cmake.sourceDirectory": [
"${workspaceFolder}/profiler",
"${workspaceFolder}/capture",
"${workspaceFolder}/csvexport",
"${workspaceFolder}/import",
"${workspaceFolder}/update",
"${workspaceFolder}/test",
"${workspaceFolder}",
],
"cmake.buildDirectory": "${sourceDirectory}/build",
"cmake.autoSelectActiveFolder": false,
"cmake.options.advanced": {
"folder": { "statusBarVisibility": "visible" },
"variant": { "statusBarVisibility": "compact" }
},
"cmake.copyCompileCommands": "${workspaceFolder}/compile_commands.json",
"lldb.launch.initCommands": ["command script import ${workspaceRoot}/extra/natvis.py"],
}

88
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,88 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Build Profiler GUI",
"type": "shell",
"command": "CC=clang CXX=clang++ make debug -C profiler/build/unix -j `nproc`",
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"close": true
}
},
{
"label": "Build capture tool",
"type": "shell",
"command": "CC=clang CXX=clang++ make debug -C capture/build/unix -j `nproc`",
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"close": true
}
},
{
"label": "Build csvexport tool",
"type": "shell",
"command": "CC=clang CXX=clang++ make debug -C csvexport/build/unix -j `nproc`",
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"close": true
}
},
{
"label": "Build import-chrome tool",
"type": "shell",
"command": "CC=clang CXX=clang++ make debug -C import-chrome/build/unix -j `nproc`",
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "Build update tool",
"type": "shell",
"command": "CC=clang CXX=clang++ make debug -C update/build/unix -j `nproc`",
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"close": true
}
},
{
"label": "Build client library",
"type": "shell",
"command": "CC=clang CXX=clang++ make debug -C library/unix -j `nproc`",
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"close": true
}
},
{
"label": "Build test application",
"type": "shell",
"command": "CC=clang CXX=clang++ make OPTFLAGS=-DTRACY_VERBOSE\\ -fno-omit-frame-pointer\\ -march=native\\ -g -C test -j `nproc`",
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"close": true
}
}
]
}

20
AUTHORS Normal file
View File

@ -0,0 +1,20 @@
Bartosz Taudul <wolf@nereid.pl>
Kamil Klimek <kamil.klimek@sharkbits.com> (initial find zone implementation)
Bartosz Szreder <zgredder@gmail.com> (view/worker split)
Arvid Gerstmann <dev@arvid-g.de> (compatibility fixes)
Rokas Kupstys <rokups@zoho.com> (compatibility fixes, initial CI work, MingW support)
Till Rathmann <till.rathmann@gmx.de> (DLL support)
Sherief Farouk <sherief.personal@gmail.com> (compatibility fixes)
Dedmen Miller <dedmen@dedmen.de> (find zone bug fixes, improvements)
Michał Cichoń <michcic@gmail.com> (OSX call stack decoding backport)
Thales Sabino <thales@codeplay.com> (OpenCL support)
Andrew Depke <andrewdepke@gmail.com> (Direct3D 12 support)
Simonas Kazlauskas <git@kazlauskas.me> (OSX CI, external bindings)
Jakub Žádník <kubouch@gmail.com> (csvexport utility)
Andrey Voroshilov <andrew.voroshilov@gmail.com> (multi-DLL fixes)
Benoit Jacob <benoitjacob@google.com> (Android improvements)
David Farrel <dafarrel@adobe.com> (Direct3D 11 support)
Terence Rokop <rokopt@sharpears.net> (Non-reentrant zones)
Lukas Berbuer <lukas.berbuer@gmail.com> (CMake integration)
Xavier Bouchoux <xavierb@gmail.com> (sample data in find zone)
Balazs Kovacsics <kovab93@gmail.com> (Universal Windows Platform)

View File

@ -1,54 +1,13 @@
cmake_minimum_required(VERSION 3.10)
# Run version helper script
include(cmake/version.cmake)
project(Tracy LANGUAGES CXX VERSION ${TRACY_VERSION_STRING})
file(GENERATE OUTPUT .gitignore CONTENT "*")
if(${BUILD_SHARED_LIBS})
set(DEFAULT_STATIC OFF)
else()
set(DEFAULT_STATIC ON)
endif()
option(TRACY_STATIC "Whether to build Tracy as a static library" ${DEFAULT_STATIC})
option(TRACY_Fortran "Build Fortran bindings" OFF)
option(TRACY_LTO "Enable Link-Time optimization" OFF)
if(TRACY_Fortran)
enable_language(Fortran)
set(CMAKE_Fortran_VERSION 2003)
endif()
if(TRACY_LTO OR CMAKE_INTERPROCEDURAL_OPTIMIZATION)
include(CheckIPOSupported)
check_ipo_supported(RESULT LTO_SUPPORTED)
if(NOT LTO_SUPPORTED)
message(WARNING "LTO is not supported!")
endif()
else()
set(LTO_SUPPORTED OFF)
endif()
project(Tracy LANGUAGES CXX)
find_package(Threads REQUIRED)
set(TRACY_PUBLIC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/public)
if(LTO_SUPPORTED)
set(TRACY_VISIBILITY "OBJECT")
elseif(TRACY_STATIC)
set(TRACY_VISIBILITY "STATIC")
else()
set(TRACY_VISIBILITY "SHARED")
endif()
add_library(TracyClient ${TRACY_VISIBILITY} "${TRACY_PUBLIC_DIR}/TracyClient.cpp")
add_library(TracyClient TracyClient.cpp)
target_compile_features(TracyClient PUBLIC cxx_std_11)
set_target_properties(TracyClient PROPERTIES INTERPROCEDURAL_OPTIMIZATION ${LTO_SUPPORTED})
target_include_directories(TracyClient SYSTEM PUBLIC
$<BUILD_INTERFACE:${TRACY_PUBLIC_DIR}>
target_include_directories(TracyClient SYSTEM PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>)
target_link_libraries(
TracyClient
@ -57,22 +16,8 @@ target_link_libraries(
${CMAKE_DL_LIBS}
)
if(TRACY_Fortran)
add_library(TracyClientF90 ${TRACY_VISIBILITY} "${TRACY_PUBLIC_DIR}/TracyClient.F90")
target_include_directories(TracyClientF90 PUBLIC
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>
$<INSTALL_INTERFACE:include>)
target_link_libraries(
TracyClientF90
PUBLIC
TracyClient
)
set_target_properties(TracyClientF90 PROPERTIES Fortran_MODULE_DIRECTORY ${PROJECT_BINARY_DIR}
INTERPROCEDURAL_OPTIMIZATION ${LTO_SUPPORTED})
endif()
# Public dependency on some libraries required when using Mingw
if(WIN32 AND ${CMAKE_CXX_COMPILER_ID} MATCHES "GNU|Clang")
if(WIN32 AND ${CMAKE_CXX_COMPILER_ID} MATCHES "GNU")
target_link_libraries(TracyClient PUBLIC ws2_32 dbghelp)
endif()
@ -81,24 +26,7 @@ if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
target_link_libraries(TracyClient PUBLIC ${EXECINFO_LIBRARY})
endif()
if(TRACY_LIBUNWIND_BACKTRACE)
include(FindPkgConfig)
pkg_check_modules(unwind REQUIRED libunwind)
target_include_directories(TracyClient INTERFACE ${unwind_INCLUDE_DIRS})
target_link_libraries(TracyClient INTERFACE ${unwind_LINK_LIBRARIES})
endif()
if(TRACY_DEBUGINFOD)
include(FindPkgConfig)
pkg_check_modules(debuginfod REQUIRED libdebuginfod)
target_include_directories(TracyClient INTERFACE ${debuginfod_INCLUDE_DIRS})
target_link_libraries(TracyClient INTERFACE ${debuginfod_LINK_LIBRARIES})
endif()
add_library(Tracy::TracyClient ALIAS TracyClient)
if(TRACY_Fortran)
add_library(Tracy::TracyClient_Fortran ALIAS TracyClientF90)
endif()
macro(set_option option help value)
option(${option} ${help} ${value})
@ -112,7 +40,7 @@ endmacro()
set_option(TRACY_ENABLE "Enable profiling" ON)
set_option(TRACY_ON_DEMAND "On-demand profiling" OFF)
set_option(TRACY_CALLSTACK "Enforce callstack collection for tracy regions" OFF)
set_option(TRACY_CALLSTACK "Enfore callstack collection for tracy regions" OFF)
set_option(TRACY_NO_CALLSTACK "Disable all callstack related functionality" OFF)
set_option(TRACY_NO_CALLSTACK_INLINES "Disables the inline functions in callstacks" OFF)
set_option(TRACY_ONLY_LOCALHOST "Only listen on the localhost interface" OFF)
@ -126,29 +54,13 @@ set_option(TRACY_NO_VERIFY "Disable zone validation for C API" OFF)
set_option(TRACY_NO_VSYNC_CAPTURE "Disable capture of hardware Vsync events" OFF)
set_option(TRACY_NO_FRAME_IMAGE "Disable the frame image support and its thread" OFF)
set_option(TRACY_NO_SYSTEM_TRACING "Disable systrace sampling" OFF)
set_option(TRACY_PATCHABLE_NOPSLEDS "Enable nopsleds for efficient patching by system-level tools (e.g. rr)" OFF)
set_option(TRACY_DELAYED_INIT "Enable delayed initialization of the library (init on first call)" OFF)
set_option(TRACY_MANUAL_LIFETIME "Enable the manual lifetime management of the profile" OFF)
set_option(TRACY_FIBERS "Enable fibers support" OFF)
set_option(TRACY_NO_CRASH_HANDLER "Disable crash handling" OFF)
set_option(TRACY_TIMER_FALLBACK "Use lower resolution timers" OFF)
set_option(TRACY_LIBUNWIND_BACKTRACE "Use libunwind backtracing where supported" OFF)
set_option(TRACY_SYMBOL_OFFLINE_RESOLVE "Instead of full runtime symbol resolution, only resolve the image path and offset to enable offline symbol resolution" OFF)
set_option(TRACY_LIBBACKTRACE_ELF_DYNLOAD_SUPPORT "Enable libbacktrace to support dynamically loaded elfs in symbol resolution resolution after the first symbol resolve operation" OFF)
set_option(TRACY_DEBUGINFOD "Enable debuginfod support" OFF)
# advanced
set_option(TRACY_VERBOSE "[advanced] Verbose output from the profiler" OFF)
mark_as_advanced(TRACY_VERBOSE)
set_option(TRACY_DEMANGLE "[advanced] Don't use default demangling function - You'll need to provide your own" OFF)
mark_as_advanced(TRACY_DEMANGLE)
# handle incompatible combinations
if(TRACY_MANUAL_LIFETIME AND NOT TRACY_DELAYED_INIT)
message(FATAL_ERROR "TRACY_MANUAL_LIFETIME can not be activated with disabled TRACY_DELAYED_INIT")
endif()
if(NOT TRACY_STATIC)
if(BUILD_SHARED_LIBS)
target_compile_definitions(TracyClient PRIVATE TRACY_EXPORTS)
target_compile_definitions(TracyClient PUBLIC TRACY_IMPORTS)
endif()
@ -156,116 +68,65 @@ endif()
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)
set_target_properties(TracyClient PROPERTIES VERSION ${PROJECT_VERSION})
if(TRACY_Fortran)
set_target_properties(TracyClientF90 PROPERTIES VERSION ${PROJECT_VERSION})
endif()
set(tracy_includes
${TRACY_PUBLIC_DIR}/tracy/TracyC.h
${TRACY_PUBLIC_DIR}/tracy/Tracy.hpp
${TRACY_PUBLIC_DIR}/tracy/TracyD3D11.hpp
${TRACY_PUBLIC_DIR}/tracy/TracyD3D12.hpp
${TRACY_PUBLIC_DIR}/tracy/TracyLua.hpp
${TRACY_PUBLIC_DIR}/tracy/TracyOpenCL.hpp
${TRACY_PUBLIC_DIR}/tracy/TracyOpenGL.hpp
${TRACY_PUBLIC_DIR}/tracy/TracyVulkan.hpp)
set(includes
${CMAKE_CURRENT_LIST_DIR}/TracyC.h
${CMAKE_CURRENT_LIST_DIR}/Tracy.hpp
${CMAKE_CURRENT_LIST_DIR}/TracyD3D11.hpp
${CMAKE_CURRENT_LIST_DIR}/TracyD3D12.hpp
${CMAKE_CURRENT_LIST_DIR}/TracyLua.hpp
${CMAKE_CURRENT_LIST_DIR}/TracyOpenCL.hpp
${CMAKE_CURRENT_LIST_DIR}/TracyOpenGL.hpp
${CMAKE_CURRENT_LIST_DIR}/TracyVulkan.hpp)
set(client_includes
${TRACY_PUBLIC_DIR}/client/tracy_concurrentqueue.h
${TRACY_PUBLIC_DIR}/client/tracy_rpmalloc.hpp
${TRACY_PUBLIC_DIR}/client/tracy_SPSCQueue.h
${TRACY_PUBLIC_DIR}/client/TracyKCore.hpp
${TRACY_PUBLIC_DIR}/client/TracyArmCpuTable.hpp
${TRACY_PUBLIC_DIR}/client/TracyCallstack.h
${TRACY_PUBLIC_DIR}/client/TracyCallstack.hpp
${TRACY_PUBLIC_DIR}/client/TracyCpuid.hpp
${TRACY_PUBLIC_DIR}/client/TracyDebug.hpp
${TRACY_PUBLIC_DIR}/client/TracyDxt1.hpp
${TRACY_PUBLIC_DIR}/client/TracyFastVector.hpp
${TRACY_PUBLIC_DIR}/client/TracyLock.hpp
${TRACY_PUBLIC_DIR}/client/TracyProfiler.hpp
${TRACY_PUBLIC_DIR}/client/TracyRingBuffer.hpp
${TRACY_PUBLIC_DIR}/client/TracyScoped.hpp
${TRACY_PUBLIC_DIR}/client/TracyStringHelpers.hpp
${TRACY_PUBLIC_DIR}/client/TracySysPower.hpp
${TRACY_PUBLIC_DIR}/client/TracySysTime.hpp
${TRACY_PUBLIC_DIR}/client/TracySysTrace.hpp
${TRACY_PUBLIC_DIR}/client/TracyThread.hpp)
${CMAKE_CURRENT_LIST_DIR}/client/tracy_concurrentqueue.h
${CMAKE_CURRENT_LIST_DIR}/client/tracy_rpmalloc.hpp
${CMAKE_CURRENT_LIST_DIR}/client/tracy_SPSCQueue.h
${CMAKE_CURRENT_LIST_DIR}/client/TracyArmCpuTable.hpp
${CMAKE_CURRENT_LIST_DIR}/client/TracyCallstack.h
${CMAKE_CURRENT_LIST_DIR}/client/TracyCallstack.hpp
${CMAKE_CURRENT_LIST_DIR}/client/TracyDebug.hpp
${CMAKE_CURRENT_LIST_DIR}/client/TracyDxt1.hpp
${CMAKE_CURRENT_LIST_DIR}/client/TracyFastVector.hpp
${CMAKE_CURRENT_LIST_DIR}/client/TracyLock.hpp
${CMAKE_CURRENT_LIST_DIR}/client/TracyProfiler.hpp
${CMAKE_CURRENT_LIST_DIR}/client/TracyRingBuffer.hpp
${CMAKE_CURRENT_LIST_DIR}/client/TracyScoped.hpp
${CMAKE_CURRENT_LIST_DIR}/client/TracyStringHelpers.hpp
${CMAKE_CURRENT_LIST_DIR}/client/TracySysTime.hpp
${CMAKE_CURRENT_LIST_DIR}/client/TracySysTrace.hpp
${CMAKE_CURRENT_LIST_DIR}/client/TracyThread.hpp)
set(common_includes
${TRACY_PUBLIC_DIR}/common/tracy_lz4.hpp
${TRACY_PUBLIC_DIR}/common/tracy_lz4hc.hpp
${TRACY_PUBLIC_DIR}/common/TracyAlign.hpp
${TRACY_PUBLIC_DIR}/common/TracyAlloc.hpp
${TRACY_PUBLIC_DIR}/common/TracyApi.h
${TRACY_PUBLIC_DIR}/common/TracyColor.hpp
${TRACY_PUBLIC_DIR}/common/TracyForceInline.hpp
${TRACY_PUBLIC_DIR}/common/TracyMutex.hpp
${TRACY_PUBLIC_DIR}/common/TracyProtocol.hpp
${TRACY_PUBLIC_DIR}/common/TracyQueue.hpp
${TRACY_PUBLIC_DIR}/common/TracySocket.hpp
${TRACY_PUBLIC_DIR}/common/TracyStackFrames.hpp
${TRACY_PUBLIC_DIR}/common/TracySystem.hpp
${TRACY_PUBLIC_DIR}/common/TracyUwp.hpp
${TRACY_PUBLIC_DIR}/common/TracyYield.hpp)
${CMAKE_CURRENT_LIST_DIR}/common/tracy_lz4.hpp
${CMAKE_CURRENT_LIST_DIR}/common/tracy_lz4hc.hpp
${CMAKE_CURRENT_LIST_DIR}/common/TracyAlign.hpp
${CMAKE_CURRENT_LIST_DIR}/common/TracyAlign.hpp
${CMAKE_CURRENT_LIST_DIR}/common/TracyAlloc.hpp
${CMAKE_CURRENT_LIST_DIR}/common/TracyApi.h
${CMAKE_CURRENT_LIST_DIR}/common/TracyColor.hpp
${CMAKE_CURRENT_LIST_DIR}/common/TracyForceInline.hpp
${CMAKE_CURRENT_LIST_DIR}/common/TracyMutex.hpp
${CMAKE_CURRENT_LIST_DIR}/common/TracyProtocol.hpp
${CMAKE_CURRENT_LIST_DIR}/common/TracyQueue.hpp
${CMAKE_CURRENT_LIST_DIR}/common/TracySocket.hpp
${CMAKE_CURRENT_LIST_DIR}/common/TracyStackFrames.hpp
${CMAKE_CURRENT_LIST_DIR}/common/TracySystem.hpp
${CMAKE_CURRENT_LIST_DIR}/common/TracyUwp.hpp
${CMAKE_CURRENT_LIST_DIR}/common/TracyYield.hpp)
install(TARGETS TracyClient
EXPORT TracyConfig
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT lib)
if(TRACY_Fortran)
install(TARGETS TracyClientF90
EXPORT TracyConfig
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT lib)
endif()
# Export targets to build tree root
export(TARGETS TracyClient
NAMESPACE Tracy::
FILE ${CMAKE_BINARY_DIR}/TracyTargets.cmake)
if(TRACY_Fortran)
export(TARGETS TracyClientF90
NAMESPACE Tracy::
APPEND
FILE ${CMAKE_BINARY_DIR}/TracyTargets.cmake)
endif()
install(FILES ${tracy_includes}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/tracy/tracy)
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES ${includes}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(FILES ${client_includes}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/tracy/client)
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/client)
install(FILES ${common_includes}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/tracy/common)
if(TRACY_Fortran)
if(${CMAKE_Fortran_COMPILER_ID} MATCHES "Cray")
install(FILES ${PROJECT_BINARY_DIR}/TRACY.mod
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/tracy)
else()
install(FILES ${PROJECT_BINARY_DIR}/tracy.mod
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/tracy)
endif()
endif()
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/common)
install(EXPORT TracyConfig
NAMESPACE Tracy::
FILE TracyTargets.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
include(CMakePackageConfigHelpers)
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/TracyConfig.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/TracyConfig.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
option(TRACY_CLIENT_PYTHON "Whether to build Tracy python client library" OFF)
if(TRACY_CLIENT_PYTHON)
if(TRACY_STATIC)
message(FATAL_ERROR "Python-bindings require a shared client library")
endif()
add_subdirectory(python)
endif()
FILE TracyConfig.cmake
DESTINATION share/Tracy)

View File

@ -1,6 +0,0 @@
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
find_dependency(Threads REQUIRED)
include("${CMAKE_CURRENT_LIST_DIR}/TracyTargets.cmake")

View File

@ -1,7 +1,7 @@
Tracy Profiler (https://github.com/wolfpld/tracy) is licensed under the
3-clause BSD license.
Copyright (c) 2017-2025, Bartosz Taudul <wolf@nereid.pl>
Copyright (c) 2017-2022, Bartosz Taudul <wolf@nereid.pl>
All rights reserved.
Redistribution and use in source and binary forms, with or without

401
NEWS
View File

@ -2,407 +2,6 @@ Note: There is no guarantee that version mismatched client and server will
be able to talk with each other. Network protocol breakages won't be listed
here.
vx.xx.x (xxxx-xx-xx)
--------------------
- Enabled workaround for MSVC runtime library SNAFU, which manifested with
the profiler executables crashing at startup inside mutex code.
- CPU topology data now includes CPU die information.
- Clients running under Wine will now report that in the trace info.
- Added flame graph.
- The Git ref information for the build is now included in the about dialog.
- Added support for clipboard copy and paste on Wayland.
- The welcome dialog client address entry field will now trim the entered
address, so that stray spaces at the start and the end are removed. This
should reduce the amount of user precision required when copy pasting the
address from somewhere else.
- Metal GPU profiling is now available.
- Profiling zones can now optionally inherit their parent color.
- It is no longer needed to have up-to-date copy of wayland-protocols
installed. CMake will download the required version from GitHub.
- Added option to show the top inline in symbol statistics list in stead of
the symbol name.
- Parallel sorting is now performed with PPQSort (which removes potential
dependency on TBB).
- Added CMake option TRACY_DEBUGINFOD to enable use of libdebuginfod to
retrieve symbols on Linux clients.
- Added a "custom" label as an option to select for GPU context type.
- Symbol code retrieval is now protected against reading no longer available
memory.
- Clicking on a symbol in the symbol statistics list will now open a popup
with two options. This change intends to make the useful but quite hidden
disassembly view more discoverable.
- "View symbol" shows the symbol code disassembly. It was previously
available by right-click on the source file name.
- "Sample entry stacks" shows the list window that was previously
opened when the symbol entry was clicked.
- Plots are now extended to the end of the trace, instead of ending at the
last data point.
- Added TracyMemoryDiscard macros to mark that all allocations made in a
certain memory pool were freed. This enables better support for arena
allocators.
- It is now possible to fine-tune horizontal and vertical mouse wheel scroll
sensitivity.
- Added p75 and p90 percentiles in the Find zone window.
- Zone info window will now display (approximate) wall-clock time of when
the zone appeared, in addition to the previously displayed time from the
start of the program.
- Zone values passed via ZoneValue macro will be now also displayed in hex.
- The csvexport utility can now export plots.
- Fortran integration is now available.
v0.11.1 (2024-08-22)
--------------------
- Utilities import-chrome and import-fuchsia now live together in the import
directory.
- Added TRACY_VERBOSE to available CMake options.
- It is now possible to set TRACY_SAMPLING_HZ via a environment variable.
- Thread group hints can be now used to group threads together in the
profiler UI.
- Limit Lua file names to 255 characters, as the source string can contain
the whole script, if loaded with loadstring().
v0.11.0 (2024-07-16)
--------------------
- Support for pre-0.9 traces has been dropped.
- The old server-side build system has been replaced by CMake. The client
integration is not affected. Refer to the manual for details.
- Most importantly, a known version of the capstone library is now
downloaded from GitHub. You will need to have git installed for this
to work (there is a CMake option to use the capstone installed on the
system, as was done previously).
- Various Meson fixes.
- Proper way of loading Vulkan calibrated timestamps extension.
- Fixed C API support for GPU tracing when on demand mode is enabled.
- Added a way to resynchronize CPU and GPU timestamps.
- Using calibrated contexts should always be preferred.
- Each synchronization event requires a sync of CPU and GPU, which is
something you always want to avoid.
- This is not exposed as an easy-to-use API available through the GPU
wrappers.
- Added TracyIsStarted macro to check if the profiler has been started.
Using this functionality only makes sense in the manual lifetime mode,
and will always return true in any other mode of operation.
- Added basic QNX support.
- Zmmword is now recognized as an assemble size directive.
- Libunwind can be used for call stack capture on Linux if you build with
the TRACY_LIBUNWIND_BACKTRACE define.
- Preloading symbols for all modules on Windows, which is always performed
on program init, and which can be quite slow, may now be omitted through
the TRACY_NO_DBGHELP_INIT_LOAD define. In this mode, symbols will be
loaded as needed.
- Validation of discontinuous frames has been disabled in on-demand mode.
It's quite likely to connect in the middle of a discontinuous frame,
which resulted in frame end event for a frame that hasn't been started.
- Symbols can be now resolved offline on Windows and Linux.
- Enabled with the TRACY_SYMBOL_OFFLINE_RESOLVE define or env variable.
- The update utility has two additional options:
- -r, which enables resolving symbol and patching stack frames in the
trace.
- -p, which you can use to modify the paths used for symbol resolution.
- Some functionality will be missing if this mode is used. For example,
symbol statistics are unavailable.
- Resolving symbol names on Linux will now use image cache to reduce the
number of dladdr() calls.
- Compiling with the TRACY_LIBBACKTRACE_ELF_DYNLOAD_SUPPORT define will
enable support for run-time updating of known elf ranges in libbacktrace
on Linux. Previously, shared objects dlopened() after libbacktrace init
would not be visible during symbol resolution.
- Zone group count in the Find zone window is now explicitly displayed.
- Instrumentation statistics now display in how many threads each source
location has appeared in.
- Added import tool for fuchsia traces.
- https://fuchsia.dev/fuchsia-src/reference/tracing/trace-format
- Added checks for overflow of source locations.
- As a reminder, Tracy only allows to have 64K unique source locations,
split in half between static and dynamic locations.
- Runtime checks are active during capture and will stop a trace that
goes beyond the limit.
- Load-time checks will stop any broken trace file from loading.
- Opening the source code view that has no associated address in code
(i.e., from the list of instrumented zones, or from the find zone
window) will now search the list of symbols for a function name match.
- In many cases this will result in displaying the full disassembly view
where previously you would only see the source code.
- Matching is performed by string comparisons, which in rare cases may
result in showing false data.
- Press ctrl key while opening source view to keep the old behavior.
- If more than one matching symbol is found (e.g., if two classes have
methods with the same name, or if a template is instantiated in multiple
places in code), it is not possible to tell which of the code locations
the source location corresponds to and only the source code will be
displayed.
- Added TracyNoop macro, which inserts a reference to Tracy's object file
into your application. Use it if you want to use Tracy in sampling mode,
without any manual instrumentation (so no references of your own exist)
and link Tracy as a static library. Linkers will only include library code
if code references it, and this doesn't work as intended with Tracy, as it
ignores global constructors that have side effects.
- ZoneText and ZoneName macros now have a printf-like variant, denoted with
a 'F' postfix.
- The 'tracy_shared_libs' Meson option was removed. Use interface provided
by Meson to set the library type instead.
- Dropped the 'tracy_' prefix from Meson options. The `tracy_enable` option
remains as it was, as it can be inherited from parent projects.
- Fixed display of active / inactive allocations in memory call tree.
- Instrumentation statistics can be now sorted by source location.
- Added option to hide external code frames in call stack view.
- There's now a copy to clipboard button in the statistics view. It copies
the visible rows of either the instrumentation or GPU statistics view to
a CSV string matching a subset of the csvexport format.
- Source file contents can be copied to the clipboard.
- Added key binding for immediate reconnect: Ctrl+Shift+Alt+R.
- Lock markup is now available through the C API.
- Symbol statistics window now allows aggregation of inlined functions in
symbols.
- Cost measurements of inlined functions in the symbol statistics window
can be now relative to the base symbol instead of total program run time.
- ScopedZone and AllocSourceLocation now accept color parameter. Impact on
existing code should be minimal.
- AllocSourceLocation has a new parameter with a default value.
- __tracy_alloc_srcloc and __tracy_alloc_srcloc_name break the existing
API. This can be easily fixed by setting the last parameter to zero.
- To build the profiler GUI with Wayland you now need wayland-scanner and
wayland-protocols to be installed. A reasonably recent release of the
protocols is required, which, as always, is not available on Ubuntu.
Seriously, stop trying to build modern software with that broken distro.
- Fractional DPI scaling is now properly supported on Wayland.
- Added Python bindings.
- The per-line sampling statistics are now also displayed as a percentage
of total program run time.
- The out-of-focus render frame rate reduction can be now disabled in
global settings.
- It is now possible to load source files that are newer than the trace.
The default setting is still to reject such files.
- Memory limit for a capture can be now set, both in the GUI profiler and
in the capture utility.
- Thread list can be now sorted alphabetically.
- It is now possible to adjust plot height.
- Trace comparison statistics were expanded and made more clear.
- Implemented retrieval of kernel symbol code on Linux.
- Added support for multiple compression streams in trace files. This
effectively parallelizes both load and save operations.
- The default save setup is now set to Zstd level 3 with 4 compression
streams. This gives both faster compression time and smaller file size.
- New users will be now eased into the profiler with a set of tutorial
achievements.
- You can now set the timeline options default values in global settings.
- Added a check for program memory being available before symbol retrieval
on Windows.
v0.10.0 (2023-10-16)
--------------------
- Missed frames region of on-demand captures will be now ignored when
calculating trace time span, zone percentages, etc.
- Due to technicalities information about locks, frame statistics in trace
information window and csvexport utility still include the missed frames
time.
- When source location dynamic zone coloring mode is enabled, collapsed
zones will be now gray-colored. Previously such regions falled back to
showing thread colors, which may have been confusing to users.
- Vulkan contexts can now use VK_EXT_host_query_reset extension.
- System power usage is now reported on x86 Linux.
- Program name displayed in broadcast messages can be now changed with the
TracySetProgramName() macro.
- Zone error markers (red regions and error bars) have been removed for
consistency with how all other profiling events are displayed.
- It is now possible to export messages in the csvexport utility.
- Major overhaul of how timeline items are processed in GUI.
- The process of figuring out what needs to be drawn on the timeline has
been heavily parallelized.
- The impact is especially visible with traces containing large amounts
of data. The framerate improvement in such cases can be ~30x.
- Consequently, the profiler GUI will now produce multi-core spikes when
rendering frames. This may have impact on the profiled application's
performance, if both the application and the profiler GUI are running
on the same machine. If this is a problem, you may consider the capture
utility instead, which is not affected by these changes. Alternatively,
you may disable parallelization in the options menu.
- Most of the timeline item logic has been written from scratch, which
may have taken care of some elusive bugs.
- Added global configuration settings dialog. You can find it in the
profiler's about menu (the wrench icon in the welcome dialog).
- List of found zones in the Find zone menu can be filtered by user text.
- Fixed div-by-zero in cvsexport utility when there was only one zone of
a kind.
- Fixed compatibility problems with FreeBSD.
- Added support for dynamically loaded Vulkan symbols.
- Trace description or filename is now displayed on the window title bar.
- The csvexport utility will now export thread id data.
- Improved compatibility with MSVC projects not defining NOMINMAX.
- Improved compatibility with Linux setups targeting musl as libc.
- Thread safety of Vulkan instrumentation has been reviewed.
- D3D11 and D3D12 instrumentation was rewritten.
- Added support for efficient profiling when running under rr, the record-
replaying debugger. This is enabled with TRACY_PATCHABLE_NOPSLEDS define.
- History of viewed symbols is now preserved and you can go back to
previously displayed entries.
v0.9.1 (2023-02-26)
-------------------
- Support for pre-0.8 traces has been dropped.
- Profiled programs will ignore dlclose() calls.
- Added warning when the profiler interface is run with privilege elevation.
Advice is given to instead run the client with admin rights.
- Switched to official ZEN4 uarch data.
- Handle cases when thread name is set, but not through Tracy facilities.
- Allow customization of source location data through the following macros:
- TracyFunction - defaults to __FUNCTION__
- TracyFile - defaults to __FILE__
- TracyLine - defaults to __LINE__
- Tracy on Linux now targets and requires Wayland by default.
- Please don't ask about window decorations on Gnome. Current behavior is
the intended behavior. Gnome does not want windows to have decorations,
and Tracy respects this choice. If you find this problematic, use a
desktop environment that actually listens to its users.
- Pass LEGACY=1 parameter to make, if you want to instead rely on the GLFW
library, like before.
- Other platforms still use GLFW.
- Compare traces menu can now display source code differences between two
traces.
- Assembly listings saved to files have been improved.
- Listings are now annotated with source line information.
- To improve compatibility with external tools comments are now prefixed
with '#' instead of ';'.
- Histogram tooltip will now also show left/right counts.
- Tracy now actively manages timeline vertical scroll offset in order to keep
the thread under the mouse cursor in the same place on screen.
- Removed support for AT&T assembly syntax.
- Tracy will not display notification if the file selector can't be used.
Possible reasons for failure include lack of xdg-desktop-portal.
- Using the TRACY_NO_CRASH_HANDLER define will disable handling of
application crashes by the profiler.
- Tracy will now query jump and call target addresses. This enables discovery
of target function names, even if such function has no samples and is not
present in any call stack.
v0.9.0 (2022-10-26)
-------------------
- Attention! All the header and source files used for integrating Tracy with
applications were moved to the public/ directory. This will break your
integration!
- To fix this, update the source and include directories lists to point to
the new location.
- Tracy include files directly referenced by the client were moved to
tracy/ subdirectory, to facilitate setups which previously had Tracy
checkout parent directory in the include paths list (i.e. when you
included "tracy/Tracy.hpp").
- Previously, if you have included the Tracy checkout directory in your
project include directories list (i.e. you could include "Tracy.hpp"),
this could result in third-party library conflicts, e.g. with ImGui.
Such scenarios are no longer the case.
- Tracy macros now require to be terminated with a semicolon.
- The undocumented ___tracy_demangle() function API has been changed. Please
refer to the source code for further instructions.
- The parameter callback and its registration macro have been extended to
include user data pointer. You will need to update your code accordingly.
- Plots visualization has been improved.
- Each plot now has its own color, which can also be defined by the user.
- The area below the plot is now optionally filled with a color.
- Plots can now also be configured to be staircase instead of smooth. This
new setting is appropriate for many inputs where only discrete values
make sense, e.g. the memory allocation plot.
- The API for TracyPlotConfig() macro has been changed. Please refer to
the manual to see how you can fix this.
- Some text labels in the user interface are now more easy to read.
- The profiler will now instruct the user in the UI on what can be done, if
the send queue is slow to process (typically due to symbol resolution).
- If a client with an incompatible protocol is discovered, Tracy will now
try to show which versions can be used to handle the connection.
- Messages list in zone info window can now show messages exclusive to the
zone, filtering out the messages emitted from child zones.
- Added capture of vertical synchronization timings on Linux.
- The range of frame bar colors in the frames overview on top of the screen
can be now controlled with the "Target FPS" entry box in the options menu.
- The "Draw frame targets" option does not need to be selected.
- Previously the hardcoded FPS target thresholds were: 30, 60, 144 FPS.
- Currently the FPS target threshold is: half of target, target, twice the
target.
- Reworked the way zone names are shortened.
- Previously shortening supported only namespace removal, in a way that
didn't consider function parameters or template arguments.
- Shortening to one-letter namespace chains is no longer available.
- The new shortening rules first perform normalization of the function name.
- The function const qualifier is removed.
- Common return types are removed.
- All function parameters and all template arguments are removed.
- The next steps consist of repeated removal of namespaces, starting with
the most outermost one.
- While the old process was all or nothing, the new implementation by
default will dynamically adjust to the space available, trying to show
the most context possible.
- It is also possible to completely disable shortening, or require that it
is always performed in full.
- Function name normalization is enabled by default, even if there is space
to show full function name. This can be changed in options.
- Previously shortening was only applied to the zone names displayed on the
timeline. Currently this process will also apply to all other places in
the UI where function names are displayed. However, in these cases the
function names will only be normalized.
- Full function names are still available as tooltips, or in fine print if
the normalized name is already displayed in a tooltip.
- This functionality is disabled if zone name shortening is disabled.
- Added context menu for timeline labels. Currently the only option is to hide
the selected thread, plot, etc.
- You can now provide custom source file contents through a profiler callback.
- Exposed Tracy version to client applications (available through the
common/TracyVersion.hpp header file).
- D3D12 instrumentation is now thread-safe.
- Timeline can be now navigated with WASD keys.
- Symbol file paths are now normalized on libbacktrace systems. For example,
instead of "/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../
include/c++/12.2.0/bits/std_mutex.h" Tracy will now report such file as
"/usr/include/c++/12.2.0/bits/std_mutex.h".
- The import-chrome utility interprets Instant (`i`/`I`) events where the
`name` field contains the word `frame` as a frame event. The `name` is the
frame set name.
- Frame data won't be displayed if there was no frame instrumentation in the
profiling session.
- Note that some automated functionality (e.g. vertical synchronization
capture) may automatically generate frame data, which will force frames to
be displayed.
- Tracy threads will now be collapsed by default on the timeline.
- Clicking on a local thread in the CPU data view will make the thread visible
and uncollapsed on the timeline.
- Assembly view is now in color.
- The profiler UI will no longer unnecessarily redraw the screen if nothing
was changed. This should have a profound impact on power usage.
- Added microarchitecture data for Zen 4.
- Implemented optional propagation of inline cost down the local call stack.
- This feature may be useful when trying to get a general outlook of the
cost at the top-level function in the symbol.
- It is possible to get nonsense data when this is enabled, for example
total cost exceeding 100%. This is by design.
- Assembly line costs are not affected.
- Available clients now also broadcast their PID.
- Reversed mouse button assignments for jumping to source / assembly line in
symbol view. The left mouse button will now focus the target line.
- Assembly lines tooltip will now display local call stack of inline functions
(within the symbol).
- Right-clicking the source location entry in assembly line will show the
local call stack, along with source code preview of each entry and ability
to navigate to any selected inline function.
- The profiler UI will now indicate that it needs attention if the window is
not focused and something interesting happens. For example when a connection
is established, or when a saved trace finishes loading, etc. How the
attention request is indicated depends on the operating system.
- Clicking on the red microarchitecture icon in the symbol view assembly pane
will switch the selected microarchitecture to one the profiled application
was running on.
- Removed option to display instruction latencies in a graphical form. Latency
data is still available in instruction tooltip.
v0.8.2 (2022-06-28)
-------------------

View File

@ -4,12 +4,11 @@
### A real time, nanosecond resolution, remote telemetry, hybrid frame and sampling profiler for games and other applications.
Tracy supports profiling CPU (Direct support is provided for C, C++, Lua, Python and Fortran integration. At the same time, third-party bindings to many other languages exist on the internet, such as [Rust](https://github.com/nagisa/rust_tracy_client), [Zig](https://github.com/tealsnow/zig-tracy), [C#](https://github.com/clibequilibrium/Tracy-CSharp), [OCaml](https://github.com/imandra-ai/ocaml-tracy), [Odin](https://github.com/oskarnp/odin-tracy), etc.), GPU (All major graphic APIs: OpenGL, Vulkan, Direct3D 11/12, Metal, OpenCL.), memory allocations, locks, context switches, automatically attribute screenshots to captured frames, and much more.
Tracy supports profiling CPU (Direct support is provided for C, C++, and Lua integration. At the same time, third-party bindings to many other languages exist on the internet, such as Rust, Zig, OCaml, Odin, etc.), GPU (All major graphic APIs: OpenGL, Vulkan, Direct3D 11/12, OpenCL.), memory allocations, locks, context switches, automatically attribute screenshots to captured frames, and much more.
- [Documentation](https://github.com/wolfpld/tracy/releases/latest/download/tracy.pdf) for usage and build process instructions
- [Releases](https://github.com/wolfpld/tracy/releases) containing the documentation (`tracy.pdf`) and compiled Windows x64 binaries (`Tracy-<version>.7z`) as assets
- [Changelog](NEWS)
- [Interactive demo](https://tracy.nereid.pl/)
![](doc/profiler.png)
@ -17,8 +16,6 @@ Tracy supports profiling CPU (Direct support is provided for C, C++, Lua, Python
![](doc/profiler3.png)
[An Introduction to Tracy Profiler in C++ - Marcos Slomp - CppCon 2023](https://youtu.be/ghXk3Bk5F2U?t=37)
[Introduction to Tracy Profiler v0.2](https://www.youtube.com/watch?v=fB5B46lbapc)
[New features in Tracy Profiler v0.3](https://www.youtube.com/watch?v=3SXpDpDh2Uo)
[New features in Tracy Profiler v0.4](https://www.youtube.com/watch?v=eAkgkaO8B9o)

7
TODO Normal file
View File

@ -0,0 +1,7 @@
"Would be nice to have" list for 1.0 release:
=============================================
* Pack queue items tightly in the queues.
* Use level-of-detail system for plots.
* Use per-thread lock data structures.
* Use DTrace for BSD/OSX context switch capture.

267
Tracy.hpp Normal file
View File

@ -0,0 +1,267 @@
#ifndef __TRACY_HPP__
#define __TRACY_HPP__
#include "common/TracyColor.hpp"
#include "common/TracySystem.hpp"
#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)
#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 TracyParameterRegister(x)
#define TracyParameterSetup(x,y,z,w)
#define TracyIsConnected false
#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,__LINE__) { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), TRACY_CALLSTACK, active );
# define ZoneNamedN( varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), TRACY_CALLSTACK, active );
# define ZoneNamedC( varname, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), TRACY_CALLSTACK, active );
# define ZoneNamedNC( varname, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), TRACY_CALLSTACK, active );
# define ZoneTransient( varname, active ) tracy::ScopedZone varname( __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), nullptr, 0, TRACY_CALLSTACK, active );
# define ZoneTransientN( varname, name, active ) tracy::ScopedZone varname( __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), name, strlen( name ), TRACY_CALLSTACK, active );
#else
# define ZoneNamed( varname, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), active );
# define ZoneNamedN( varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), active );
# define ZoneNamedC( varname, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), active );
# define ZoneNamedNC( varname, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), active );
# define ZoneTransient( varname, active ) tracy::ScopedZone varname( __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), nullptr, 0, active );
# define ZoneTransientN( varname, name, active ) tracy::ScopedZone varname( __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), 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, __FILE__, __LINE__, 0 }; return &srcloc; }() };
#define TracyLockableN( type, varname, desc ) tracy::Lockable<type> varname { [] () -> const tracy::SourceLocationData* { static constexpr tracy::SourceLocationData srcloc { nullptr, desc, __FILE__, __LINE__, 0 }; return &srcloc; }() };
#define TracySharedLockable( type, varname ) tracy::SharedLockable<type> varname { [] () -> const tracy::SourceLocationData* { static constexpr tracy::SourceLocationData srcloc { nullptr, #type " " #varname, __FILE__, __LINE__, 0 }; return &srcloc; }() };
#define TracySharedLockableN( type, varname, desc ) tracy::SharedLockable<type> varname { [] () -> const tracy::SourceLocationData* { static constexpr tracy::SourceLocationData srcloc { nullptr, desc, __FILE__, __LINE__, 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, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 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 ) tracy::Profiler::ConfigurePlot( name, type );
#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,__LINE__) { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), depth, active );
# define ZoneNamedNS( varname, name, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), depth, active );
# define ZoneNamedCS( varname, color, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { nullptr, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), depth, active );
# define ZoneNamedNCS( varname, name, color, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::ScopedZone varname( &TracyConcat(__tracy_source_location,__LINE__), depth, active );
# define ZoneTransientS( varname, depth, active ) tracy::ScopedZone varname( __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), nullptr, 0, depth, active );
# define ZoneTransientNS( varname, name, depth, active ) tracy::ScopedZone varname( __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), 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 ) TracyAlloc( ptr, size, name )
# define TracyFreeNS( ptr, depth, name ) TracyFree( ptr, name )
# define TracySecureAllocNS( ptr, size, depth, name ) TracySecureAlloc( ptr, size, name )
# define TracySecureFreeNS( ptr, depth, name ) TracySecureFree( 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 TracyParameterRegister( cb ) tracy::Profiler::ParameterRegister( cb );
#define TracyParameterSetup( idx, name, isBool, val ) tracy::Profiler::ParameterSetup( idx, name, isBool, val );
#define TracyIsConnected tracy::GetProfiler().IsConnected()
#ifdef TRACY_FIBERS
# define TracyFiberEnter( fiber ) tracy::Profiler::EnterFiber( fiber );
# define TracyFiberLeave tracy::Profiler::LeaveFiber();
#endif
#endif
#endif

320
TracyC.h Normal file
View File

@ -0,0 +1,320 @@
#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
TRACY_API void ___tracy_set_thread_name( const char* name );
#define TracyCSetThreadName( name ) ___tracy_set_thread_name( name );
#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 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
#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_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;
};
// 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);
#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_alloc( const struct ___tracy_gpu_zone_begin_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_zone_begin_alloc_serial( const struct ___tracy_gpu_zone_begin_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 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,__LINE__) = { NULL, __func__, __FILE__, (uint32_t)__LINE__, 0 }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,__LINE__), TRACY_CALLSTACK, active );
# define TracyCZoneN( ctx, name, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,__LINE__) = { name, __func__, __FILE__, (uint32_t)__LINE__, 0 }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,__LINE__), TRACY_CALLSTACK, active );
# define TracyCZoneC( ctx, color, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,__LINE__) = { NULL, __func__, __FILE__, (uint32_t)__LINE__, color }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,__LINE__), TRACY_CALLSTACK, active );
# define TracyCZoneNC( ctx, name, color, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,__LINE__) = { name, __func__, __FILE__, (uint32_t)__LINE__, color }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,__LINE__), TRACY_CALLSTACK, active );
#else
# define TracyCZone( ctx, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,__LINE__) = { NULL, __func__, __FILE__, (uint32_t)__LINE__, 0 }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin( &TracyConcat(__tracy_source_location,__LINE__), active );
# define TracyCZoneN( ctx, name, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,__LINE__) = { name, __func__, __FILE__, (uint32_t)__LINE__, 0 }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin( &TracyConcat(__tracy_source_location,__LINE__), active );
# define TracyCZoneC( ctx, color, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,__LINE__) = { NULL, __func__, __FILE__, (uint32_t)__LINE__, color }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin( &TracyConcat(__tracy_source_location,__LINE__), active );
# define TracyCZoneNC( ctx, name, color, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,__LINE__) = { name, __func__, __FILE__, (uint32_t)__LINE__, color }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin( &TracyConcat(__tracy_source_location,__LINE__), 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_message_appinfo( const char* txt, size_t size );
#define TracyCPlot( name, val ) ___tracy_emit_plot( name, val );
#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,__LINE__) = { NULL, __func__, __FILE__, (uint32_t)__LINE__, 0 }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,__LINE__), depth, active );
# define TracyCZoneNS( ctx, name, depth, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,__LINE__) = { name, __func__, __FILE__, (uint32_t)__LINE__, 0 }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,__LINE__), depth, active );
# define TracyCZoneCS( ctx, color, depth, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,__LINE__) = { NULL, __func__, __FILE__, (uint32_t)__LINE__, color }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,__LINE__), depth, active );
# define TracyCZoneNCS( ctx, name, color, depth, active ) static const struct ___tracy_source_location_data TracyConcat(__tracy_source_location,__LINE__) = { name, __func__, __FILE__, (uint32_t)__LINE__, color }; TracyCZoneCtx ctx = ___tracy_emit_zone_begin_callstack( &TracyConcat(__tracy_source_location,__LINE__), 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()
TRACY_API void ___tracy_fiber_enter( const char* fiber );
TRACY_API void ___tracy_fiber_leave( void );
#ifdef TRACY_FIBERS
# define TracyCFiberEnter( fiber ) ___tracy_fiber_enter( fiber );
# define TracyCFiberLeave ___tracy_fiber_leave();
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -22,32 +22,27 @@
#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"
#include "client/TracyKCore.cpp"
#if defined(TRACY_HAS_CALLSTACK)
# 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"
#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

442
TracyD3D11.hpp Normal file
View File

@ -0,0 +1,442 @@
#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 TracyD3D12ZoneTransient(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 TracyD3D12ZoneTransientS(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/TracyAlign.hpp"
#include "common/TracyAlloc.hpp"
namespace tracy
{
class D3D11Ctx
{
friend class D3D11ZoneScope;
enum { QueryCount = 64 * 1024 };
public:
D3D11Ctx( ID3D11Device* device, ID3D11DeviceContext* devicectx )
: m_device( device )
, m_devicectx( devicectx )
, m_context( GetGpuCtxCounter().fetch_add( 1, std::memory_order_relaxed ) )
, m_head( 0 )
, m_tail( 0 )
{
assert( m_context != 255 );
for (int i = 0; i < QueryCount; i++)
{
HRESULT hr = S_OK;
D3D11_QUERY_DESC desc;
desc.MiscFlags = 0;
desc.Query = D3D11_QUERY_TIMESTAMP;
hr |= device->CreateQuery(&desc, &m_queries[i]);
desc.Query = D3D11_QUERY_TIMESTAMP_DISJOINT;
hr |= device->CreateQuery(&desc, &m_disjoints[i]);
m_disjointMap[i] = nullptr;
assert(SUCCEEDED(hr));
}
// Force query the initial GPU timestamp (pipeline stall)
D3D11_QUERY_DATA_TIMESTAMP_DISJOINT disjoint;
UINT64 timestamp;
for (int attempts = 0; attempts < 50; attempts++)
{
devicectx->Begin(m_disjoints[0]);
devicectx->End(m_queries[0]);
devicectx->End(m_disjoints[0]);
devicectx->Flush();
while (devicectx->GetData(m_disjoints[0], &disjoint, sizeof(disjoint), 0) == S_FALSE)
/* Nothing */;
if (disjoint.Disjoint)
continue;
while (devicectx->GetData(m_queries[0], &timestamp, sizeof(timestamp), 0) == S_FALSE)
/* Nothing */;
break;
}
int64_t tgpu = timestamp * (1000000000ull / disjoint.Frequency);
int64_t tcpu = Profiler::GetTime();
uint8_t flags = 0;
const float period = 1.f;
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::Direct3D11 );
#ifdef TRACY_ON_DEMAND
GetProfiler().DeferItem( *item );
#endif
Profiler::QueueSerialFinish();
}
~D3D11Ctx()
{
for (int i = 0; i < QueryCount; i++)
{
m_queries[i]->Release();
m_disjoints[i]->Release();
m_disjointMap[i] = 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()
{
ZoneScopedC( Color::Red4 );
if( m_tail == m_head ) return;
#ifdef TRACY_ON_DEMAND
if( !GetProfiler().IsConnected() )
{
m_head = m_tail = 0;
return;
}
#endif
auto start = m_tail;
auto end = m_head + QueryCount;
auto cnt = (end - start) % QueryCount;
while (cnt > 1)
{
auto mid = start + cnt / 2;
bool available =
m_devicectx->GetData(m_disjointMap[mid % QueryCount], nullptr, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH) == S_OK &&
m_devicectx->GetData(m_queries[mid % QueryCount], nullptr, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH) == S_OK;
if (available)
{
start = mid;
}
else
{
end = mid;
}
cnt = (end - start) % QueryCount;
}
start %= QueryCount;
while (m_tail != start)
{
D3D11_QUERY_DATA_TIMESTAMP_DISJOINT disjoint;
UINT64 time;
m_devicectx->GetData(m_disjointMap[m_tail], &disjoint, sizeof(disjoint), 0);
m_devicectx->GetData(m_queries[m_tail], &time, sizeof(time), 0);
time *= (1000000000ull / disjoint.Frequency);
auto* item = Profiler::QueueSerial();
MemWrite(&item->hdr.type, QueueType::GpuTime);
MemWrite(&item->gpuTime.gpuTime, (int64_t)time);
MemWrite(&item->gpuTime.queryId, (uint16_t)m_tail);
MemWrite(&item->gpuTime.context, m_context);
Profiler::QueueSerialFinish();
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 ID3D11Query* TranslateQueryId( unsigned int id )
{
return m_queries[id];
}
tracy_force_inline ID3D11Query* MapDisjointQueryId( unsigned int id, unsigned int disjointId )
{
m_disjointMap[id] = m_disjoints[disjointId];
return m_disjoints[disjointId];
}
tracy_force_inline uint8_t GetId() const
{
return m_context;
}
ID3D11Device* m_device;
ID3D11DeviceContext* m_devicectx;
ID3D11Query* m_queries[QueryCount];
ID3D11Query* m_disjoints[QueryCount];
ID3D11Query* m_disjointMap[QueryCount]; // Multiple time queries can have one disjoint query
uint8_t m_context;
unsigned int m_head;
unsigned int m_tail;
};
class D3D11ZoneScope
{
public:
tracy_force_inline D3D11ZoneScope( D3D11Ctx* ctx, 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;
m_ctx = ctx;
const auto queryId = ctx->NextQueryId();
ctx->m_devicectx->Begin(ctx->MapDisjointQueryId(queryId, queryId));
ctx->m_devicectx->End(ctx->TranslateQueryId(queryId));
m_disjointId = 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 D3D11ZoneScope( D3D11Ctx* 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
{
if( !m_active ) return;
m_ctx = ctx;
const auto queryId = ctx->NextQueryId();
ctx->m_devicectx->Begin(ctx->MapDisjointQueryId(queryId, queryId));
ctx->m_devicectx->End(ctx->TranslateQueryId(queryId));
m_disjointId = queryId;
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( queryId ) );
MemWrite( &item->gpuZoneBegin.context, ctx->GetId() );
Profiler::QueueSerialFinish();
GetProfiler().SendCallstack( depth );
}
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)
#ifdef TRACY_ON_DEMAND
: m_active(active&& GetProfiler().IsConnected())
#else
: m_active(active)
#endif
{
if( !m_active ) return;
m_ctx = ctx;
const auto queryId = ctx->NextQueryId();
ctx->m_devicectx->Begin(ctx->MapDisjointQueryId(queryId, queryId));
ctx->m_devicectx->End(ctx->TranslateQueryId(queryId));
m_disjointId = queryId;
const auto sourceLocation = 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, sourceLocation);
MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle());
MemWrite(&item->gpuZoneBegin.queryId, static_cast<uint16_t>(queryId));
MemWrite(&item->gpuZoneBegin.context, ctx->GetId());
Profiler::QueueSerialFinish();
}
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)
#ifdef TRACY_ON_DEMAND
: m_active(active&& GetProfiler().IsConnected())
#else
: m_active(active)
#endif
{
if( !m_active ) return;
m_ctx = ctx;
const auto queryId = ctx->NextQueryId();
ctx->m_devicectx->Begin(ctx->MapDisjointQueryId(queryId, queryId));
ctx->m_devicectx->End(ctx->TranslateQueryId(queryId));
m_disjointId = queryId;
const auto sourceLocation = 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, sourceLocation);
MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle());
MemWrite(&item->gpuZoneBegin.queryId, static_cast<uint16_t>(queryId));
MemWrite(&item->gpuZoneBegin.context, ctx->GetId());
Profiler::QueueSerialFinish();
}
tracy_force_inline ~D3D11ZoneScope()
{
if( !m_active ) return;
const auto queryId = m_ctx->NextQueryId();
m_ctx->m_devicectx->End(m_ctx->TranslateQueryId(queryId));
m_ctx->m_devicectx->End(m_ctx->MapDisjointQueryId(queryId, m_disjointId));
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;
D3D11Ctx* m_ctx;
unsigned int m_disjointId;
};
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 );
}
}
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);
#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK
# define TracyD3D11Zone( ctx, name ) TracyD3D11NamedZoneS( ctx, ___tracy_gpu_zone, name, TRACY_CALLSTACK, true )
# define TracyD3D11ZoneC( ctx, name, color ) TracyD3D11NamedZoneCS( ctx, ___tracy_gpu_zone, name, color, TRACY_CALLSTACK, true )
# define TracyD3D11NamedZone( ctx, varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::D3D11ZoneScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), TRACY_CALLSTACK, active );
# define TracyD3D11NamedZoneC( ctx, varname, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::D3D11ZoneScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), TRACY_CALLSTACK, active );
# define TracyD3D11ZoneTransient(ctx, varname, name, active) TracyD3D11ZoneTransientS(ctx, varname, cmdList, name, TRACY_CALLSTACK, active)
#else
# define TracyD3D11Zone( ctx, name ) TracyD3D11NamedZone( ctx, ___tracy_gpu_zone, name, true )
# define TracyD3D11ZoneC( ctx, name, color ) TracyD3D11NamedZoneC( ctx, ___tracy_gpu_zone, name, color, true )
# define TracyD3D11NamedZone( ctx, varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::D3D11ZoneScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), active );
# define TracyD3D11NamedZoneC( ctx, varname, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::D3D11ZoneScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), active );
# define TracyD3D11ZoneTransient(ctx, varname, name, active) tracy::D3D11ZoneScope varname{ ctx, __LINE__, __FILE__, strlen(__FILE__), __FUNCTION__, strlen(__FUNCTION__), name, strlen(name), active };
#endif
#ifdef TRACY_HAS_CALLSTACK
# define TracyD3D11ZoneS( ctx, name, depth ) TracyD3D11NamedZoneS( ctx, ___tracy_gpu_zone, name, depth, true )
# define TracyD3D11ZoneCS( ctx, name, color, depth ) TracyD3D11NamedZoneCS( ctx, ___tracy_gpu_zone, name, color, depth, true )
# define TracyD3D11NamedZoneS( ctx, varname, name, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::D3D11ZoneScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), depth, active );
# define TracyD3D11NamedZoneCS( ctx, varname, name, color, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::D3D11ZoneScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), depth, active );
# define TracyD3D11ZoneTransientS(ctx, varname, name, depth, active) tracy::D3D11ZoneScope varname{ ctx, __LINE__, __FILE__, strlen(__FILE__), __FUNCTION__, strlen(__FUNCTION__), 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) TracyD3D12ZoneTransient(ctx, varname, name, active)
#endif
#define TracyD3D11Collect( ctx ) ctx->Collect();
#endif
#endif

506
TracyD3D12.hpp Normal file
View File

@ -0,0 +1,506 @@
#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 <wrl/client.h>
#include <queue>
namespace tracy
{
struct D3D12QueryPayload
{
uint32_t m_queryIdStart = 0;
uint32_t m_queryCount = 0;
};
// Command queue context.
class D3D12QueueCtx
{
friend class D3D12ZoneScope;
static constexpr uint32_t MaxQueries = 64 * 1024; // Queries are begin and end markers, so we can store half as many total time durations. Must be even!
bool m_initialized = false;
ID3D12Device* m_device = nullptr;
ID3D12CommandQueue* m_queue = nullptr;
uint8_t m_context;
Microsoft::WRL::ComPtr<ID3D12QueryHeap> m_queryHeap;
Microsoft::WRL::ComPtr<ID3D12Resource> m_readbackBuffer;
// In-progress payload.
uint32_t m_queryLimit = MaxQueries;
uint32_t m_queryCounter = 0;
uint32_t m_previousQueryCounter = 0;
uint32_t m_activePayload = 0;
Microsoft::WRL::ComPtr<ID3D12Fence> m_payloadFence;
std::queue<D3D12QueryPayload> m_payloadQueue;
int64_t m_prevCalibration = 0;
int64_t m_qpcToNs = int64_t{ 1000000000 / GetFrequencyQpc() };
public:
D3D12QueueCtx(ID3D12Device* device, ID3D12CommandQueue* queue)
: m_device(device)
, m_queue(queue)
, m_context(GetGpuCtxCounter().fetch_add(1, std::memory_order_relaxed))
{
// Verify we support timestamp queries on this queue.
if (queue->GetDesc().Type == D3D12_COMMAND_LIST_TYPE_COPY)
{
D3D12_FEATURE_DATA_D3D12_OPTIONS3 featureData{};
bool Success = SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS3, &featureData, sizeof(featureData)));
assert(Success && featureData.CopyQueueTimestampQueriesSupported && "Platform does not support profiling of copy queues.");
}
uint64_t timestampFrequency;
if (FAILED(queue->GetTimestampFrequency(&timestampFrequency)))
{
assert(false && "Failed to get timestamp frequency.");
}
uint64_t cpuTimestamp;
uint64_t gpuTimestamp;
if (FAILED(queue->GetClockCalibration(&gpuTimestamp, &cpuTimestamp)))
{
assert(false && "Failed to get queue clock calibration.");
}
// Save the device cpu timestamp, not the profiler's timestamp.
m_prevCalibration = cpuTimestamp * m_qpcToNs;
cpuTimestamp = Profiler::GetTime();
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))))
{
assert(false && "Failed to create query readback buffer.");
}
if (FAILED(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_payloadFence))))
{
assert(false && "Failed to create payload fence.");
}
auto* item = Profiler::QueueSerial();
MemWrite(&item->hdr.type, QueueType::GpuNewContext);
MemWrite(&item->gpuNewContext.cpuTime, cpuTimestamp);
MemWrite(&item->gpuNewContext.gpuTime, gpuTimestamp);
memset(&item->gpuNewContext.thread, 0, sizeof(item->gpuNewContext.thread));
MemWrite(&item->gpuNewContext.period, 1E+09f / static_cast<float>(timestampFrequency));
MemWrite(&item->gpuNewContext.context, m_context);
MemWrite(&item->gpuNewContext.flags, GpuContextCalibration);
MemWrite(&item->gpuNewContext.type, GpuContextType::Direct3D12);
#ifdef TRACY_ON_DEMAND
GetProfiler().DeferItem(*item);
#endif
Profiler::QueueSerialFinish();
m_initialized = true;
}
void NewFrame()
{
m_payloadQueue.emplace(D3D12QueryPayload{ m_previousQueryCounter, m_queryCounter });
m_previousQueryCounter += m_queryCounter;
m_queryCounter = 0;
if (m_previousQueryCounter >= m_queryLimit)
{
m_previousQueryCounter -= m_queryLimit;
}
m_queue->Signal(m_payloadFence.Get(), ++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, 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()
{
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)))
{
assert(false && "Failed to map readback buffer.");
}
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, m_context);
Profiler::QueueSerialFinish();
}
m_payloadQueue.pop();
}
m_readbackBuffer->Unmap(0, nullptr);
// Recalibrate to account for drift.
uint64_t cpuTimestamp;
uint64_t gpuTimestamp;
if (FAILED(m_queue->GetClockCalibration(&gpuTimestamp, &cpuTimestamp)))
{
assert(false && "Failed to get queue clock calibration.");
}
cpuTimestamp *= m_qpcToNs;
const auto cpuDelta = cpuTimestamp - m_prevCalibration;
if (cpuDelta > 0)
{
m_prevCalibration = 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, cpuDelta);
MemWrite(&item->gpuCalibration.context, m_context);
Profiler::QueueSerialFinish();
}
}
private:
tracy_force_inline uint32_t NextQueryId()
{
assert(m_queryCounter < m_queryLimit && "Submitted too many GPU queries! Consider increasing MaxQueries.");
const uint32_t id = (m_previousQueryCounter + m_queryCounter) % m_queryLimit;
m_queryCounter += 2; // Allocate space for a begin and end query.
return id;
}
tracy_force_inline uint8_t GetId() const
{
return m_context;
}
};
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.
public:
tracy_force_inline D3D12ZoneScope(D3D12QueueCtx* ctx, ID3D12GraphicsCommandList* cmdList, const SourceLocationData* srcLocation, 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 = ctx->NextQueryId();
cmdList->EndQuery(ctx->m_queryHeap.Get(), D3D12_QUERY_TYPE_TIMESTAMP, m_queryId);
auto* item = Profiler::QueueSerial();
MemWrite(&item->hdr.type, QueueType::GpuZoneBeginSerial);
MemWrite(&item->gpuZoneBegin.cpuTime, Profiler::GetTime());
MemWrite(&item->gpuZoneBegin.srcloc, reinterpret_cast<uint64_t>(srcLocation));
MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle());
MemWrite(&item->gpuZoneBegin.queryId, static_cast<uint16_t>(m_queryId));
MemWrite(&item->gpuZoneBegin.context, ctx->GetId());
Profiler::QueueSerialFinish();
}
tracy_force_inline D3D12ZoneScope(D3D12QueueCtx* ctx, ID3D12GraphicsCommandList* cmdList, const SourceLocationData* srcLocation, int depth, 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 = ctx->NextQueryId();
cmdList->EndQuery(ctx->m_queryHeap.Get(), D3D12_QUERY_TYPE_TIMESTAMP, m_queryId);
auto* item = Profiler::QueueSerialCallstack(Callstack(depth));
MemWrite(&item->hdr.type, QueueType::GpuZoneBeginCallstackSerial);
MemWrite(&item->gpuZoneBegin.cpuTime, Profiler::GetTime());
MemWrite(&item->gpuZoneBegin.srcloc, reinterpret_cast<uint64_t>(srcLocation));
MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle());
MemWrite(&item->gpuZoneBegin.queryId, static_cast<uint16_t>(m_queryId));
MemWrite(&item->gpuZoneBegin.context, ctx->GetId());
Profiler::QueueSerialFinish();
}
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)
#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 = ctx->NextQueryId();
cmdList->EndQuery(ctx->m_queryHeap.Get(), D3D12_QUERY_TYPE_TIMESTAMP, m_queryId);
const auto sourceLocation = 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, sourceLocation);
MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle());
MemWrite(&item->gpuZoneBegin.queryId, static_cast<uint16_t>(m_queryId));
MemWrite(&item->gpuZoneBegin.context, ctx->GetId());
Profiler::QueueSerialFinish();
}
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)
#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 = ctx->NextQueryId();
cmdList->EndQuery(ctx->m_queryHeap.Get(), D3D12_QUERY_TYPE_TIMESTAMP, m_queryId);
const auto sourceLocation = 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, sourceLocation);
MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle());
MemWrite(&item->gpuZoneBegin.queryId, static_cast<uint16_t>(m_queryId));
MemWrite(&item->gpuZoneBegin.context, ctx->GetId());
Profiler::QueueSerialFinish();
}
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.Get(), 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.Get(), D3D12_QUERY_TYPE_TIMESTAMP, m_queryId, 2, m_ctx->m_readbackBuffer.Get(), 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);
}
}
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();
#if defined TRACY_HAS_CALLSTACK && defined TRACY_CALLSTACK
# define TracyD3D12Zone(ctx, cmdList, name) TracyD3D12NamedZoneS(ctx, ___tracy_gpu_zone, cmdList, name, TRACY_CALLSTACK, true)
# define TracyD3D12ZoneC(ctx, cmdList, name, color) TracyD3D12NamedZoneCS(ctx, ___tracy_gpu_zone, cmdList, name, color, TRACY_CALLSTACK, true)
# define TracyD3D12NamedZone(ctx, varname, cmdList, name, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location, __LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyConcat(__tracy_gpu_source_location, __LINE__), TRACY_CALLSTACK, active };
# define TracyD3D12NamedZoneC(ctx, varname, cmdList, name, color, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location, __LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyConcat(__tracy_gpu_source_location, __LINE__), 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, ___tracy_gpu_zone, cmdList, name, true)
# define TracyD3D12ZoneC(ctx, cmdList, name, color) TracyD3D12NamedZoneC(ctx, ___tracy_gpu_zone, cmdList, name, color, true)
# define TracyD3D12NamedZone(ctx, varname, cmdList, name, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location, __LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyConcat(__tracy_gpu_source_location, __LINE__), active };
# define TracyD3D12NamedZoneC(ctx, varname, cmdList, name, color, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location, __LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyConcat(__tracy_gpu_source_location, __LINE__), active };
# define TracyD3D12ZoneTransient(ctx, varname, cmdList, name, active) tracy::D3D12ZoneScope varname{ ctx, __LINE__, __FILE__, strlen(__FILE__), __FUNCTION__, strlen(__FUNCTION__), name, strlen(name), cmdList, active };
#endif
#ifdef TRACY_HAS_CALLSTACK
# define TracyD3D12ZoneS(ctx, cmdList, name, depth) TracyD3D12NamedZoneS(ctx, ___tracy_gpu_zone, cmdList, name, depth, true)
# define TracyD3D12ZoneCS(ctx, cmdList, name, color, depth) TracyD3D12NamedZoneCS(ctx, ___tracy_gpu_zone, cmdList, name, color, depth, true)
# define TracyD3D12NamedZoneS(ctx, varname, cmdList, name, depth, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location, __LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyConcat(__tracy_gpu_source_location, __LINE__), depth, active };
# define TracyD3D12NamedZoneCS(ctx, varname, cmdList, name, color, depth, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location, __LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::D3D12ZoneScope varname{ ctx, cmdList, &TracyConcat(__tracy_gpu_source_location, __LINE__), depth, active };
# define TracyD3D12ZoneTransientS(ctx, varname, cmdList, name, depth, active) tracy::D3D12ZoneScope varname{ ctx, __LINE__, __FILE__, strlen(__FILE__), __FUNCTION__, strlen(__FUNCTION__), 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

View File

@ -120,8 +120,6 @@ static inline void LuaRemove( char* script )
}
}
static inline void LuaHook( lua_State* L, lua_Debug* ar ) {}
}
#else
@ -129,11 +127,11 @@ static inline void LuaHook( lua_State* L, lua_Debug* ar ) {}
#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"
#include "common/TracyColor.hpp"
#include "common/TracyAlign.hpp"
#include "common/TracyForceInline.hpp"
#include "common/TracySystem.hpp"
#include "client/TracyProfiler.hpp"
namespace tracy
{
@ -175,10 +173,10 @@ static tracy_force_inline void SendLuaCallstack( lua_State* L, uint32_t depth )
{
const uint32_t line = dbg[i].currentline;
memcpy( dst, &line, 4 ); dst += 4;
assert( fsz[i] <= (std::numeric_limits<uint16_t>::max)() );
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)() );
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];
}
@ -190,13 +188,6 @@ static tracy_force_inline void SendLuaCallstack( lua_State* L, uint32_t depth )
TracyQueueCommit( callstackAllocFatThread );
}
static inline void LuaShortenSrc( char* dst, const char* src )
{
size_t l = std::min( (size_t)255, strlen( src ) );
memcpy( dst, src, l );
dst[l] = 0;
}
static inline int LuaZoneBeginS( lua_State* L )
{
#ifdef TRACY_ON_DEMAND
@ -216,9 +207,7 @@ static inline int LuaZoneBeginS( lua_State* L )
lua_Debug dbg;
lua_getstack( L, 1, &dbg );
lua_getinfo( L, "Snl", &dbg );
char src[256];
LuaShortenSrc( src, dbg.source );
const auto srcloc = Profiler::AllocSourceLocation( dbg.currentline, src, dbg.name ? dbg.name : dbg.short_src );
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() );
@ -248,10 +237,8 @@ static inline int LuaZoneBeginNS( lua_State* L )
lua_getstack( L, 1, &dbg );
lua_getinfo( L, "Snl", &dbg );
size_t nsz;
char src[256];
LuaShortenSrc( src, dbg.source );
const auto name = lua_tolstring( L, 1, &nsz );
const auto srcloc = Profiler::AllocSourceLocation( dbg.currentline, src, dbg.name ? dbg.name : dbg.short_src, name, 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() );
@ -277,9 +264,7 @@ static inline int LuaZoneBegin( lua_State* L )
lua_Debug dbg;
lua_getstack( L, 1, &dbg );
lua_getinfo( L, "Snl", &dbg );
char src[256];
LuaShortenSrc( src, dbg.source );
const auto srcloc = Profiler::AllocSourceLocation( dbg.currentline, src, dbg.name ? dbg.name : dbg.short_src );
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() );
@ -305,10 +290,8 @@ static inline int LuaZoneBeginN( lua_State* L )
lua_getstack( L, 1, &dbg );
lua_getinfo( L, "Snl", &dbg );
size_t nsz;
char src[256];
LuaShortenSrc( src, dbg.source );
const auto name = lua_tolstring( L, 1, &nsz );
const auto srcloc = Profiler::AllocSourceLocation( dbg.currentline, src, dbg.name ? dbg.name : dbg.short_src, name, 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() );
@ -350,7 +333,7 @@ static inline int LuaZoneText( lua_State* L )
auto txt = lua_tostring( L, 1 );
const auto size = strlen( txt );
assert( size < (std::numeric_limits<uint16_t>::max)() );
assert( size < std::numeric_limits<uint16_t>::max() );
auto ptr = (char*)tracy_malloc( size );
memcpy( ptr, txt, size );
@ -375,7 +358,7 @@ static inline int LuaZoneName( lua_State* L )
auto txt = lua_tostring( L, 1 );
const auto size = strlen( txt );
assert( size < (std::numeric_limits<uint16_t>::max)() );
assert( size < std::numeric_limits<uint16_t>::max() );
auto ptr = (char*)tracy_malloc( size );
memcpy( ptr, txt, size );
@ -395,7 +378,7 @@ static inline int LuaMessage( lua_State* L )
auto txt = lua_tostring( L, 1 );
const auto size = strlen( txt );
assert( size < (std::numeric_limits<uint16_t>::max)() );
assert( size < std::numeric_limits<uint16_t>::max() );
auto ptr = (char*)tracy_malloc( size );
memcpy( ptr, txt, size );
@ -441,44 +424,6 @@ static inline void LuaRegister( lua_State* L )
static inline void LuaRemove( char* script ) {}
static inline void LuaHook( lua_State* L, lua_Debug* ar )
{
if ( ar->event == LUA_HOOKCALL )
{
#ifdef TRACY_ON_DEMAND
const auto zoneCnt = GetLuaZoneState().counter++;
if ( zoneCnt != 0 && !GetLuaZoneState().active ) return;
GetLuaZoneState().active = GetProfiler().IsConnected();
if ( !GetLuaZoneState().active ) return;
#endif
lua_getinfo( L, "Snl", ar );
char src[256];
detail::LuaShortenSrc( src, ar->short_src );
const auto srcloc = Profiler::AllocSourceLocation( ar->currentline, src, ar->name ? ar->name : ar->short_src );
TracyQueuePrepare( QueueType::ZoneBeginAllocSrcLoc );
MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
MemWrite( &item->zoneBegin.srcloc, srcloc );
TracyQueueCommit( zoneBeginThread );
}
else if (ar->event == LUA_HOOKRET) {
#ifdef TRACY_ON_DEMAND
assert( GetLuaZoneState().counter != 0 );
GetLuaZoneState().counter--;
if ( !GetLuaZoneState().active ) return;
if ( !GetProfiler().IsConnected() )
{
GetLuaZoneState().active = false;
return;
}
#endif
TracyQueuePrepare( QueueType::ZoneEnd );
MemWrite( &item->zoneEnd.time, Profiler::GetTime() );
TracyQueueCommit( zoneEndThread );
}
}
}
#endif

View File

@ -40,19 +40,19 @@ using TracyCLCtx = void*;
#include <sstream>
#include "Tracy.hpp"
#include "../client/TracyCallstack.hpp"
#include "../client/TracyProfiler.hpp"
#include "../common/TracyAlloc.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) ); \
TracyMessageL( "TRACY_CL_ASSERT failed on " __FILE__ ":" TRACY_CL_TO_STRING(__LINE__) ); \
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 \
oss << "TRACY_CL_CHECK_ERROR failed on " << __FILE__ << ":" << __LINE__ \
<< ": error code " << err; \
auto msg = oss.str(); \
TracyMessage(msg.data(), msg.size()); \
@ -255,7 +255,7 @@ namespace tracy {
Profiler::QueueSerialFinish();
}
tracy_force_inline OpenCLCtxScope(OpenCLCtx* ctx, const SourceLocationData* srcLoc, int32_t depth, bool is_active)
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
@ -304,7 +304,7 @@ namespace tracy {
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, int32_t depth, bool is_active)
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
@ -373,29 +373,29 @@ namespace tracy {
using TracyCLCtx = tracy::OpenCLCtx*;
#define TracyCLContext(ctx, device) tracy::CreateCLContext(ctx, device);
#define TracyCLContext(context, device) tracy::CreateCLContext(context, device);
#define TracyCLDestroy(ctx) tracy::DestroyCLContext(ctx);
#define TracyCLContextName(ctx, name, size) ctx->Name(name, size);
#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 TracyCLNamedZone(ctx, varname, name, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::OpenCLCtxScope varname(ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), TRACY_CALLSTACK, active );
# define TracyCLNamedZoneC(ctx, varname, name, color, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::OpenCLCtxScope varname(ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), 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 );
# define TracyCLZoneTransient( ctx, varname, name, active ) tracy::OpenCLCtxScope varname( ctx, __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), 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 TracyCLNamedZone(ctx, varname, name, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__){ name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::OpenCLCtxScope varname(ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), active);
# define TracyCLNamedZoneC(ctx, varname, name, color, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__){ name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::OpenCLCtxScope varname(ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), 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 );
# define TracyCLZoneTransient( ctx, varname, name, active ) tracy::OpenCLCtxScope varname( ctx, __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), 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 TracyCLNamedZoneS(ctx, varname, name, depth, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__){ name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::OpenCLCtxScope varname(ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), depth, active);
# define TracyCLNamedZoneCS(ctx, varname, name, color, depth, active) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__){ name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::OpenCLCtxScope varname(ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), 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 );
# define TracyCLZoneTransientS( ctx, varname, name, depth, active ) tracy::OpenCLCtxScope varname( ctx, __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), 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)

View File

@ -25,7 +25,7 @@ class GpuCtxScope
{
public:
GpuCtxScope( const SourceLocationData*, bool ) {}
GpuCtxScope( const SourceLocationData*, int32_t, bool ) {}
GpuCtxScope( const SourceLocationData*, int, bool ) {}
};
}
@ -36,10 +36,10 @@ public:
#include <stdlib.h>
#include "Tracy.hpp"
#include "../client/TracyProfiler.hpp"
#include "../client/TracyCallstack.hpp"
#include "../common/TracyAlign.hpp"
#include "../common/TracyAlloc.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
@ -52,26 +52,26 @@ public:
#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 TracyGpuNamedZone( varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::GpuCtxScope varname( &TracyConcat(__tracy_gpu_source_location,__LINE__), TRACY_CALLSTACK, active );
# define TracyGpuNamedZoneC( varname, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::GpuCtxScope varname( &TracyConcat(__tracy_gpu_source_location,__LINE__), 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 );
# define TracyGpuZoneTransient( varname, name, active ) tracy::GpuCtxScope varname( __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), 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 TracyGpuNamedZone( varname, name, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::GpuCtxScope varname( &TracyConcat(__tracy_gpu_source_location,__LINE__), active );
# define TracyGpuNamedZoneC( varname, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::GpuCtxScope varname( &TracyConcat(__tracy_gpu_source_location,__LINE__), 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 );
# define TracyGpuZoneTransient( varname, name, active ) tracy::GpuCtxScope varname( __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), 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 TracyGpuNamedZoneS( varname, name, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::GpuCtxScope varname( &TracyConcat(__tracy_gpu_source_location,__LINE__), depth, active );
# define TracyGpuNamedZoneCS( varname, name, color, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::GpuCtxScope varname( &TracyConcat(__tracy_gpu_source_location,__LINE__), 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 );
# define TracyGpuZoneTransientS( varname, name, depth, active ) tracy::GpuCtxScope varname( __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), 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 )
@ -222,7 +222,7 @@ public:
TracyLfqCommit;
}
tracy_force_inline GpuCtxScope( const SourceLocationData* srcloc, int32_t depth, bool is_active )
tracy_force_inline GpuCtxScope( const SourceLocationData* srcloc, int depth, bool is_active )
#ifdef TRACY_ON_DEMAND
: m_active( is_active && GetProfiler().IsConnected() )
#else
@ -271,7 +271,7 @@ public:
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, int32_t depth, bool is_active )
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

512
TracyVulkan.hpp Normal file
View File

@ -0,0 +1,512 @@
#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
#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"
namespace tracy
{
class VkCtx
{
friend class VkCtxScope;
enum { QueryCount = 64 * 1024 };
public:
VkCtx( VkPhysicalDevice physdev, VkDevice device, VkQueue queue, VkCommandBuffer cmdbuf, PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT _vkGetPhysicalDeviceCalibrateableTimeDomainsEXT, PFN_vkGetCalibratedTimestampsEXT _vkGetCalibratedTimestampsEXT )
: 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 )
, m_vkGetCalibratedTimestampsEXT( _vkGetCalibratedTimestampsEXT )
{
assert( m_context != 255 );
if( _vkGetPhysicalDeviceCalibrateableTimeDomainsEXT && _vkGetCalibratedTimestampsEXT )
{
uint32_t num;
_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT( physdev, &num, nullptr );
if( num > 4 ) num = 4;
VkTimeDomainEXT data[4];
_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT( physdev, &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;
}
}
}
VkPhysicalDeviceProperties prop;
vkGetPhysicalDeviceProperties( physdev, &prop );
const float period = prop.limits.timestampPeriod;
VkQueryPoolCreateInfo poolInfo = {};
poolInfo.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
poolInfo.queryCount = m_queryCount;
poolInfo.queryType = VK_QUERY_TYPE_TIMESTAMP;
while( vkCreateQueryPool( device, &poolInfo, nullptr, &m_query ) != VK_SUCCESS )
{
m_queryCount /= 2;
poolInfo.queryCount = m_queryCount;
}
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;
vkBeginCommandBuffer( cmdbuf, &beginInfo );
vkCmdResetQueryPool( cmdbuf, m_query, 0, m_queryCount );
vkEndCommandBuffer( cmdbuf );
vkQueueSubmit( queue, 1, &submitInfo, VK_NULL_HANDLE );
vkQueueWaitIdle( queue );
int64_t tcpu, tgpu;
if( m_timeDomain == VK_TIME_DOMAIN_DEVICE_EXT )
{
vkBeginCommandBuffer( cmdbuf, &beginInfo );
vkCmdWriteTimestamp( cmdbuf, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, m_query, 0 );
vkEndCommandBuffer( cmdbuf );
vkQueueSubmit( queue, 1, &submitInfo, VK_NULL_HANDLE );
vkQueueWaitIdle( queue );
tcpu = Profiler::GetTime();
vkGetQueryPoolResults( device, m_query, 0, 1, sizeof( tgpu ), &tgpu, sizeof( tgpu ), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT );
vkBeginCommandBuffer( cmdbuf, &beginInfo );
vkCmdResetQueryPool( cmdbuf, m_query, 0, 1 );
vkEndCommandBuffer( cmdbuf );
vkQueueSubmit( queue, 1, &submitInfo, VK_NULL_HANDLE );
vkQueueWaitIdle( queue );
}
else
{
enum { 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++ )
{
_vkGetCalibratedTimestampsEXT( 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
Calibrate( device, m_prevCalibration, tgpu );
tcpu = Profiler::GetTime();
}
uint8_t flags = 0;
if( m_timeDomain != VK_TIME_DOMAIN_DEVICE_EXT ) flags |= GpuContextCalibration;
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();
m_res = (int64_t*)tracy_malloc( sizeof( int64_t ) * m_queryCount );
}
~VkCtx()
{
tracy_free( m_res );
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 );
if( m_tail == m_head ) return;
#ifdef TRACY_ON_DEMAND
if( !GetProfiler().IsConnected() )
{
vkCmdResetQueryPool( cmdbuf, m_query, 0, m_queryCount );
m_head = m_tail = m_oldCnt = 0;
int64_t tgpu;
if( m_timeDomain != VK_TIME_DOMAIN_DEVICE_EXT ) Calibrate( m_device, m_prevCalibration, tgpu );
return;
}
#endif
unsigned int cnt;
if( m_oldCnt != 0 )
{
cnt = m_oldCnt;
m_oldCnt = 0;
}
else
{
cnt = m_head < m_tail ? m_queryCount - m_tail : m_head - m_tail;
}
if( vkGetQueryPoolResults( m_device, m_query, m_tail, 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( m_tail + 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();
}
}
vkCmdResetQueryPool( cmdbuf, m_query, m_tail, cnt );
m_tail += cnt;
if( m_tail == m_queryCount ) m_tail = 0;
}
private:
tracy_force_inline unsigned int NextQueryId()
{
const auto id = m_head;
m_head = ( m_head + 1 ) % m_queryCount;
assert( m_head != m_tail );
return id;
}
tracy_force_inline uint8_t GetId() const
{
return m_context;
}
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
}
VkDevice m_device;
VkQueryPool m_query;
VkTimeDomainEXT m_timeDomain;
uint64_t m_deviation;
int64_t m_qpcToNs;
int64_t m_prevCalibration;
uint8_t m_context;
unsigned int m_head;
unsigned int 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();
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();
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();
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();
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();
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;
};
static inline VkCtx* CreateVkContext( VkPhysicalDevice physdev, VkDevice device, VkQueue queue, VkCommandBuffer cmdbuf, PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT gpdctd, PFN_vkGetCalibratedTimestampsEXT gct )
{
auto ctx = (VkCtx*)tracy_malloc( sizeof( VkCtx ) );
new(ctx) VkCtx( physdev, device, queue, cmdbuf, gpdctd, gct );
return ctx;
}
static inline void DestroyVkContext( VkCtx* ctx )
{
ctx->~VkCtx();
tracy_free( ctx );
}
}
using TracyVkCtx = tracy::VkCtx*;
#define TracyVkContext( physdev, device, queue, cmdbuf ) tracy::CreateVkContext( physdev, device, queue, cmdbuf, nullptr, nullptr );
#define TracyVkContextCalibrated( physdev, device, queue, cmdbuf, gpdctd, gct ) tracy::CreateVkContext( physdev, device, queue, cmdbuf, gpdctd, gct );
#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,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), cmdbuf, TRACY_CALLSTACK, active );
# define TracyVkNamedZoneC( ctx, varname, cmdbuf, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), 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,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), cmdbuf, active );
# define TracyVkNamedZoneC( ctx, varname, cmdbuf, name, color, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), 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, __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), 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,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0 }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), cmdbuf, depth, active );
# define TracyVkNamedZoneCS( ctx, varname, cmdbuf, name, color, depth, active ) static constexpr tracy::SourceLocationData TracyConcat(__tracy_gpu_source_location,__LINE__) { name, __FUNCTION__, __FILE__, (uint32_t)__LINE__, color }; tracy::VkCtxScope varname( ctx, &TracyConcat(__tracy_gpu_source_location,__LINE__), 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, __LINE__, __FILE__, strlen( __FILE__ ), __FUNCTION__, strlen( __FUNCTION__ ), 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

View File

@ -1,28 +0,0 @@
cmake_minimum_required(VERSION 3.16)
option(NO_ISA_EXTENSIONS "Disable ISA extensions (don't pass -march=native or -mcpu=native to the compiler)" OFF)
option(NO_STATISTICS "Disable calculation of statistics" ON)
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/version.cmake)
set(CMAKE_CXX_STANDARD 20)
project(
tracy-capture
LANGUAGES C CXX
VERSION ${TRACY_VERSION_STRING}
)
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/config.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/vendor.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/server.cmake)
set(PROGRAM_FILES
src/capture.cpp
)
add_executable(${PROJECT_NAME} ${PROGRAM_FILES} ${COMMON_FILES} ${SERVER_FILES})
target_link_libraries(${PROJECT_NAME} PRIVATE TracyServer TracyGetOpt)
set_property(DIRECTORY ${CMAKE_CURRENT_LIST_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME})
install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})

View File

@ -0,0 +1,16 @@
all: release
debug:
@+make -f debug.mk all
release:
@+make -f release.mk all
clean:
@+make -f build.mk clean
db: clean
@bear -- $(MAKE) -f debug.mk all
@mv -f compile_commands.json ../../../
.PHONY: all clean debug release db

View File

@ -0,0 +1,12 @@
CFLAGS +=
CXXFLAGS := $(CFLAGS) -std=gnu++17
DEFINES += -DTRACY_NO_STATISTICS
INCLUDES := $(shell pkg-config --cflags capstone)
LIBS += $(shell pkg-config --libs capstone) -lpthread
PROJECT := capture
IMAGE := $(PROJECT)-$(BUILD)
FILTER := ../../../getopt/getopt.c
include ../../../common/src-from-vcxproj.mk
include ../../../common/unix.mk

View File

@ -0,0 +1,6 @@
CFLAGS := -g3 -Wall
DEFINES := -DDEBUG
BUILD := debug
include ../../../common/unix-debug.mk
include build.mk

View File

@ -0,0 +1,9 @@
CFLAGS := -O3
ifndef TRACY_NO_LTO
CFLAGS += -flto
endif
DEFINES := -DNDEBUG
BUILD := release
include ../../../common/unix-release.mk
include build.mk

View File

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30907.101
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "capture", "capture.vcxproj", "{447D58BF-94CD-4469-BB90-549C05D03E00}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{447D58BF-94CD-4469-BB90-549C05D03E00}.Debug|x64.ActiveCfg = Debug|x64
{447D58BF-94CD-4469-BB90-549C05D03E00}.Debug|x64.Build.0 = Debug|x64
{447D58BF-94CD-4469-BB90-549C05D03E00}.Release|x64.ActiveCfg = Release|x64
{447D58BF-94CD-4469-BB90-549C05D03E00}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3E51386C-43EA-44AC-9F24-AFAFE4D63ADE}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,206 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{447D58BF-94CD-4469-BB90-549C05D03E00}</ProjectGuid>
<RootNamespace>capture</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<VcpkgTriplet>x64-windows-static</VcpkgTriplet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<PropertyGroup Label="Vcpkg">
<VcpkgEnableManifest>true</VcpkgEnableManifest>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<PreprocessorDefinitions>TRACY_NO_STATISTICS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;NOMINMAX;_USE_MATH_DEFINES;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnableEnhancedInstructionSet>AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\vcpkg_installed\$(VcpkgTriplet)\include;$(ProjectDir)..\..\..\vcpkg_installed\$(VcpkgTriplet)\include\capstone;$(VcpkgManifestRoot)\vcpkg_installed\$(VcpkgTriplet)\$(VcpkgTriplet)\include\capstone;$(VcpkgRoot)\installed\$(VcpkgTriplet)\include\capstone</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;capstone.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\vcpkg_installed\$(VcpkgTriplet)\debug\lib</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<PreprocessorDefinitions>TRACY_NO_STATISTICS;NDEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32_LEAN_AND_MEAN;NOMINMAX;_USE_MATH_DEFINES;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnableEnhancedInstructionSet>AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\vcpkg_installed\$(VcpkgTriplet)\include;$(ProjectDir)..\..\..\vcpkg_installed\$(VcpkgTriplet)\include\capstone;$(VcpkgManifestRoot)\vcpkg_installed\$(VcpkgTriplet)\$(VcpkgTriplet)\include\capstone;$(VcpkgRoot)\installed\$(VcpkgTriplet)\include\capstone</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>ws2_32.lib;capstone.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem>
<AdditionalLibraryDirectories>$(ProjectDir)..\..\..\vcpkg_installed\$(VcpkgTriplet)\lib</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\common\TracySocket.cpp" />
<ClCompile Include="..\..\..\common\TracyStackFrames.cpp" />
<ClCompile Include="..\..\..\common\TracySystem.cpp" />
<ClCompile Include="..\..\..\common\tracy_lz4.cpp" />
<ClCompile Include="..\..\..\common\tracy_lz4hc.cpp" />
<ClCompile Include="..\..\..\getopt\getopt.c" />
<ClCompile Include="..\..\..\server\TracyMemory.cpp" />
<ClCompile Include="..\..\..\server\TracyMmap.cpp" />
<ClCompile Include="..\..\..\server\TracyPrint.cpp" />
<ClCompile Include="..\..\..\server\TracyTaskDispatch.cpp" />
<ClCompile Include="..\..\..\server\TracyTextureCompression.cpp" />
<ClCompile Include="..\..\..\server\TracyThreadCompress.cpp" />
<ClCompile Include="..\..\..\server\TracyWorker.cpp" />
<ClCompile Include="..\..\..\zstd\common\debug.c" />
<ClCompile Include="..\..\..\zstd\common\entropy_common.c" />
<ClCompile Include="..\..\..\zstd\common\error_private.c" />
<ClCompile Include="..\..\..\zstd\common\fse_decompress.c" />
<ClCompile Include="..\..\..\zstd\common\pool.c" />
<ClCompile Include="..\..\..\zstd\common\threading.c" />
<ClCompile Include="..\..\..\zstd\common\xxhash.c" />
<ClCompile Include="..\..\..\zstd\common\zstd_common.c" />
<ClCompile Include="..\..\..\zstd\compress\fse_compress.c" />
<ClCompile Include="..\..\..\zstd\compress\hist.c" />
<ClCompile Include="..\..\..\zstd\compress\huf_compress.c" />
<ClCompile Include="..\..\..\zstd\compress\zstdmt_compress.c" />
<ClCompile Include="..\..\..\zstd\compress\zstd_compress.c" />
<ClCompile Include="..\..\..\zstd\compress\zstd_compress_literals.c" />
<ClCompile Include="..\..\..\zstd\compress\zstd_compress_sequences.c" />
<ClCompile Include="..\..\..\zstd\compress\zstd_compress_superblock.c" />
<ClCompile Include="..\..\..\zstd\compress\zstd_double_fast.c" />
<ClCompile Include="..\..\..\zstd\compress\zstd_fast.c" />
<ClCompile Include="..\..\..\zstd\compress\zstd_lazy.c" />
<ClCompile Include="..\..\..\zstd\compress\zstd_ldm.c" />
<ClCompile Include="..\..\..\zstd\compress\zstd_opt.c" />
<ClCompile Include="..\..\..\zstd\decompress\huf_decompress.c" />
<ClCompile Include="..\..\..\zstd\decompress\zstd_ddict.c" />
<ClCompile Include="..\..\..\zstd\decompress\zstd_decompress.c" />
<ClCompile Include="..\..\..\zstd\decompress\zstd_decompress_block.c" />
<ClCompile Include="..\..\..\zstd\dictBuilder\cover.c" />
<ClCompile Include="..\..\..\zstd\dictBuilder\divsufsort.c" />
<ClCompile Include="..\..\..\zstd\dictBuilder\fastcover.c" />
<ClCompile Include="..\..\..\zstd\dictBuilder\zdict.c" />
<ClCompile Include="..\..\src\capture.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\common\TracyAlign.hpp" />
<ClInclude Include="..\..\..\common\TracyAlloc.hpp" />
<ClInclude Include="..\..\..\common\TracyColor.hpp" />
<ClInclude Include="..\..\..\common\TracyForceInline.hpp" />
<ClInclude Include="..\..\..\common\TracyProtocol.hpp" />
<ClInclude Include="..\..\..\common\TracyQueue.hpp" />
<ClInclude Include="..\..\..\common\TracySocket.hpp" />
<ClInclude Include="..\..\..\common\TracyStackFrames.hpp" />
<ClInclude Include="..\..\..\common\TracySystem.hpp" />
<ClInclude Include="..\..\..\common\tracy_lz4.hpp" />
<ClInclude Include="..\..\..\common\tracy_lz4hc.hpp" />
<ClInclude Include="..\..\..\getopt\getopt.h" />
<ClInclude Include="..\..\..\server\TracyCharUtil.hpp" />
<ClInclude Include="..\..\..\server\TracyEvent.hpp" />
<ClInclude Include="..\..\..\server\TracyFileRead.hpp" />
<ClInclude Include="..\..\..\server\TracyFileWrite.hpp" />
<ClInclude Include="..\..\..\server\TracyMemory.hpp" />
<ClInclude Include="..\..\..\server\TracyMmap.hpp" />
<ClInclude Include="..\..\..\server\TracyPopcnt.hpp" />
<ClInclude Include="..\..\..\server\TracyPrint.hpp" />
<ClInclude Include="..\..\..\server\TracySlab.hpp" />
<ClInclude Include="..\..\..\server\TracyTaskDispatch.hpp" />
<ClInclude Include="..\..\..\server\TracyTextureCompression.hpp" />
<ClInclude Include="..\..\..\server\TracyThreadCompress.hpp" />
<ClInclude Include="..\..\..\server\TracyVector.hpp" />
<ClInclude Include="..\..\..\server\TracyWorker.hpp" />
<ClInclude Include="..\..\..\zstd\common\bitstream.h" />
<ClInclude Include="..\..\..\zstd\common\compiler.h" />
<ClInclude Include="..\..\..\zstd\common\cpu.h" />
<ClInclude Include="..\..\..\zstd\common\debug.h" />
<ClInclude Include="..\..\..\zstd\common\error_private.h" />
<ClInclude Include="..\..\..\zstd\common\fse.h" />
<ClInclude Include="..\..\..\zstd\common\huf.h" />
<ClInclude Include="..\..\..\zstd\common\mem.h" />
<ClInclude Include="..\..\..\zstd\common\pool.h" />
<ClInclude Include="..\..\..\zstd\common\portability_macros.h" />
<ClInclude Include="..\..\..\zstd\common\threading.h" />
<ClInclude Include="..\..\..\zstd\common\xxhash.h" />
<ClInclude Include="..\..\..\zstd\common\zstd_deps.h" />
<ClInclude Include="..\..\..\zstd\common\zstd_internal.h" />
<ClInclude Include="..\..\..\zstd\common\zstd_trace.h" />
<ClInclude Include="..\..\..\zstd\compress\clevels.h" />
<ClInclude Include="..\..\..\zstd\compress\hist.h" />
<ClInclude Include="..\..\..\zstd\compress\zstdmt_compress.h" />
<ClInclude Include="..\..\..\zstd\compress\zstd_compress_internal.h" />
<ClInclude Include="..\..\..\zstd\compress\zstd_compress_literals.h" />
<ClInclude Include="..\..\..\zstd\compress\zstd_compress_sequences.h" />
<ClInclude Include="..\..\..\zstd\compress\zstd_compress_superblock.h" />
<ClInclude Include="..\..\..\zstd\compress\zstd_cwksp.h" />
<ClInclude Include="..\..\..\zstd\compress\zstd_double_fast.h" />
<ClInclude Include="..\..\..\zstd\compress\zstd_fast.h" />
<ClInclude Include="..\..\..\zstd\compress\zstd_lazy.h" />
<ClInclude Include="..\..\..\zstd\compress\zstd_ldm.h" />
<ClInclude Include="..\..\..\zstd\compress\zstd_ldm_geartab.h" />
<ClInclude Include="..\..\..\zstd\compress\zstd_opt.h" />
<ClInclude Include="..\..\..\zstd\decompress\zstd_ddict.h" />
<ClInclude Include="..\..\..\zstd\decompress\zstd_decompress_block.h" />
<ClInclude Include="..\..\..\zstd\decompress\zstd_decompress_internal.h" />
<ClInclude Include="..\..\..\zstd\dictBuilder\cover.h" />
<ClInclude Include="..\..\..\zstd\dictBuilder\divsufsort.h" />
<ClInclude Include="..\..\..\zstd\zdict.h" />
<ClInclude Include="..\..\..\zstd\zstd.h" />
<ClInclude Include="..\..\..\zstd\zstd_errors.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\..\zstd\decompress\huf_decompress_amd64.S" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,359 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="src">
<UniqueIdentifier>{729c80ee-4d26-4a5e-8f1f-6c075783eb56}</UniqueIdentifier>
</Filter>
<Filter Include="server">
<UniqueIdentifier>{cf23ef7b-7694-4154-830b-00cf053350ea}</UniqueIdentifier>
</Filter>
<Filter Include="common">
<UniqueIdentifier>{e39d3623-47cd-4752-8da9-3ea324f964c1}</UniqueIdentifier>
</Filter>
<Filter Include="getopt">
<UniqueIdentifier>{ee9737d2-69c7-44da-b9c7-539d18f9d4b4}</UniqueIdentifier>
</Filter>
<Filter Include="zstd">
<UniqueIdentifier>{f201463b-5e69-46fe-bdfc-1b5eed86c7f7}</UniqueIdentifier>
</Filter>
<Filter Include="zstd\common">
<UniqueIdentifier>{7e93ae33-6543-4bca-b05b-50818dbf24cc}</UniqueIdentifier>
</Filter>
<Filter Include="zstd\compress">
<UniqueIdentifier>{3b0c32f5-9efb-4503-9394-5ab95909fb1c}</UniqueIdentifier>
</Filter>
<Filter Include="zstd\decompress">
<UniqueIdentifier>{c1f99170-d904-4af1-8010-0a3ded5736c8}</UniqueIdentifier>
</Filter>
<Filter Include="zstd\dictBuilder">
<UniqueIdentifier>{456e6786-ea57-42b8-ae38-829cd2d918bd}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\common\tracy_lz4.cpp">
<Filter>common</Filter>
</ClCompile>
<ClCompile Include="..\..\..\common\TracySocket.cpp">
<Filter>common</Filter>
</ClCompile>
<ClCompile Include="..\..\..\common\TracySystem.cpp">
<Filter>common</Filter>
</ClCompile>
<ClCompile Include="..\..\..\server\TracyMemory.cpp">
<Filter>server</Filter>
</ClCompile>
<ClCompile Include="..\..\..\server\TracyWorker.cpp">
<Filter>server</Filter>
</ClCompile>
<ClCompile Include="..\..\src\capture.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\..\common\tracy_lz4hc.cpp">
<Filter>common</Filter>
</ClCompile>
<ClCompile Include="..\..\..\server\TracyPrint.cpp">
<Filter>server</Filter>
</ClCompile>
<ClCompile Include="..\..\..\server\TracyThreadCompress.cpp">
<Filter>server</Filter>
</ClCompile>
<ClCompile Include="..\..\..\server\TracyTaskDispatch.cpp">
<Filter>server</Filter>
</ClCompile>
<ClCompile Include="..\..\..\server\TracyMmap.cpp">
<Filter>server</Filter>
</ClCompile>
<ClCompile Include="..\..\..\server\TracyTextureCompression.cpp">
<Filter>server</Filter>
</ClCompile>
<ClCompile Include="..\..\..\getopt\getopt.c">
<Filter>getopt</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\common\debug.c">
<Filter>zstd\common</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\common\entropy_common.c">
<Filter>zstd\common</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\common\error_private.c">
<Filter>zstd\common</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\common\fse_decompress.c">
<Filter>zstd\common</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\common\pool.c">
<Filter>zstd\common</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\common\threading.c">
<Filter>zstd\common</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\common\xxhash.c">
<Filter>zstd\common</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\common\zstd_common.c">
<Filter>zstd\common</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\compress\fse_compress.c">
<Filter>zstd\compress</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\compress\hist.c">
<Filter>zstd\compress</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\compress\huf_compress.c">
<Filter>zstd\compress</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\compress\zstd_compress.c">
<Filter>zstd\compress</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\compress\zstd_compress_literals.c">
<Filter>zstd\compress</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\compress\zstd_compress_sequences.c">
<Filter>zstd\compress</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\compress\zstd_compress_superblock.c">
<Filter>zstd\compress</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\compress\zstd_double_fast.c">
<Filter>zstd\compress</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\compress\zstd_fast.c">
<Filter>zstd\compress</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\compress\zstd_lazy.c">
<Filter>zstd\compress</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\compress\zstd_ldm.c">
<Filter>zstd\compress</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\compress\zstd_opt.c">
<Filter>zstd\compress</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\compress\zstdmt_compress.c">
<Filter>zstd\compress</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\decompress\huf_decompress.c">
<Filter>zstd\decompress</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\decompress\zstd_ddict.c">
<Filter>zstd\decompress</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\decompress\zstd_decompress.c">
<Filter>zstd\decompress</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\decompress\zstd_decompress_block.c">
<Filter>zstd\decompress</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\dictBuilder\cover.c">
<Filter>zstd\dictBuilder</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\dictBuilder\divsufsort.c">
<Filter>zstd\dictBuilder</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\dictBuilder\fastcover.c">
<Filter>zstd\dictBuilder</Filter>
</ClCompile>
<ClCompile Include="..\..\..\zstd\dictBuilder\zdict.c">
<Filter>zstd\dictBuilder</Filter>
</ClCompile>
<ClCompile Include="..\..\..\common\TracyStackFrames.cpp">
<Filter>common</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\common\tracy_lz4.hpp">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\common\TracyAlloc.hpp">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\common\TracyColor.hpp">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\common\TracyForceInline.hpp">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\common\TracyProtocol.hpp">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\common\TracyQueue.hpp">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\common\TracySocket.hpp">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\common\TracySystem.hpp">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\server\TracyCharUtil.hpp">
<Filter>server</Filter>
</ClInclude>
<ClInclude Include="..\..\..\server\TracyEvent.hpp">
<Filter>server</Filter>
</ClInclude>
<ClInclude Include="..\..\..\server\TracyFileWrite.hpp">
<Filter>server</Filter>
</ClInclude>
<ClInclude Include="..\..\..\server\TracyMemory.hpp">
<Filter>server</Filter>
</ClInclude>
<ClInclude Include="..\..\..\server\TracyPopcnt.hpp">
<Filter>server</Filter>
</ClInclude>
<ClInclude Include="..\..\..\server\TracySlab.hpp">
<Filter>server</Filter>
</ClInclude>
<ClInclude Include="..\..\..\server\TracyVector.hpp">
<Filter>server</Filter>
</ClInclude>
<ClInclude Include="..\..\..\server\TracyWorker.hpp">
<Filter>server</Filter>
</ClInclude>
<ClInclude Include="..\..\..\common\TracyAlign.hpp">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\common\tracy_lz4hc.hpp">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\server\TracyPrint.hpp">
<Filter>server</Filter>
</ClInclude>
<ClInclude Include="..\..\..\server\TracyThreadCompress.hpp">
<Filter>server</Filter>
</ClInclude>
<ClInclude Include="..\..\..\server\TracyTaskDispatch.hpp">
<Filter>server</Filter>
</ClInclude>
<ClInclude Include="..\..\..\server\TracyFileRead.hpp">
<Filter>server</Filter>
</ClInclude>
<ClInclude Include="..\..\..\server\TracyMmap.hpp">
<Filter>server</Filter>
</ClInclude>
<ClInclude Include="..\..\..\server\TracyTextureCompression.hpp">
<Filter>server</Filter>
</ClInclude>
<ClInclude Include="..\..\..\getopt\getopt.h">
<Filter>getopt</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\zstd.h">
<Filter>zstd</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\zstd_errors.h">
<Filter>zstd</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\common\bitstream.h">
<Filter>zstd\common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\common\compiler.h">
<Filter>zstd\common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\common\cpu.h">
<Filter>zstd\common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\common\debug.h">
<Filter>zstd\common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\common\error_private.h">
<Filter>zstd\common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\common\fse.h">
<Filter>zstd\common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\common\huf.h">
<Filter>zstd\common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\common\mem.h">
<Filter>zstd\common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\common\pool.h">
<Filter>zstd\common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\common\threading.h">
<Filter>zstd\common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\common\xxhash.h">
<Filter>zstd\common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\common\zstd_deps.h">
<Filter>zstd\common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\common\zstd_internal.h">
<Filter>zstd\common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\common\zstd_trace.h">
<Filter>zstd\common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\compress\hist.h">
<Filter>zstd\compress</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\compress\zstd_compress_internal.h">
<Filter>zstd\compress</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\compress\zstd_compress_literals.h">
<Filter>zstd\compress</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\compress\zstd_compress_sequences.h">
<Filter>zstd\compress</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\compress\zstd_compress_superblock.h">
<Filter>zstd\compress</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\compress\zstd_cwksp.h">
<Filter>zstd\compress</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\compress\zstd_double_fast.h">
<Filter>zstd\compress</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\compress\zstd_fast.h">
<Filter>zstd\compress</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\compress\zstd_lazy.h">
<Filter>zstd\compress</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\compress\zstd_ldm.h">
<Filter>zstd\compress</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\compress\zstd_ldm_geartab.h">
<Filter>zstd\compress</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\compress\zstd_opt.h">
<Filter>zstd\compress</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\compress\zstdmt_compress.h">
<Filter>zstd\compress</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\decompress\zstd_ddict.h">
<Filter>zstd\decompress</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\decompress\zstd_decompress_block.h">
<Filter>zstd\decompress</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\decompress\zstd_decompress_internal.h">
<Filter>zstd\decompress</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\dictBuilder\cover.h">
<Filter>zstd\dictBuilder</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\dictBuilder\divsufsort.h">
<Filter>zstd\dictBuilder</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\zdict.h">
<Filter>zstd</Filter>
</ClInclude>
<ClInclude Include="..\..\..\common\TracyStackFrames.hpp">
<Filter>common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\common\portability_macros.h">
<Filter>zstd\common</Filter>
</ClInclude>
<ClInclude Include="..\..\..\zstd\compress\clevels.h">
<Filter>zstd\compress</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\..\zstd\decompress\huf_decompress_amd64.S">
<Filter>zstd\decompress</Filter>
</None>
</ItemGroup>
</Project>

View File

@ -16,12 +16,11 @@
#include <stdlib.h>
#include <sys/stat.h>
#include "../../public/common/TracyProtocol.hpp"
#include "../../public/common/TracyStackFrames.hpp"
#include "../../common/TracyProtocol.hpp"
#include "../../common/TracyStackFrames.hpp"
#include "../../server/TracyFileWrite.hpp"
#include "../../server/TracyMemory.hpp"
#include "../../server/TracyPrint.hpp"
#include "../../server/TracySysUtil.hpp"
#include "../../server/TracyWorker.hpp"
#ifdef _WIN32
@ -62,7 +61,6 @@ bool IsStdoutATerminal() { return s_isStdoutATerminal; }
#define ANSI_RED "\033[31m"
#define ANSI_GREEN "\033[32m"
#define ANSI_YELLOW "\033[33m"
#define ANSI_BLUE "\033[34m"
#define ANSI_MAGENTA "\033[35m"
#define ANSI_CYAN "\033[36m"
#define ANSI_ERASE_LINE "\033[2K"
@ -92,7 +90,7 @@ void AnsiPrintf( const char* ansiEscape, const char* format, ... ) {
[[noreturn]] void Usage()
{
printf( "Usage: capture -o output.tracy [-a address] [-p port] [-f] [-s seconds] [-m memlimit]\n" );
printf( "Usage: capture -o output.tracy [-a address] [-p port] [-f] [-s seconds]\n" );
exit( 1 );
}
@ -113,10 +111,9 @@ int main( int argc, char** argv )
const char* output = nullptr;
int port = 8086;
int seconds = -1;
int64_t memoryLimit = -1;
int c;
while( ( c = getopt( argc, argv, "a:o:p:fs:m:" ) ) != -1 )
while( ( c = getopt( argc, argv, "a:o:p:fs:" ) ) != -1 )
{
switch( c )
{
@ -133,10 +130,7 @@ int main( int argc, char** argv )
overwrite = true;
break;
case 's':
seconds = atoi(optarg);
break;
case 'm':
memoryLimit = std::clamp( atoll( optarg ), 1ll, 999ll ) * tracy::GetPhysicalMemorySize() / 100;
seconds = atoi (optarg);
break;
default:
Usage();
@ -164,8 +158,8 @@ int main( int argc, char** argv )
printf( "Connecting to %s:%i...", address, port );
fflush( stdout );
tracy::Worker worker( address, port, memoryLimit );
while( !worker.HasData() )
tracy::Worker worker( address, port );
while( !worker.IsConnected() )
{
const auto handshake = worker.GetHandshakeStatus();
if( handshake == tracy::HandshakeProtocolMismatch )
@ -183,8 +177,8 @@ int main( int argc, char** argv )
printf( "\nThe client you are trying to connect to has disconnected during the initial\nconnection handshake. Please check your network configuration.\n" );
return 3;
}
std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
}
while( !worker.HasData() ) std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
printf( "\nQueue delay: %s\nTimer resolution: %s\n", tracy::TimeToString( worker.GetDelay() ), tracy::TimeToString( worker.GetResolution() ) );
#ifdef _WIN32
@ -196,7 +190,6 @@ int main( int argc, char** argv )
sigaction( SIGINT, &sigint, &oldsigint );
#endif
const auto firstTime = worker.GetFirstTime();
auto& lock = worker.GetMbpsDataLock();
const auto t0 = std::chrono::high_resolution_clock::now();
@ -238,16 +231,11 @@ int main( int argc, char** argv )
AnsiPrintf( ANSI_YELLOW ANSI_BOLD, "%7.2f Mbps", mbps / compRatio );
printf( " | ");
AnsiPrintf( ANSI_YELLOW, "Tx: ");
AnsiPrintf( ANSI_GREEN, "%s", tracy::MemSizeToString( netTotal ) );
AnsiPrintf( ANSI_GREEN, "%s", tracy::MemSizeToString( netTotal ) );
printf( " | ");
AnsiPrintf( ANSI_RED ANSI_BOLD, "%s", tracy::MemSizeToString( tracy::memUsage.load( std::memory_order_relaxed ) ) );
if( memoryLimit > 0 )
{
printf( " / " );
AnsiPrintf( ANSI_BLUE ANSI_BOLD, "%s", tracy::MemSizeToString( memoryLimit ) );
}
AnsiPrintf( ANSI_RED ANSI_BOLD, "%s", tracy::MemSizeToString( tracy::memUsage ) );
printf( " | ");
AnsiPrintf( ANSI_RED, "%s", tracy::TimeToString( worker.GetLastTime() - firstTime ) );
AnsiPrintf( ANSI_RED, "%s", tracy::TimeToString( worker.GetLastTime() ) );
fflush( stdout );
}
@ -276,9 +264,10 @@ int main( int argc, char** argv )
}
if( fd.callstack != 0 )
{
AnsiPrintf( ANSI_BOLD, "\nFailure callstack:\n" );
AnsiPrintf( ANSI_BOLD, "\n%sFailure callstack:%s\n" );
auto& cs = worker.GetCallstack( fd.callstack );
int fidx = 0;
int bidx = 0;
for( auto& entry : cs )
{
auto frameData = worker.GetCallstackFrame( entry );
@ -310,6 +299,8 @@ int main( int argc, char** argv )
if( match ) continue;
}
bidx++;
if( f == fsz-1 )
{
printf( "%3i. ", fidx++ );
@ -343,10 +334,10 @@ int main( int argc, char** argv )
}
printf( "\nFrames: %" PRIu64 "\nTime span: %s\nZones: %s\nElapsed time: %s\nSaving trace...",
worker.GetFrameCount( *worker.GetFramesBase() ), tracy::TimeToString( worker.GetLastTime() - firstTime ), tracy::RealToString( worker.GetZoneCount() ),
worker.GetFrameCount( *worker.GetFramesBase() ), tracy::TimeToString( worker.GetLastTime() ), tracy::RealToString( worker.GetZoneCount() ),
tracy::TimeToString( std::chrono::duration_cast<std::chrono::nanoseconds>( t1 - t0 ).count() ) );
fflush( stdout );
auto f = std::unique_ptr<tracy::FileWrite>( tracy::FileWrite::Open( output, tracy::FileCompression::Zstd, 3, 4 ) );
auto f = std::unique_ptr<tracy::FileWrite>( tracy::FileWrite::Open( output ) );
if( f )
{
worker.Write( *f, false );

View File

@ -1,9 +1,8 @@
#include "../common/TracyAlloc.hpp"
#ifdef TRACY_USE_RPMALLOC
#ifdef TRACY_ENABLE
#include <atomic>
#include "../common/TracyAlloc.hpp"
#include "../common/TracyForceInline.hpp"
#include "../common/TracyYield.hpp"

View File

@ -305,14 +305,6 @@ static const char* DecodeIosDevice( const char* id )
"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)",
@ -373,8 +365,6 @@ static const char* DecodeIosDevice( const char* id )
"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",
@ -387,14 +377,6 @@ static const char* DecodeIosDevice( const char* id )
"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",

View File

@ -2,31 +2,17 @@
#define __TRACYCALLSTACK_HPP__
#include "../common/TracyApi.h"
#include "../common/TracyForceInline.hpp"
#include "TracyCallstack.h"
#ifndef TRACY_HAS_CALLSTACK
namespace tracy
{
static constexpr bool has_callstack() { return false; }
static tracy_force_inline void* Callstack( int32_t /*depth*/ ) { return nullptr; }
}
#else
#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
# include <execinfo.h>
#endif
#ifdef TRACY_HAS_CALLSTACK
#ifdef TRACY_DEBUGINFOD
# include <elfutils/debuginfod.h>
#endif
@ -35,12 +21,11 @@ static tracy_force_inline void* Callstack( int32_t /*depth*/ ) { return nullptr;
#include <stdint.h>
#include "../common/TracyAlloc.hpp"
#include "../common/TracyForceInline.hpp"
namespace tracy
{
static constexpr bool has_callstack() { return true; }
struct CallstackSymbolData
{
const char* file;
@ -66,10 +51,10 @@ struct CallstackEntryData
};
CallstackSymbolData DecodeSymbolAddress( uint64_t ptr );
CallstackSymbolData DecodeCodeAddress( 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 );
@ -86,7 +71,7 @@ extern "C"
TRACY_API extern ___tracy_t_RtlWalkFrameChain ___tracy_RtlWalkFrameChain;
}
static tracy_force_inline void* Callstack( int32_t depth )
static tracy_force_inline void* Callstack( int depth )
{
assert( depth >= 1 && depth < 63 );
auto trace = (uintptr_t*)tracy_malloc( ( 1 + depth ) * sizeof( uintptr_t ) );
@ -115,7 +100,7 @@ static _Unwind_Reason_Code tracy_unwind_callback( struct _Unwind_Context* ctx, v
return _URC_NO_REASON;
}
static tracy_force_inline void* Callstack( int32_t depth )
static tracy_force_inline void* Callstack( int depth )
{
assert( depth >= 1 && depth < 63 );
@ -130,18 +115,12 @@ static tracy_force_inline void* Callstack( int32_t depth )
#elif TRACY_HAS_CALLSTACK == 3 || TRACY_HAS_CALLSTACK == 4 || TRACY_HAS_CALLSTACK == 6
static tracy_force_inline void* Callstack( int32_t depth )
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;

View File

@ -21,7 +21,7 @@ public:
, m_active( false )
#endif
{
assert( m_id != (std::numeric_limits<uint32_t>::max)() );
assert( m_id != std::numeric_limits<uint32_t>::max() );
auto item = Profiler::QueueSerial();
MemWrite( &item->hdr.type, QueueType::LockAnnounce );
@ -98,6 +98,7 @@ public:
auto item = Profiler::QueueSerial();
MemWrite( &item->hdr.type, QueueType::LockRelease );
MemWrite( &item->lockRelease.thread, GetThreadHandle() );
MemWrite( &item->lockRelease.id, m_id );
MemWrite( &item->lockRelease.time, Profiler::GetTime() );
Profiler::QueueSerialFinish();
@ -154,7 +155,7 @@ public:
tracy_force_inline void CustomName( const char* name, size_t size )
{
assert( size < (std::numeric_limits<uint16_t>::max)() );
assert( size < std::numeric_limits<uint16_t>::max() );
auto ptr = (char*)tracy_malloc( size );
memcpy( ptr, name, size );
auto item = Profiler::QueueSerial();
@ -235,7 +236,7 @@ public:
, m_active( false )
#endif
{
assert( m_id != (std::numeric_limits<uint32_t>::max)() );
assert( m_id != std::numeric_limits<uint32_t>::max() );
auto item = Profiler::QueueSerial();
MemWrite( &item->hdr.type, QueueType::LockAnnounce );
@ -312,6 +313,7 @@ public:
auto item = Profiler::QueueSerial();
MemWrite( &item->hdr.type, QueueType::LockRelease );
MemWrite( &item->lockRelease.thread, GetThreadHandle() );
MemWrite( &item->lockRelease.id, m_id );
MemWrite( &item->lockRelease.time, Profiler::GetTime() );
Profiler::QueueSerialFinish();
@ -393,9 +395,9 @@ public:
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() );
MemWrite( &item->lockRelease.thread, GetThreadHandle() );
MemWrite( &item->lockRelease.id, m_id );
MemWrite( &item->lockRelease.time, Profiler::GetTime() );
Profiler::QueueSerialFinish();
}
@ -450,7 +452,7 @@ public:
tracy_force_inline void CustomName( const char* name, size_t size )
{
assert( size < (std::numeric_limits<uint16_t>::max)() );
assert( size < std::numeric_limits<uint16_t>::max() );
auto ptr = (char*)tracy_malloc( size );
memcpy( ptr, name, size );
auto item = Profiler::QueueSerial();

File diff suppressed because it is too large Load Diff

View File

@ -10,8 +10,6 @@
#include "tracy_concurrentqueue.h"
#include "tracy_SPSCQueue.h"
#include "TracyCallstack.hpp"
#include "TracyKCore.hpp"
#include "TracySysPower.hpp"
#include "TracySysTime.hpp"
#include "TracyFastVector.hpp"
#include "../common/TracyQueue.hpp"
@ -28,7 +26,7 @@
# include <mach/mach_time.h>
#endif
#if ( (defined _WIN32 && !(defined _M_ARM64 || defined _M_ARM)) || ( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 ) || ( defined TARGET_OS_IOS && TARGET_OS_IOS == 1 ) )
#if ( defined _WIN32 || ( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 ) || ( defined TARGET_OS_IOS && TARGET_OS_IOS == 1 ) )
# define TRACY_HW_TIMER
#endif
@ -52,10 +50,6 @@ namespace tracy
#if defined(TRACY_DELAYED_INIT) && defined(TRACY_MANUAL_LIFETIME)
TRACY_API void StartupProfiler();
TRACY_API void ShutdownProfiler();
TRACY_API bool IsProfilerStarted();
# define TracyIsStarted tracy::IsProfilerStarted()
#else
# define TracyIsStarted true
#endif
class GpuCtx;
@ -114,11 +108,11 @@ struct LuaZoneState
#define TracyLfqPrepare( _type ) \
tracy::moodycamel::ConcurrentQueueDefaultTraits::index_t __magic; \
auto __token = tracy::GetToken(); \
moodycamel::ConcurrentQueueDefaultTraits::index_t __magic; \
auto __token = GetToken(); \
auto& __tail = __token->get_tail_index(); \
auto item = __token->enqueue_begin( __magic ); \
tracy::MemWrite( &item->hdr.type, _type );
MemWrite( &item->hdr.type, _type );
#define TracyLfqCommit \
__tail.store( __magic + 1, std::memory_order_release );
@ -136,11 +130,11 @@ struct LuaZoneState
#ifdef TRACY_FIBERS
# define TracyQueuePrepare( _type ) \
auto item = tracy::Profiler::QueueSerial(); \
tracy::MemWrite( &item->hdr.type, _type );
auto item = Profiler::QueueSerial(); \
MemWrite( &item->hdr.type, _type );
# define TracyQueueCommit( _name ) \
tracy::MemWrite( &item->_name.thread, tracy::GetThreadHandle() ); \
tracy::Profiler::QueueSerialFinish();
MemWrite( &item->_name.thread, GetThreadHandle() ); \
Profiler::QueueSerialFinish();
# define TracyQueuePrepareC( _type ) \
auto item = tracy::Profiler::QueueSerial(); \
tracy::MemWrite( &item->hdr.type, _type );
@ -155,8 +149,7 @@ struct LuaZoneState
#endif
typedef void(*ParameterCallback)( void* data, uint32_t idx, int32_t val );
typedef char*(*SourceContentsCallback)( void* data, const char* filename, size_t& size );
typedef void(*ParameterCallback)( uint32_t idx, int32_t val );
class Profiler
{
@ -173,17 +166,16 @@ class Profiler
{
CallstackFrame,
SymbolQuery,
CodeLocation,
ExternalName,
KernelCode,
SourceCode
KernelCode
};
struct SymbolQueueItem
{
SymbolQueueItemType type;
uint64_t ptr;
uint64_t extra;
uint32_t id;
uint32_t extra;
};
public:
@ -214,22 +206,7 @@ public:
if( HardwareSupportsInvariantTSC() )
{
uint64_t rax, rdx;
#ifdef TRACY_PATCHABLE_NOPSLEDS
// Some external tooling (such as rr) wants to patch our rdtsc and replace it by a
// branch to control the external input seen by a program. This kind of patching is
// not generally possible depending on the surrounding code and can lead to significant
// slowdowns if the compiler generated unlucky code and rr and tracy are used together.
// To avoid this, use the rr-safe `nopl 0(%rax, %rax, 1); rdtsc` instruction sequence,
// which rr promises will be patchable independent of the surrounding code.
asm volatile (
// This is nopl 0(%rax, %rax, 1), but assemblers are inconsistent about whether
// they emit that as a 4 or 5 byte sequence and we need to be guaranteed to use
// the 5 byte one.
".byte 0x0f, 0x1f, 0x44, 0x00, 0x00\n\t"
"rdtsc" : "=a" (rax), "=d" (rdx) );
#else
asm volatile ( "rdtsc" : "=a" (rax), "=d" (rdx) );
#endif
return (int64_t)(( rdx << 32 ) + rax);
}
# else
@ -309,7 +286,7 @@ public:
{
#ifndef TRACY_NO_FRAME_IMAGE
auto& profiler = GetProfiler();
assert( profiler.m_frameCount.load( std::memory_order_relaxed ) < (std::numeric_limits<uint32_t>::max)() );
assert( profiler.m_frameCount.load( std::memory_order_relaxed ) < std::numeric_limits<uint32_t>::max() );
# ifdef TRACY_ON_DEMAND
if( !profiler.IsConnected() ) return;
# endif
@ -326,12 +303,6 @@ public:
fi->flip = flip;
profiler.m_fiQueue.commit_next();
profiler.m_fiLock.unlock();
#else
static_cast<void>(image); // unused
static_cast<void>(w); // unused
static_cast<void>(h); // unused
static_cast<void>(offset); // unused
static_cast<void>(flip); // unused
#endif
}
@ -340,10 +311,11 @@ public:
#ifdef TRACY_ON_DEMAND
if( !GetProfiler().IsConnected() ) return;
#endif
TracyLfqPrepare( QueueType::PlotDataInt );
MemWrite( &item->plotDataInt.name, (uint64_t)name );
MemWrite( &item->plotDataInt.time, GetTime() );
MemWrite( &item->plotDataInt.val, val );
TracyLfqPrepare( QueueType::PlotData );
MemWrite( &item->plotData.name, (uint64_t)name );
MemWrite( &item->plotData.time, GetTime() );
MemWrite( &item->plotData.type, PlotDataType::Int );
MemWrite( &item->plotData.data.i, val );
TracyLfqCommit;
}
@ -352,10 +324,11 @@ public:
#ifdef TRACY_ON_DEMAND
if( !GetProfiler().IsConnected() ) return;
#endif
TracyLfqPrepare( QueueType::PlotDataFloat );
MemWrite( &item->plotDataFloat.name, (uint64_t)name );
MemWrite( &item->plotDataFloat.time, GetTime() );
MemWrite( &item->plotDataFloat.val, val );
TracyLfqPrepare( QueueType::PlotData );
MemWrite( &item->plotData.name, (uint64_t)name );
MemWrite( &item->plotData.time, GetTime() );
MemWrite( &item->plotData.type, PlotDataType::Float );
MemWrite( &item->plotData.data.f, val );
TracyLfqCommit;
}
@ -364,21 +337,19 @@ public:
#ifdef TRACY_ON_DEMAND
if( !GetProfiler().IsConnected() ) return;
#endif
TracyLfqPrepare( QueueType::PlotDataDouble );
MemWrite( &item->plotDataDouble.name, (uint64_t)name );
MemWrite( &item->plotDataDouble.time, GetTime() );
MemWrite( &item->plotDataDouble.val, val );
TracyLfqPrepare( QueueType::PlotData );
MemWrite( &item->plotData.name, (uint64_t)name );
MemWrite( &item->plotData.time, GetTime() );
MemWrite( &item->plotData.type, PlotDataType::Double );
MemWrite( &item->plotData.data.d, val );
TracyLfqCommit;
}
static tracy_force_inline void ConfigurePlot( const char* name, PlotFormatType type, bool step, bool fill, uint32_t color )
static tracy_force_inline void ConfigurePlot( const char* name, PlotFormatType type )
{
TracyLfqPrepare( QueueType::PlotConfig );
MemWrite( &item->plotConfig.name, (uint64_t)name );
MemWrite( &item->plotConfig.type, (uint8_t)type );
MemWrite( &item->plotConfig.step, (uint8_t)step );
MemWrite( &item->plotConfig.fill, (uint8_t)fill );
MemWrite( &item->plotConfig.color, color );
#ifdef TRACY_ON_DEMAND
GetProfiler().DeferItem( *item );
@ -387,89 +358,89 @@ public:
TracyLfqCommit;
}
static tracy_force_inline void Message( const char* txt, size_t size, int32_t callstack_depth )
static tracy_force_inline void Message( const char* txt, size_t size, int callstack )
{
assert( size < (std::numeric_limits<uint16_t>::max)() );
assert( size < std::numeric_limits<uint16_t>::max() );
#ifdef TRACY_ON_DEMAND
if( !GetProfiler().IsConnected() ) return;
#endif
if( callstack_depth != 0 && has_callstack() )
if( callstack != 0 )
{
tracy::GetProfiler().SendCallstack( callstack_depth );
tracy::GetProfiler().SendCallstack( callstack );
}
auto ptr = (char*)tracy_malloc( size );
memcpy( ptr, txt, size );
TracyQueuePrepare( callstack_depth == 0 ? QueueType::Message : QueueType::MessageCallstack );
TracyQueuePrepare( callstack == 0 ? QueueType::Message : QueueType::MessageCallstack );
MemWrite( &item->messageFat.time, GetTime() );
MemWrite( &item->messageFat.text, (uint64_t)ptr );
MemWrite( &item->messageFat.size, (uint16_t)size );
TracyQueueCommit( messageFatThread );
}
static tracy_force_inline void Message( const char* txt, int32_t callstack_depth )
static tracy_force_inline void Message( const char* txt, int callstack )
{
#ifdef TRACY_ON_DEMAND
if( !GetProfiler().IsConnected() ) return;
#endif
if( callstack_depth != 0 && has_callstack() )
if( callstack != 0 )
{
tracy::GetProfiler().SendCallstack( callstack_depth );
tracy::GetProfiler().SendCallstack( callstack );
}
TracyQueuePrepare( callstack_depth == 0 ? QueueType::MessageLiteral : QueueType::MessageLiteralCallstack );
TracyQueuePrepare( callstack == 0 ? QueueType::MessageLiteral : QueueType::MessageLiteralCallstack );
MemWrite( &item->messageLiteral.time, GetTime() );
MemWrite( &item->messageLiteral.text, (uint64_t)txt );
TracyQueueCommit( messageLiteralThread );
}
static tracy_force_inline void MessageColor( const char* txt, size_t size, uint32_t color, int32_t callstack_depth )
static tracy_force_inline void MessageColor( const char* txt, size_t size, uint32_t color, int callstack )
{
assert( size < (std::numeric_limits<uint16_t>::max)() );
assert( size < std::numeric_limits<uint16_t>::max() );
#ifdef TRACY_ON_DEMAND
if( !GetProfiler().IsConnected() ) return;
#endif
if( callstack_depth != 0 && has_callstack() )
if( callstack != 0 )
{
tracy::GetProfiler().SendCallstack( callstack_depth );
tracy::GetProfiler().SendCallstack( callstack );
}
auto ptr = (char*)tracy_malloc( size );
memcpy( ptr, txt, size );
TracyQueuePrepare( callstack_depth == 0 ? QueueType::MessageColor : QueueType::MessageColorCallstack );
TracyQueuePrepare( callstack == 0 ? QueueType::MessageColor : QueueType::MessageColorCallstack );
MemWrite( &item->messageColorFat.time, GetTime() );
MemWrite( &item->messageColorFat.text, (uint64_t)ptr );
MemWrite( &item->messageColorFat.b, uint8_t( ( color ) & 0xFF ) );
MemWrite( &item->messageColorFat.r, uint8_t( ( color ) & 0xFF ) );
MemWrite( &item->messageColorFat.g, uint8_t( ( color >> 8 ) & 0xFF ) );
MemWrite( &item->messageColorFat.r, uint8_t( ( color >> 16 ) & 0xFF ) );
MemWrite( &item->messageColorFat.b, uint8_t( ( color >> 16 ) & 0xFF ) );
MemWrite( &item->messageColorFat.size, (uint16_t)size );
TracyQueueCommit( messageColorFatThread );
}
static tracy_force_inline void MessageColor( const char* txt, uint32_t color, int32_t callstack_depth )
static tracy_force_inline void MessageColor( const char* txt, uint32_t color, int callstack )
{
#ifdef TRACY_ON_DEMAND
if( !GetProfiler().IsConnected() ) return;
#endif
if( callstack_depth != 0 && has_callstack() )
if( callstack != 0 )
{
tracy::GetProfiler().SendCallstack( callstack_depth );
tracy::GetProfiler().SendCallstack( callstack );
}
TracyQueuePrepare( callstack_depth == 0 ? QueueType::MessageLiteralColor : QueueType::MessageLiteralColorCallstack );
TracyQueuePrepare( callstack == 0 ? QueueType::MessageLiteralColor : QueueType::MessageLiteralColorCallstack );
MemWrite( &item->messageColorLiteral.time, GetTime() );
MemWrite( &item->messageColorLiteral.text, (uint64_t)txt );
MemWrite( &item->messageColorLiteral.b, uint8_t( ( color ) & 0xFF ) );
MemWrite( &item->messageColorLiteral.r, uint8_t( ( color ) & 0xFF ) );
MemWrite( &item->messageColorLiteral.g, uint8_t( ( color >> 8 ) & 0xFF ) );
MemWrite( &item->messageColorLiteral.r, uint8_t( ( color >> 16 ) & 0xFF ) );
MemWrite( &item->messageColorLiteral.b, uint8_t( ( color >> 16 ) & 0xFF ) );
TracyQueueCommit( messageColorLiteralThread );
}
static tracy_force_inline void MessageAppInfo( const char* txt, size_t size )
{
assert( size < (std::numeric_limits<uint16_t>::max)() );
assert( size < std::numeric_limits<uint16_t>::max() );
auto ptr = (char*)tracy_malloc( size );
memcpy( ptr, txt, size );
TracyLfqPrepare( QueueType::MessageAppInfo );
@ -510,31 +481,29 @@ public:
GetProfiler().m_serialLock.unlock();
}
static tracy_force_inline void MemAllocCallstack( const void* ptr, size_t size, int32_t depth, bool secure )
static tracy_force_inline void MemAllocCallstack( const void* ptr, size_t size, int depth, bool secure )
{
if( secure && !ProfilerAvailable() ) return;
if( depth > 0 && has_callstack() )
{
auto& profiler = GetProfiler();
#ifdef TRACY_HAS_CALLSTACK
auto& profiler = GetProfiler();
# ifdef TRACY_ON_DEMAND
if( !profiler.IsConnected() ) return;
if( !profiler.IsConnected() ) return;
# endif
const auto thread = GetThreadHandle();
const auto thread = GetThreadHandle();
auto callstack = Callstack( depth );
auto callstack = Callstack( depth );
profiler.m_serialLock.lock();
SendCallstackSerial( callstack );
SendMemAlloc( QueueType::MemAllocCallstack, thread, ptr, size );
profiler.m_serialLock.unlock();
}
else
{
MemAlloc( ptr, size, secure );
}
profiler.m_serialLock.lock();
SendCallstackSerial( callstack );
SendMemAlloc( QueueType::MemAllocCallstack, thread, ptr, size );
profiler.m_serialLock.unlock();
#else
static_cast<void>(depth); // unused
MemAlloc( ptr, size, secure );
#endif
}
static tracy_force_inline void MemFreeCallstack( const void* ptr, int32_t depth, bool secure )
static tracy_force_inline void MemFreeCallstack( const void* ptr, int depth, bool secure )
{
if( secure && !ProfilerAvailable() ) return;
if( !ProfilerAllocatorAvailable() )
@ -542,25 +511,23 @@ public:
MemFree( ptr, secure );
return;
}
if( depth > 0 && has_callstack() )
{
auto& profiler = GetProfiler();
#ifdef TRACY_HAS_CALLSTACK
auto& profiler = GetProfiler();
# ifdef TRACY_ON_DEMAND
if( !profiler.IsConnected() ) return;
if( !profiler.IsConnected() ) return;
# endif
const auto thread = GetThreadHandle();
const auto thread = GetThreadHandle();
auto callstack = Callstack( depth );
auto callstack = Callstack( depth );
profiler.m_serialLock.lock();
SendCallstackSerial( callstack );
SendMemFree( QueueType::MemFreeCallstack, thread, ptr );
profiler.m_serialLock.unlock();
}
else
{
MemFree( ptr, secure );
}
profiler.m_serialLock.lock();
SendCallstackSerial( callstack );
SendMemFree( QueueType::MemFreeCallstack, thread, ptr );
profiler.m_serialLock.unlock();
#else
static_cast<void>(depth); // unused
MemFree( ptr, secure );
#endif
}
static tracy_force_inline void MemAllocNamed( const void* ptr, size_t size, bool secure, const char* name )
@ -591,110 +558,67 @@ public:
GetProfiler().m_serialLock.unlock();
}
static tracy_force_inline void MemAllocCallstackNamed( const void* ptr, size_t size, int32_t depth, bool secure, const char* name )
static tracy_force_inline void MemAllocCallstackNamed( const void* ptr, size_t size, int depth, bool secure, const char* name )
{
if( secure && !ProfilerAvailable() ) return;
if( depth > 0 && has_callstack() )
{
auto& profiler = GetProfiler();
#ifdef TRACY_HAS_CALLSTACK
auto& profiler = GetProfiler();
# ifdef TRACY_ON_DEMAND
if( !profiler.IsConnected() ) return;
if( !profiler.IsConnected() ) return;
# endif
const auto thread = GetThreadHandle();
auto callstack = Callstack( depth );
profiler.m_serialLock.lock();
SendCallstackSerial( callstack );
SendMemName( name );
SendMemAlloc( QueueType::MemAllocCallstackNamed, thread, ptr, size );
profiler.m_serialLock.unlock();
}
else
{
MemAllocNamed( ptr, size, secure, name );
}
}
static tracy_force_inline void MemFreeCallstackNamed( const void* ptr, int32_t depth, bool secure, const char* name )
{
if( secure && !ProfilerAvailable() ) return;
if( depth > 0 && has_callstack() )
{
auto& profiler = GetProfiler();
# ifdef TRACY_ON_DEMAND
if( !profiler.IsConnected() ) return;
# endif
const auto thread = GetThreadHandle();
auto callstack = Callstack( depth );
profiler.m_serialLock.lock();
SendCallstackSerial( callstack );
SendMemName( name );
SendMemFree( QueueType::MemFreeCallstackNamed, thread, ptr );
profiler.m_serialLock.unlock();
}
else
{
MemFreeNamed( ptr, secure, name );
}
}
static tracy_force_inline void MemDiscard( const char* name, bool secure )
{
if( secure && !ProfilerAvailable() ) return;
#ifdef TRACY_ON_DEMAND
if( !GetProfiler().IsConnected() ) return;
#endif
const auto thread = GetThreadHandle();
GetProfiler().m_serialLock.lock();
SendMemDiscard( QueueType::MemDiscard, thread, name );
GetProfiler().m_serialLock.unlock();
auto callstack = Callstack( depth );
profiler.m_serialLock.lock();
SendCallstackSerial( callstack );
SendMemName( name );
SendMemAlloc( QueueType::MemAllocCallstackNamed, thread, ptr, size );
profiler.m_serialLock.unlock();
#else
static_cast<void>(depth); // unused
static_cast<void>(name); // unused
MemAlloc( ptr, size, secure );
#endif
}
static tracy_force_inline void MemDiscardCallstack( const char* name, bool secure, int32_t depth )
static tracy_force_inline void MemFreeCallstackNamed( const void* ptr, int depth, bool secure, const char* name )
{
if( secure && !ProfilerAvailable() ) return;
if( depth > 0 && has_callstack() )
{
# ifdef TRACY_ON_DEMAND
if( !GetProfiler().IsConnected() ) return;
# endif
const auto thread = GetThreadHandle();
auto callstack = Callstack( depth );
GetProfiler().m_serialLock.lock();
SendCallstackSerial( callstack );
SendMemDiscard( QueueType::MemDiscard, thread, name );
GetProfiler().m_serialLock.unlock();
}
else
{
MemDiscard( name, secure );
}
}
static tracy_force_inline void SendCallstack( int32_t depth )
{
if( depth > 0 && has_callstack() )
{
auto ptr = Callstack( depth );
TracyQueuePrepare( QueueType::Callstack );
MemWrite( &item->callstackFat.ptr, (uint64_t)ptr );
TracyQueueCommit( callstackFatThread );
}
}
static tracy_force_inline void ParameterRegister( ParameterCallback cb, void* data )
{
#ifdef TRACY_HAS_CALLSTACK
auto& profiler = GetProfiler();
profiler.m_paramCallback = cb;
profiler.m_paramCallbackData = data;
# ifdef TRACY_ON_DEMAND
if( !profiler.IsConnected() ) return;
# endif
const auto thread = GetThreadHandle();
auto callstack = Callstack( depth );
profiler.m_serialLock.lock();
SendCallstackSerial( callstack );
SendMemName( name );
SendMemFree( QueueType::MemFreeCallstackNamed, thread, ptr );
profiler.m_serialLock.unlock();
#else
static_cast<void>(depth); // unused
static_cast<void>(name); // unused
MemFree( ptr, secure );
#endif
}
static tracy_force_inline void SendCallstack( int depth )
{
#ifdef TRACY_HAS_CALLSTACK
auto ptr = Callstack( depth );
TracyQueuePrepare( QueueType::Callstack );
MemWrite( &item->callstackFat.ptr, (uint64_t)ptr );
TracyQueueCommit( callstackFatThread );
#else
static_cast<void>(depth); // unused
#endif
}
static tracy_force_inline void ParameterRegister( ParameterCallback cb ) { GetProfiler().m_paramCallback = cb; }
static tracy_force_inline void ParameterSetup( uint32_t idx, const char* name, bool isBool, int32_t val )
{
TracyLfqPrepare( QueueType::ParamSetup );
@ -710,20 +634,12 @@ public:
TracyLfqCommit;
}
static tracy_force_inline void SourceCallbackRegister( SourceContentsCallback cb, void* data )
{
auto& profiler = GetProfiler();
profiler.m_sourceCallback = cb;
profiler.m_sourceCallbackData = data;
}
#ifdef TRACY_FIBERS
static tracy_force_inline void EnterFiber( const char* fiber, int32_t groupHint )
static tracy_force_inline void EnterFiber( const char* fiber )
{
TracyQueuePrepare( QueueType::FiberEnter );
MemWrite( &item->fiberEnter.time, GetTime() );
MemWrite( &item->fiberEnter.fiber, (uint64_t)fiber );
MemWrite( &item->fiberEnter.groupHint, groupHint );
TracyQueueCommit( fiberEnter );
}
@ -735,7 +651,7 @@ public:
}
#endif
void SendCallstack( int32_t depth, const char* skipBefore );
void SendCallstack( int depth, const char* skipBefore );
static void CutCallstack( void* callstack, const char* skipBefore );
static bool ShouldExit();
@ -745,13 +661,6 @@ public:
return m_isConnected.load( std::memory_order_acquire );
}
tracy_force_inline void SetProgramName( const char* name )
{
m_programNameLock.lock();
m_programName = name;
m_programNameLock.unlock();
}
#ifdef TRACY_ON_DEMAND
tracy_force_inline uint64_t ConnectionId() const
{
@ -788,29 +697,29 @@ public:
// 1b null terminator
// nsz zone name (optional)
static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, const char* function, uint32_t color = 0 )
static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, const char* function )
{
return AllocSourceLocation( line, source, function, nullptr, 0, color );
return AllocSourceLocation( line, source, function, nullptr, 0 );
}
static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, const char* function, const char* name, size_t nameSz, uint32_t color = 0 )
static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, const char* function, const char* name, size_t nameSz )
{
return AllocSourceLocation( line, source, strlen(source), function, strlen(function), name, nameSz, color );
return AllocSourceLocation( line, source, strlen(source), function, strlen(function), name, nameSz );
}
static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, uint32_t color = 0 )
static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz )
{
return AllocSourceLocation( line, source, sourceSz, function, functionSz, nullptr, 0, color );
return AllocSourceLocation( line, source, sourceSz, function, functionSz, nullptr, 0 );
}
static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, uint32_t color = 0 )
static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz )
{
const auto sz32 = uint32_t( 2 + 4 + 4 + functionSz + 1 + sourceSz + 1 + nameSz );
assert( sz32 <= (std::numeric_limits<uint16_t>::max)() );
assert( sz32 <= std::numeric_limits<uint16_t>::max() );
const auto sz = uint16_t( sz32 );
auto ptr = (char*)tracy_malloc( sz );
memcpy( ptr, &sz, 2 );
memcpy( ptr + 2, &color, 4 );
memset( ptr + 2, 0, 4 );
memcpy( ptr + 6, &line, 4 );
memcpy( ptr + 10, function, functionSz );
ptr[10 + functionSz] = '\0';
@ -841,9 +750,6 @@ private:
void HandleSymbolQueueItem( const SymbolQueueItem& si );
#endif
void InstallCrashHandler();
void RemoveCrashHandler();
void ClearQueues( tracy::moodycamel::ConsumerToken& token );
void ClearSerial();
DequeueStatus Dequeue( tracy::moodycamel::ConsumerToken& token );
@ -876,21 +782,6 @@ private:
m_bufferOffset += int( len );
}
char* SafeCopyProlog( const char* p, size_t size );
void SafeCopyEpilog( char* buf );
template<class Callable> // must be void( const char* buf, size_t size )
bool WithSafeCopy( const char* p, size_t size, Callable&& callable )
{
if( char* buf = SafeCopyProlog( p, size ) )
{
callable( buf, size );
SafeCopyEpilog( buf );
return true;
}
return false;
}
bool SendData( const char* data, size_t len );
void SendLongString( uint64_t ptr, const char* str, size_t len, QueueType type );
void SendSourceLocation( uint64_t ptr );
@ -901,17 +792,18 @@ private:
void QueueCallstackFrame( uint64_t ptr );
void QueueSymbolQuery( uint64_t symbol );
void QueueCodeLocation( uint64_t ptr );
void QueueExternalName( uint64_t ptr );
void QueueKernelCode( uint64_t symbol, uint32_t size );
void QueueSourceCodeQuery( uint32_t id );
bool HandleServerQuery();
void HandleDisconnect();
void HandleParameter( uint64_t payload );
void HandleSymbolCodeQuery( uint64_t symbol, uint32_t size );
void HandleSourceCodeQuery( char* data, char* image, uint32_t id );
void HandleSourceCodeQuery();
void AckServerQuery();
void AckSourceCodeNotAvailable();
void AckSymbolCodeNotAvailable();
void CalibrateTimer();
@ -920,13 +812,14 @@ private:
static tracy_force_inline void SendCallstackSerial( void* ptr )
{
if( has_callstack() )
{
auto item = GetProfiler().m_serialQueue.prepare_next();
MemWrite( &item->hdr.type, QueueType::CallstackSerial );
MemWrite( &item->callstackFat.ptr, (uint64_t)ptr );
GetProfiler().m_serialQueue.commit_next();
}
#ifdef TRACY_HAS_CALLSTACK
auto item = GetProfiler().m_serialQueue.prepare_next();
MemWrite( &item->hdr.type, QueueType::CallstackSerial );
MemWrite( &item->callstackFat.ptr, (uint64_t)ptr );
GetProfiler().m_serialQueue.commit_next();
#else
static_cast<void>(ptr); // unused
#endif
}
static tracy_force_inline void SendMemAlloc( QueueType type, const uint32_t thread, const void* ptr, size_t size )
@ -964,18 +857,6 @@ private:
GetProfiler().m_serialQueue.commit_next();
}
static tracy_force_inline void SendMemDiscard( QueueType type, const uint32_t thread, const char* name )
{
assert( type == QueueType::MemDiscard || type == QueueType::MemDiscardCallstack );
auto item = GetProfiler().m_serialQueue.prepare_next();
MemWrite( &item->hdr.type, type );
MemWrite( &item->memDiscard.time, GetTime() );
MemWrite( &item->memDiscard.thread, thread );
MemWrite( &item->memDiscard.name, (uint64_t)name );
GetProfiler().m_serialQueue.commit_next();
}
static tracy_force_inline void SendMemName( const char* name )
{
assert( name );
@ -1046,42 +927,21 @@ private:
void ProcessSysTime() {}
#endif
#ifdef TRACY_HAS_SYSPOWER
SysPower m_sysPower;
#endif
ParameterCallback m_paramCallback;
void* m_paramCallbackData;
SourceContentsCallback m_sourceCallback;
void* m_sourceCallbackData;
char* m_queryImage;
char* m_queryData;
char* m_queryDataPtr;
#ifndef NDEBUG
// m_safeSendBuffer and m_pipe should only be used by the Tracy Profiler thread; this ensures that in debug builds.
std::atomic_bool m_inUse{ false };
#endif
char* m_safeSendBuffer;
#if defined _WIN32
void* m_prevHandler;
#else
int m_pipe[2];
int m_pipeBufSize;
void* m_exceptionHandler;
#endif
#ifdef __linux__
struct {
struct sigaction pwr, ill, fpe, segv, pipe, bus, abrt;
} m_prevSignal;
KCore* m_kcore;
#endif
bool m_crashHandlerInstalled;
const char* m_programName;
TracyMutex m_programNameLock;
};
}

View File

@ -2,7 +2,6 @@
#define __TRACYSCOPED_HPP__
#include <limits>
#include <stdarg.h>
#include <stdint.h>
#include <string.h>
@ -10,7 +9,6 @@
#include "../common/TracyAlign.hpp"
#include "../common/TracyAlloc.hpp"
#include "TracyProfiler.hpp"
#include "TracyCallstack.hpp"
namespace tracy
{
@ -23,7 +21,7 @@ public:
ScopedZone& operator=( const ScopedZone& ) = delete;
ScopedZone& operator=( ScopedZone&& ) = delete;
tracy_force_inline ScopedZone( const SourceLocationData* srcloc, int32_t depth = -1, bool is_active = true )
tracy_force_inline ScopedZone( const SourceLocationData* srcloc, bool is_active = true )
#ifdef TRACY_ON_DEMAND
: m_active( is_active && GetProfiler().IsConnected() )
#else
@ -34,19 +32,13 @@ public:
#ifdef TRACY_ON_DEMAND
m_connectionId = GetProfiler().ConnectionId();
#endif
auto zoneQueue = QueueType::ZoneBegin;
if( depth > 0 && has_callstack() )
{
GetProfiler().SendCallstack( depth );
zoneQueue = QueueType::ZoneBeginCallstack;
}
TracyQueuePrepare( zoneQueue );
TracyQueuePrepare( QueueType::ZoneBegin );
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, uint32_t color, int32_t depth = -1, bool is_active = true )
tracy_force_inline ScopedZone( const SourceLocationData* srcloc, int depth, bool is_active = true )
#ifdef TRACY_ON_DEMAND
: m_active( is_active && GetProfiler().IsConnected() )
#else
@ -57,21 +49,51 @@ public:
#ifdef TRACY_ON_DEMAND
m_connectionId = GetProfiler().ConnectionId();
#endif
auto zoneQueue = QueueType::ZoneBeginAllocSrcLoc;
if( depth > 0 && has_callstack() )
{
GetProfiler().SendCallstack( depth );
zoneQueue = QueueType::ZoneBeginAllocSrcLocCallstack;
}
TracyQueuePrepare( zoneQueue );
const auto srcloc =
Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz, color );
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, int32_t depth, bool is_active = true ) : ScopedZone( line, source, sourceSz, function, functionSz, name, nameSz, 0, depth, is_active ) {}
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()
{
@ -86,7 +108,7 @@ public:
tracy_force_inline void Text( const char* txt, size_t size )
{
assert( size < (std::numeric_limits<uint16_t>::max)() );
assert( size < std::numeric_limits<uint16_t>::max() );
if( !m_active ) return;
#ifdef TRACY_ON_DEMAND
if( GetProfiler().ConnectionId() != m_connectionId ) return;
@ -99,33 +121,9 @@ public:
TracyQueueCommit( zoneTextFatThread );
}
void TextFmt( const char* fmt, ... )
{
if( !m_active ) return;
#ifdef TRACY_ON_DEMAND
if( GetProfiler().ConnectionId() != m_connectionId ) return;
#endif
va_list args;
va_start( args, fmt );
auto size = vsnprintf( nullptr, 0, fmt, args );
va_end( args );
if( size < 0 ) return;
assert( size < (std::numeric_limits<uint16_t>::max)() );
char* ptr = (char*)tracy_malloc( size_t( size ) + 1 );
va_start( args, fmt );
vsnprintf( ptr, size_t( size ) + 1, fmt, args );
va_end( args );
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)() );
assert( size < std::numeric_limits<uint16_t>::max() );
if( !m_active ) return;
#ifdef TRACY_ON_DEMAND
if( GetProfiler().ConnectionId() != m_connectionId ) return;
@ -138,30 +136,6 @@ public:
TracyQueueCommit( zoneTextFatThread );
}
void NameFmt( const char* fmt, ... )
{
if( !m_active ) return;
#ifdef TRACY_ON_DEMAND
if( GetProfiler().ConnectionId() != m_connectionId ) return;
#endif
va_list args;
va_start( args, fmt );
auto size = vsnprintf( nullptr, 0, fmt, args );
va_end( args );
if( size < 0 ) return;
assert( size < (std::numeric_limits<uint16_t>::max)() );
char* ptr = (char*)tracy_malloc( size_t( size ) + 1 );
va_start( args, fmt );
vsnprintf( ptr, size_t( size ) + 1, fmt, args );
va_end( args );
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;
@ -169,9 +143,9 @@ public:
if( GetProfiler().ConnectionId() != m_connectionId ) return;
#endif
TracyQueuePrepare( QueueType::ZoneColor );
MemWrite( &item->zoneColor.b, uint8_t( ( color ) & 0xFF ) );
MemWrite( &item->zoneColor.r, uint8_t( ( color ) & 0xFF ) );
MemWrite( &item->zoneColor.g, uint8_t( ( color >> 8 ) & 0xFF ) );
MemWrite( &item->zoneColor.r, uint8_t( ( color >> 16 ) & 0xFF ) );
MemWrite( &item->zoneColor.b, uint8_t( ( color >> 16 ) & 0xFF ) );
TracyQueueCommit( zoneColorThread );
}
@ -192,7 +166,7 @@ private:
const bool m_active;
#ifdef TRACY_ON_DEMAND
uint64_t m_connectionId = 0;
uint64_t m_connectionId;
#endif
};

View File

@ -0,0 +1,50 @@
#ifndef __TRACYSTRINGHELPERS_HPP__
#define __TRACYSTRINGHELPERS_HPP__
#include <assert.h>
#include <string.h>
#include "../common/TracyAlloc.hpp"
namespace tracy
{
static inline char* CopyString( const char* src, size_t sz )
{
assert( strlen( src ) == sz );
auto dst = (char*)tracy_malloc( sz + 1 );
memcpy( dst, src, sz );
dst[sz] = '\0';
return dst;
}
static inline char* CopyString( const char* src )
{
const auto sz = strlen( src );
auto dst = (char*)tracy_malloc( sz + 1 );
memcpy( dst, src, sz );
dst[sz] = '\0';
return dst;
}
static inline char* CopyStringFast( const char* src, size_t sz )
{
assert( strlen( src ) == sz );
auto dst = (char*)tracy_malloc_fast( sz + 1 );
memcpy( dst, src, sz );
dst[sz] = '\0';
return dst;
}
static inline char* CopyStringFast( const char* src )
{
const auto sz = strlen( src );
auto dst = (char*)tracy_malloc_fast( sz + 1 );
memcpy( dst, src, sz );
dst[sz] = '\0';
return dst;
}
}
#endif

View File

@ -16,25 +16,16 @@
namespace tracy
{
static int GetSamplingFrequency()
static constexpr int GetSamplingFrequency()
{
int samplingHz = TRACY_SAMPLING_HZ;
auto env = GetEnvVar( "TRACY_SAMPLING_HZ" );
if( env )
{
int val = atoi( env );
if( val > 0 ) samplingHz = val;
}
#if defined _WIN32
return samplingHz > 8000 ? 8000 : ( samplingHz < 1 ? 1 : samplingHz );
return TRACY_SAMPLING_HZ > 8000 ? 8000 : ( TRACY_SAMPLING_HZ < 1 ? 1 : TRACY_SAMPLING_HZ );
#else
return samplingHz > 1000000 ? 1000000 : ( samplingHz < 1 ? 1 : samplingHz );
return TRACY_SAMPLING_HZ > 1000000 ? 1000000 : ( TRACY_SAMPLING_HZ < 1 ? 1 : TRACY_SAMPLING_HZ );
#endif
}
static int GetSamplingPeriod()
static constexpr int GetSamplingPeriod()
{
return 1000000000 / GetSamplingFrequency();
}
@ -225,6 +216,20 @@ void WINAPI EventRecordCallback( PEVENT_RECORD record )
}
}
static constexpr const char* VsyncName[] = {
"[0] Vsync",
"[1] Vsync",
"[2] Vsync",
"[3] Vsync",
"[4] Vsync",
"[5] Vsync",
"[6] Vsync",
"[7] Vsync",
"Vsync"
};
static uint32_t VsyncTarget[8] = {};
void WINAPI EventRecordCallbackVsync( PEVENT_RECORD record )
{
#ifdef TRACY_ON_DEMAND
@ -237,9 +242,24 @@ void WINAPI EventRecordCallbackVsync( PEVENT_RECORD record )
const auto vs = (const VSyncInfo*)record->UserData;
TracyLfqPrepare( QueueType::FrameVsync );
MemWrite( &item->frameVsync.time, hdr.TimeStamp.QuadPart );
MemWrite( &item->frameVsync.id, vs->vidPnTargetId );
int idx = 0;
do
{
if( VsyncTarget[idx] == 0 )
{
VsyncTarget[idx] = vs->vidPnTargetId;
break;
}
else if( VsyncTarget[idx] == vs->vidPnTargetId )
{
break;
}
}
while( ++idx < 8 );
TracyLfqPrepare( QueueType::FrameMarkMsg );
MemWrite( &item->frameMark.time, hdr.TimeStamp.QuadPart );
MemWrite( &item->frameMark.name, uint64_t( VsyncName[idx] ) );
TracyLfqCommit;
}
@ -330,7 +350,7 @@ static void SetupVsync()
#endif
}
static int GetSamplingInterval()
static constexpr int GetSamplingInterval()
{
return GetSamplingPeriod() / 100;
}
@ -418,7 +438,6 @@ bool SysTraceStart( int64_t& samplingPeriod )
return false;
}
#ifndef TRACY_NO_SAMPLING
if( isOs64Bit )
{
CLASSIC_EVENT_ID stackId[2] = {};
@ -433,7 +452,6 @@ bool SysTraceStart( int64_t& samplingPeriod )
return false;
}
}
#endif
#ifdef UNICODE
WCHAR KernelLoggerName[sizeof( KERNEL_LOGGER_NAME )];
@ -498,11 +516,11 @@ void SysTraceGetExternalName( uint64_t thread, const char*& threadName, const ch
if( _GetThreadDescription )
{
PWSTR tmp;
if ( SUCCEEDED( _GetThreadDescription( hnd, &tmp ) ) )
_GetThreadDescription( hnd, &tmp );
char buf[256];
if( tmp )
{
char buf[256];
auto ret = wcstombs( buf, tmp, 256 );
LocalFree(tmp);
if( ret != 0 )
{
threadName = CopyString( buf, ret );
@ -619,10 +637,6 @@ void SysTraceGetExternalName( uint64_t thread, const char*& threadName, const ch
# include <sys/ioctl.h>
# include <sys/syscall.h>
# if defined __i386 || defined __x86_64__
# include "TracyCpuid.hpp"
# endif
# include "TracyProfiler.hpp"
# include "TracyRingBuffer.hpp"
# include "TracyThread.hpp"
@ -676,7 +690,6 @@ enum TraceEventId
EventCacheMiss,
EventBranchRetired,
EventBranchMiss,
EventVsync,
EventContextSwitch,
EventWakeup,
};
@ -767,24 +780,13 @@ bool SysTraceStart( int64_t& samplingPeriod )
TracyDebug( "perf_event_paranoid: %i\n", paranoidLevel );
#endif
int switchId = -1, wakeupId = -1, vsyncId = -1;
int switchId = -1, wakeupId = -1;
const auto switchIdStr = ReadFile( "/sys/kernel/debug/tracing/events/sched/sched_switch/id" );
if( switchIdStr ) switchId = atoi( switchIdStr );
const auto wakeupIdStr = ReadFile( "/sys/kernel/debug/tracing/events/sched/sched_wakeup/id" );
if( wakeupIdStr ) wakeupId = atoi( wakeupIdStr );
const auto vsyncIdStr = ReadFile( "/sys/kernel/debug/tracing/events/drm/drm_vblank_event/id" );
if( vsyncIdStr ) vsyncId = atoi( vsyncIdStr );
TracyDebug( "sched_switch id: %i\n", switchId );
TracyDebug( "sched_wakeup id: %i\n", wakeupId );
TracyDebug( "drm_vblank_event id: %i\n", vsyncId );
#ifdef TRACY_NO_SAMPLING
const bool noSoftwareSampling = true;
#else
const char* noSoftwareSamplingEnv = GetEnvVar( "TRACY_NO_SAMPLING" );
const bool noSoftwareSampling = noSoftwareSamplingEnv && noSoftwareSamplingEnv[0] == '1';
#endif
TracyDebug( "sched_switch id: %i\nsched_wakeup id: %i\n", switchId, wakeupId );
#ifdef TRACY_NO_SAMPLE_RETIREMENT
const bool noRetirement = true;
@ -814,13 +816,6 @@ bool SysTraceStart( int64_t& samplingPeriod )
const bool noCtxSwitch = noCtxSwitchEnv && noCtxSwitchEnv[0] == '1';
#endif
#ifdef TRACY_NO_VSYNC_CAPTURE
const bool noVsync = true;
#else
const char* noVsyncEnv = GetEnvVar( "TRACY_NO_VSYNC_CAPTURE" );
const bool noVsync = noVsyncEnv && noVsyncEnv[0] == '1';
#endif
samplingPeriod = GetSamplingPeriod();
uint32_t currentPid = (uint32_t)getpid();
@ -831,8 +826,7 @@ bool SysTraceStart( int64_t& samplingPeriod )
2 + // CPU cycles + instructions retired
2 + // cache reference + miss
2 + // branch retired + miss
2 + // context switches + wakeups
1 // vsync
2 // context switches + wakeups
);
s_ring = (RingBuffer*)tracy_malloc( sizeof( RingBuffer ) * maxNumBuffers );
s_numBuffers = 0;
@ -855,31 +849,28 @@ bool SysTraceStart( int64_t& samplingPeriod )
pe.clockid = CLOCK_MONOTONIC_RAW;
#endif
if( !noSoftwareSampling )
TracyDebug( "Setup software sampling\n" );
ProbePreciseIp( pe, currentPid );
for( int i=0; i<s_numCpus; i++ )
{
TracyDebug( "Setup software sampling\n" );
ProbePreciseIp( pe, currentPid );
for( int i=0; i<s_numCpus; i++ )
int fd = perf_event_open( &pe, currentPid, i, -1, PERF_FLAG_FD_CLOEXEC );
if( fd == -1 )
{
int fd = perf_event_open( &pe, currentPid, i, -1, PERF_FLAG_FD_CLOEXEC );
pe.exclude_kernel = 1;
ProbePreciseIp( pe, currentPid );
fd = perf_event_open( &pe, currentPid, i, -1, PERF_FLAG_FD_CLOEXEC );
if( fd == -1 )
{
pe.exclude_kernel = 1;
ProbePreciseIp( pe, currentPid );
fd = perf_event_open( &pe, currentPid, i, -1, PERF_FLAG_FD_CLOEXEC );
if( fd == -1 )
{
TracyDebug( " Failed to setup!\n");
break;
}
TracyDebug( " No access to kernel samples\n" );
}
new( s_ring+s_numBuffers ) RingBuffer( 64*1024, fd, EventCallstack );
if( s_ring[s_numBuffers].IsValid() )
{
s_numBuffers++;
TracyDebug( " Core %i ok\n", i );
TracyDebug( " Failed to setup!\n");
break;
}
TracyDebug( " No access to kernel samples\n" );
}
new( s_ring+s_numBuffers ) RingBuffer( 64*1024, fd, EventCallstack );
if( s_ring[s_numBuffers].IsValid() )
{
s_numBuffers++;
TracyDebug( " Core %i ok\n", i );
}
}
@ -1011,37 +1002,6 @@ bool SysTraceStart( int64_t& samplingPeriod )
s_ctxBufferIdx = s_numBuffers;
// vsync
if( !noVsync && vsyncId != -1 )
{
pe = {};
pe.type = PERF_TYPE_TRACEPOINT;
pe.size = sizeof( perf_event_attr );
pe.sample_period = 1;
pe.sample_type = PERF_SAMPLE_TIME | PERF_SAMPLE_RAW;
pe.disabled = 1;
pe.config = vsyncId;
#if !defined TRACY_HW_TIMER || !( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 )
pe.use_clockid = 1;
pe.clockid = CLOCK_MONOTONIC_RAW;
#endif
TracyDebug( "Setup vsync capture\n" );
for( int i=0; i<s_numCpus; i++ )
{
const int fd = perf_event_open( &pe, -1, i, -1, PERF_FLAG_FD_CLOEXEC );
if( fd != -1 )
{
new( s_ring+s_numBuffers ) RingBuffer( 64*1024, fd, EventVsync, i );
if( s_ring[s_numBuffers].IsValid() )
{
s_numBuffers++;
TracyDebug( " Core %i ok\n", i );
}
}
}
}
// context switches
if( !noCtxSwitch && switchId != -1 )
{
@ -1153,19 +1113,16 @@ void SysTraceWorker( void* ptr )
InitRpmalloc();
sched_param sp = { 99 };
if( pthread_setschedparam( pthread_self(), SCHED_FIFO, &sp ) != 0 ) TracyDebug( "Failed to increase SysTraceWorker thread priority!\n" );
auto ctxBufferIdx = s_ctxBufferIdx;
auto ringArray = s_ring;
auto numBuffers = s_numBuffers;
for( int i=0; i<numBuffers; i++ ) ringArray[i].Enable();
for( int i=0; i<s_numBuffers; i++ ) s_ring[i].Enable();
for(;;)
{
#ifdef TRACY_ON_DEMAND
if( !GetProfiler().IsConnected() )
{
if( !traceActive.load( std::memory_order_relaxed ) ) break;
for( int i=0; i<numBuffers; i++ )
for( int i=0; i<s_numBuffers; i++ )
{
auto& ring = ringArray[i];
auto& ring = s_ring[i];
const auto head = ring.LoadHead();
const auto tail = ring.GetTail();
if( head != tail )
@ -1181,10 +1138,10 @@ void SysTraceWorker( void* ptr )
#endif
bool hadData = false;
for( int i=0; i<ctxBufferIdx; i++ )
for( int i=0; i<s_ctxBufferIdx; i++ )
{
if( !traceActive.load( std::memory_order_relaxed ) ) break;
auto& ring = ringArray[i];
auto& ring = s_ring[i];
const auto head = ring.LoadHead();
const auto tail = ring.GetTail();
if( head == tail ) continue;
@ -1284,7 +1241,8 @@ void SysTraceWorker( void* ptr )
type = QueueType::HwSampleBranchMiss;
break;
default:
abort();
assert( false );
break;
}
TracyLfqPrepare( type );
@ -1300,24 +1258,24 @@ void SysTraceWorker( void* ptr )
}
if( !traceActive.load( std::memory_order_relaxed ) ) break;
if( ctxBufferIdx != numBuffers )
if( s_ctxBufferIdx != s_numBuffers )
{
const auto ctxBufNum = numBuffers - ctxBufferIdx;
const auto ctxBufNum = s_numBuffers - s_ctxBufferIdx;
int activeNum = 0;
uint16_t active[512];
bool active[512];
uint32_t end[512];
uint32_t pos[512];
for( int i=0; i<ctxBufNum; i++ )
{
const auto rbIdx = ctxBufferIdx + i;
const auto rbHead = ringArray[rbIdx].LoadHead();
const auto rbTail = ringArray[rbIdx].GetTail();
const auto rbIdx = s_ctxBufferIdx + i;
const auto rbHead = s_ring[rbIdx].LoadHead();
const auto rbTail = s_ring[rbIdx].GetTail();
const auto rbActive = rbHead != rbTail;
active[i] = rbActive;
if( rbActive )
{
active[activeNum] = (uint16_t)i;
activeNum++;
end[i] = rbHead - rbTail;
pos[i] = 0;
@ -1333,45 +1291,42 @@ void SysTraceWorker( void* ptr )
while( activeNum > 0 )
{
int sel = -1;
int selPos;
int64_t t0 = std::numeric_limits<int64_t>::max();
for( int i=0; i<activeNum; i++ )
for( int i=0; i<ctxBufNum; i++ )
{
auto idx = active[i];
auto rbPos = pos[idx];
assert( rbPos < end[idx] );
const auto rbIdx = ctxBufferIdx + idx;
if( !active[i] ) continue;
auto rbPos = pos[i];
assert( rbPos < end[i] );
const auto rbIdx = s_ctxBufferIdx + i;
perf_event_header hdr;
ringArray[rbIdx].Read( &hdr, rbPos, sizeof( perf_event_header ) );
s_ring[rbIdx].Read( &hdr, rbPos, sizeof( perf_event_header ) );
if( hdr.type == PERF_RECORD_SAMPLE )
{
int64_t rbTime;
ringArray[rbIdx].Read( &rbTime, rbPos + sizeof( perf_event_header ), sizeof( int64_t ) );
s_ring[rbIdx].Read( &rbTime, rbPos + sizeof( perf_event_header ), sizeof( int64_t ) );
if( rbTime < t0 )
{
t0 = rbTime;
sel = idx;
selPos = i;
sel = i;
}
}
else
{
rbPos += hdr.size;
if( rbPos == end[idx] )
if( rbPos == end[i] )
{
memmove( active+i, active+i+1, sizeof(*active) * ( activeNum - i - 1 ) );
active[i] = false;
activeNum--;
i--;
}
else
{
pos[idx] = rbPos;
pos[i] = rbPos;
}
}
}
if( sel >= 0 )
{
auto& ring = ringArray[ctxBufferIdx + sel];
auto& ring = s_ring[s_ctxBufferIdx + sel];
auto rbPos = pos[sel];
auto offset = rbPos;
perf_event_header hdr;
@ -1381,8 +1336,7 @@ void SysTraceWorker( void* ptr )
t0 = ring.ConvertTimeToTsc( t0 );
#endif
const auto rid = ring.GetId();
if( rid == EventContextSwitch )
if( ring.GetId() == EventContextSwitch )
{
// Layout:
// u64 time
@ -1450,8 +1404,10 @@ void SysTraceWorker( void* ptr )
TracyLfqCommit;
}
}
else if( rid == EventWakeup )
else
{
assert( ring.GetId() == EventWakeup );
// Layout:
// u64 time
// u32 size
@ -1473,45 +1429,11 @@ void SysTraceWorker( void* ptr )
MemWrite( &item->threadWakeup.thread, pid );
TracyLfqCommit;
}
else
{
assert( rid == EventVsync );
// Layout:
// u64 time
// u32 size
// u8 data[size]
// Data (not ABI stable):
// u8 hdr[8]
// i32 crtc
// u32 seq
// i64 ktime
// u8 high precision
offset += sizeof( perf_event_header ) + sizeof( uint64_t ) + sizeof( uint32_t ) + 8;
int32_t crtc;
ring.Read( &crtc, offset, sizeof( int32_t ) );
// Note: The timestamp value t0 might be off by a number of microseconds from the
// true hardware vblank event. The ktime value should be used instead, but it is
// measured in CLOCK_MONOTONIC time. Tracy only supports the timestamp counter
// register (TSC) or CLOCK_MONOTONIC_RAW clock.
#if 0
offset += sizeof( uint32_t ) * 2;
int64_t ktime;
ring.Read( &ktime, offset, sizeof( int64_t ) );
#endif
TracyLfqPrepare( QueueType::FrameVsync );
MemWrite( &item->frameVsync.id, crtc );
MemWrite( &item->frameVsync.time, t0 );
TracyLfqCommit;
}
rbPos += hdr.size;
if( rbPos == end[sel] )
{
memmove( active+selPos, active+selPos+1, sizeof(*active) * ( activeNum - selPos - 1 ) );
active[sel] = false;
activeNum--;
}
else
@ -1522,7 +1444,7 @@ void SysTraceWorker( void* ptr )
}
for( int i=0; i<ctxBufNum; i++ )
{
if( end[i] != 0 ) ringArray[ctxBufferIdx + i].Advance( end[i] );
if( end[i] != 0 ) s_ring[s_ctxBufferIdx + i].Advance( end[i] );
}
}
}
@ -1533,8 +1455,8 @@ void SysTraceWorker( void* ptr )
}
}
for( int i=0; i<numBuffers; i++ ) ringArray[i].~RingBuffer();
tracy_free_fast( ringArray );
for( int i=0; i<s_numBuffers; i++ ) s_ring[i].~RingBuffer();
tracy_free_fast( s_ring );
}
void SysTraceGetExternalName( uint64_t thread, const char*& threadName, const char*& name )

View File

@ -24,7 +24,7 @@ public:
~ThreadExitHandler()
{
#ifdef TRACY_MANUAL_LIFETIME
rpmalloc_thread_finalize( 1 );
rpmalloc_thread_finalize();
RpThreadInitDone = false;
#endif
}

View File

@ -210,14 +210,19 @@ namespace details
}
};
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4554)
#endif
template<typename T>
static inline bool circular_less_than(T a, T b)
{
static_assert(std::is_integral<T>::value && !std::numeric_limits<T>::is_signed, "circular_less_than is intended to be used only with unsigned integer types");
return static_cast<T>(a - b) > static_cast<T>(static_cast<T>(1) << (static_cast<T>(sizeof(T) * CHAR_BIT - 1)));
// Note: extra parens around rhs of operator<< is MSVC bug: https://developercommunity2.visualstudio.com/t/C4554-triggers-when-both-lhs-and-rhs-is/10034931
// silencing the bug requires #pragma warning(disable: 4554) around the calling code and has no effect when done here.
return static_cast<T>(a - b) > (static_cast<T>(static_cast<T>(1) << static_cast<T>(sizeof(T) * CHAR_BIT - 1)));
}
#ifdef _MSC_VER
#pragma warning(pop)
#endif
template<typename U>
static inline char* align_for(char* ptr)

2500
client/tracy_rpmalloc.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -20,12 +20,11 @@ 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_MALLOC __attribute__((__malloc__))
# if defined(__clang_major__) && (__clang_major__ < 4)
# 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
@ -46,24 +45,13 @@ namespace tracy
# 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
//! Define RPMALLOC_CONFIGURABLE to enable configuring sizes
#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)
@ -111,7 +99,7 @@ typedef struct rpmalloc_thread_statistics_t {
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];
} span_use[32];
//! Per size class statistics (only if ENABLE_STATISTICS=1)
struct {
//! Current number of allocations
@ -143,8 +131,7 @@ typedef struct rpmalloc_config_t {
// 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.
// be used for both.
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
@ -152,18 +139,8 @@ typedef struct rpmalloc_config_t {
// 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.
// else the default implementation will be used for both.
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.
@ -186,10 +163,6 @@ typedef struct rpmalloc_config_t {
// 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
@ -214,7 +187,7 @@ rpmalloc_thread_initialize(void);
//! Finalize allocator for calling thread
TRACY_API void
rpmalloc_thread_finalize(int release_caches);
rpmalloc_thread_finalize(void);
//! Perform deferred deallocations pending for the calling thread heap
RPMALLOC_EXPORT void
@ -267,13 +240,6 @@ rpaligned_realloc(void* ptr, size_t alignment, size_t size, size_t oldsize, unsi
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
@ -286,78 +252,10 @@ rpmemalign(size_t alignment, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB
// 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);
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
}

File diff suppressed because it is too large Load Diff

View File

@ -1,300 +0,0 @@
#.rst:
# ECMFindModuleHelpers
# --------------------
#
# Helper macros for find modules: ecm_find_package_version_check(),
# ecm_find_package_parse_components() and
# ecm_find_package_handle_library_components().
#
# ::
#
# ecm_find_package_version_check(<name>)
#
# Prints warnings if the CMake version or the project's required CMake version
# is older than that required by extra-cmake-modules.
#
# ::
#
# ecm_find_package_parse_components(<name>
# RESULT_VAR <variable>
# KNOWN_COMPONENTS <component1> [<component2> [...]]
# [SKIP_DEPENDENCY_HANDLING])
#
# This macro will populate <variable> with a list of components found in
# <name>_FIND_COMPONENTS, after checking that all those components are in the
# list of KNOWN_COMPONENTS; if there are any unknown components, it will print
# an error or warning (depending on the value of <name>_FIND_REQUIRED) and call
# return().
#
# The order of components in <variable> is guaranteed to match the order they
# are listed in the KNOWN_COMPONENTS argument.
#
# If SKIP_DEPENDENCY_HANDLING is not set, for each component the variable
# <name>_<component>_component_deps will be checked for dependent components.
# If <component> is listed in <name>_FIND_COMPONENTS, then all its (transitive)
# dependencies will also be added to <variable>.
#
# ::
#
# ecm_find_package_handle_library_components(<name>
# COMPONENTS <component> [<component> [...]]
# [SKIP_DEPENDENCY_HANDLING])
# [SKIP_PKG_CONFIG])
#
# Creates an imported library target for each component. The operation of this
# macro depends on the presence of a number of CMake variables.
#
# The <name>_<component>_lib variable should contain the name of this library,
# and <name>_<component>_header variable should contain the name of a header
# file associated with it (whatever relative path is normally passed to
# '#include'). <name>_<component>_header_subdir variable can be used to specify
# which subdirectory of the include path the headers will be found in.
# ecm_find_package_components() will then search for the library
# and include directory (creating appropriate cache variables) and create an
# imported library target named <name>::<component>.
#
# Additional variables can be used to provide additional information:
#
# If SKIP_PKG_CONFIG, the <name>_<component>_pkg_config variable is set, and
# pkg-config is found, the pkg-config module given by
# <name>_<component>_pkg_config will be searched for and used to help locate the
# library and header file. It will also be used to set
# <name>_<component>_VERSION.
#
# Note that if version information is found via pkg-config,
# <name>_<component>_FIND_VERSION can be set to require a particular version
# for each component.
#
# If SKIP_DEPENDENCY_HANDLING is not set, the INTERFACE_LINK_LIBRARIES property
# of the imported target for <component> will be set to contain the imported
# targets for the components listed in <name>_<component>_component_deps.
# <component>_FOUND will also be set to false if any of the components in
# <name>_<component>_component_deps are not found. This requires the components
# in <name>_<component>_component_deps to be listed before <component> in the
# COMPONENTS argument.
#
# The following variables will be set:
#
# ``<name>_TARGETS``
# the imported targets
# ``<name>_LIBRARIES``
# the found libraries
# ``<name>_INCLUDE_DIRS``
# the combined required include directories for the components
# ``<name>_DEFINITIONS``
# the "other" CFLAGS provided by pkg-config, if any
# ``<name>_VERSION``
# the value of ``<name>_<component>_VERSION`` for the first component that
# has this variable set (note that components are searched for in the order
# they are passed to the macro), although if it is already set, it will not
# be altered
#
# Note that these variables are never cleared, so if
# ecm_find_package_handle_library_components() is called multiple times with
# different components (typically because of multiple find_package() calls) then
# ``<name>_TARGETS``, for example, will contain all the targets found in any
# call (although no duplicates).
#
# Since pre-1.0.0.
#=============================================================================
# Copyright 2014 Alex Merry <alex.merry@kde.org>
#
# 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 copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the 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.
macro(ecm_find_package_version_check module_name)
if(CMAKE_VERSION VERSION_LESS 2.8.12)
message(FATAL_ERROR "CMake 2.8.12 is required by Find${module_name}.cmake")
endif()
if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.12)
message(AUTHOR_WARNING "Your project should require at least CMake 2.8.12 to use Find${module_name}.cmake")
endif()
endmacro()
macro(ecm_find_package_parse_components module_name)
set(ecm_fppc_options SKIP_DEPENDENCY_HANDLING)
set(ecm_fppc_oneValueArgs RESULT_VAR)
set(ecm_fppc_multiValueArgs KNOWN_COMPONENTS DEFAULT_COMPONENTS)
cmake_parse_arguments(ECM_FPPC "${ecm_fppc_options}" "${ecm_fppc_oneValueArgs}" "${ecm_fppc_multiValueArgs}" ${ARGN})
if(ECM_FPPC_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Unexpected arguments to ecm_find_package_parse_components: ${ECM_FPPC_UNPARSED_ARGUMENTS}")
endif()
if(NOT ECM_FPPC_RESULT_VAR)
message(FATAL_ERROR "Missing RESULT_VAR argument to ecm_find_package_parse_components")
endif()
if(NOT ECM_FPPC_KNOWN_COMPONENTS)
message(FATAL_ERROR "Missing KNOWN_COMPONENTS argument to ecm_find_package_parse_components")
endif()
if(NOT ECM_FPPC_DEFAULT_COMPONENTS)
set(ECM_FPPC_DEFAULT_COMPONENTS ${ECM_FPPC_KNOWN_COMPONENTS})
endif()
if(${module_name}_FIND_COMPONENTS)
set(ecm_fppc_requestedComps ${${module_name}_FIND_COMPONENTS})
if(NOT ECM_FPPC_SKIP_DEPENDENCY_HANDLING)
# Make sure deps are included
foreach(ecm_fppc_comp ${ecm_fppc_requestedComps})
foreach(ecm_fppc_dep_comp ${${module_name}_${ecm_fppc_comp}_component_deps})
list(FIND ecm_fppc_requestedComps "${ecm_fppc_dep_comp}" ecm_fppc_index)
if("${ecm_fppc_index}" STREQUAL "-1")
if(NOT ${module_name}_FIND_QUIETLY)
message(STATUS "${module_name}: ${ecm_fppc_comp} requires ${${module_name}_${ecm_fppc_comp}_component_deps}")
endif()
list(APPEND ecm_fppc_requestedComps "${ecm_fppc_dep_comp}")
endif()
endforeach()
endforeach()
else()
message(STATUS "Skipping dependency handling for ${module_name}")
endif()
list(REMOVE_DUPLICATES ecm_fppc_requestedComps)
# This makes sure components are listed in the same order as
# KNOWN_COMPONENTS (potentially important for inter-dependencies)
set(${ECM_FPPC_RESULT_VAR})
foreach(ecm_fppc_comp ${ECM_FPPC_KNOWN_COMPONENTS})
list(FIND ecm_fppc_requestedComps "${ecm_fppc_comp}" ecm_fppc_index)
if(NOT "${ecm_fppc_index}" STREQUAL "-1")
list(APPEND ${ECM_FPPC_RESULT_VAR} "${ecm_fppc_comp}")
list(REMOVE_AT ecm_fppc_requestedComps ${ecm_fppc_index})
endif()
endforeach()
# if there are any left, they are unknown components
if(ecm_fppc_requestedComps)
set(ecm_fppc_msgType STATUS)
if(${module_name}_FIND_REQUIRED)
set(ecm_fppc_msgType FATAL_ERROR)
endif()
if(NOT ${module_name}_FIND_QUIETLY)
message(${ecm_fppc_msgType} "${module_name}: requested unknown components ${ecm_fppc_requestedComps}")
endif()
return()
endif()
else()
set(${ECM_FPPC_RESULT_VAR} ${ECM_FPPC_DEFAULT_COMPONENTS})
endif()
endmacro()
macro(ecm_find_package_handle_library_components module_name)
set(ecm_fpwc_options SKIP_PKG_CONFIG SKIP_DEPENDENCY_HANDLING)
set(ecm_fpwc_oneValueArgs)
set(ecm_fpwc_multiValueArgs COMPONENTS)
cmake_parse_arguments(ECM_FPWC "${ecm_fpwc_options}" "${ecm_fpwc_oneValueArgs}" "${ecm_fpwc_multiValueArgs}" ${ARGN})
if(ECM_FPWC_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Unexpected arguments to ecm_find_package_handle_components: ${ECM_FPWC_UNPARSED_ARGUMENTS}")
endif()
if(NOT ECM_FPWC_COMPONENTS)
message(FATAL_ERROR "Missing COMPONENTS argument to ecm_find_package_handle_components")
endif()
include(FindPackageHandleStandardArgs)
find_package(PkgConfig QUIET)
foreach(ecm_fpwc_comp ${ECM_FPWC_COMPONENTS})
set(ecm_fpwc_dep_vars)
set(ecm_fpwc_dep_targets)
if(NOT SKIP_DEPENDENCY_HANDLING)
foreach(ecm_fpwc_dep ${${module_name}_${ecm_fpwc_comp}_component_deps})
list(APPEND ecm_fpwc_dep_vars "${module_name}_${ecm_fpwc_dep}_FOUND")
list(APPEND ecm_fpwc_dep_targets "${module_name}::${ecm_fpwc_dep}")
endforeach()
endif()
if(NOT ECM_FPWC_SKIP_PKG_CONFIG AND ${module_name}_${ecm_fpwc_comp}_pkg_config)
pkg_check_modules(PKG_${module_name}_${ecm_fpwc_comp} QUIET
${${module_name}_${ecm_fpwc_comp}_pkg_config})
endif()
find_path(${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR
NAMES ${${module_name}_${ecm_fpwc_comp}_header}
HINTS ${PKG_${module_name}_${ecm_fpwc_comp}_INCLUDE_DIRS}
PATH_SUFFIXES ${${module_name}_${ecm_fpwc_comp}_header_subdir}
)
find_library(${module_name}_${ecm_fpwc_comp}_LIBRARY
NAMES ${${module_name}_${ecm_fpwc_comp}_lib}
HINTS ${PKG_${module_name}_${ecm_fpwc_comp}_LIBRARY_DIRS}
)
set(${module_name}_${ecm_fpwc_comp}_VERSION "${PKG_${module_name}_${ecm_fpwc_comp}_VERSION}")
if(NOT ${module_name}_VERSION)
set(${module_name}_VERSION ${${module_name}_${ecm_fpwc_comp}_VERSION})
endif()
set(_name_mismatched_arg)
if(NOT CMAKE_VERSION VERSION_LESS 3.17)
set(_name_mismatched_arg NAME_MISMATCHED)
endif()
find_package_handle_standard_args(${module_name}_${ecm_fpwc_comp}
FOUND_VAR
${module_name}_${ecm_fpwc_comp}_FOUND
REQUIRED_VARS
${module_name}_${ecm_fpwc_comp}_LIBRARY
${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR
${ecm_fpwc_dep_vars}
VERSION_VAR
${module_name}_${ecm_fpwc_comp}_VERSION
${_name_mismatched_arg}
)
mark_as_advanced(
${module_name}_${ecm_fpwc_comp}_LIBRARY
${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR
)
if(${module_name}_${ecm_fpwc_comp}_FOUND)
list(APPEND ${module_name}_LIBRARIES
"${${module_name}_${ecm_fpwc_comp}_LIBRARY}")
list(APPEND ${module_name}_INCLUDE_DIRS
"${${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR}")
set(${module_name}_DEFINITIONS
${${module_name}_DEFINITIONS}
${PKG_${module_name}_${ecm_fpwc_comp}_DEFINITIONS})
if(NOT TARGET ${module_name}::${ecm_fpwc_comp})
add_library(${module_name}::${ecm_fpwc_comp} UNKNOWN IMPORTED)
set_target_properties(${module_name}::${ecm_fpwc_comp} PROPERTIES
IMPORTED_LOCATION "${${module_name}_${ecm_fpwc_comp}_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${PKG_${module_name}_${ecm_fpwc_comp}_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${ecm_fpwc_dep_targets}"
)
endif()
list(APPEND ${module_name}_TARGETS
"${module_name}::${ecm_fpwc_comp}")
endif()
endforeach()
if(${module_name}_LIBRARIES)
list(REMOVE_DUPLICATES ${module_name}_LIBRARIES)
endif()
if(${module_name}_INCLUDE_DIRS)
list(REMOVE_DUPLICATES ${module_name}_INCLUDE_DIRS)
endif()
if(${module_name}_DEFINITIONS)
list(REMOVE_DUPLICATES ${module_name}_DEFINITIONS)
endif()
if(${module_name}_TARGETS)
list(REMOVE_DUPLICATES ${module_name}_TARGETS)
endif()
endmacro()

View File

@ -1,170 +0,0 @@
#.rst:
# FindWaylandScanner
# ------------------
#
# Try to find wayland-scanner.
#
# If the wayland-scanner executable is not in your PATH, you can provide
# an alternative name or full path location with the ``WaylandScanner_EXECUTABLE``
# variable.
#
# This will define the following variables:
#
# ``WaylandScanner_FOUND``
# True if wayland-scanner is available.
#
# ``WaylandScanner_EXECUTABLE``
# The wayland-scanner executable.
#
# If ``WaylandScanner_FOUND`` is TRUE, it will also define the following imported
# target:
#
# ``Wayland::Scanner``
# The wayland-scanner executable.
#
# This module provides the following functions to generate C protocol
# implementations:
#
# - ``ecm_add_wayland_client_protocol``
# - ``ecm_add_wayland_server_protocol``
#
# ::
#
# ecm_add_wayland_client_protocol(<source_files_var>
# PROTOCOL <xmlfile>
# BASENAME <basename>)
#
# Generate Wayland client protocol files from ``<xmlfile>`` XML
# definition for the ``<basename>`` interface and append those files
# to ``<source_files_var>``.
#
# ::
#
# ecm_add_wayland_server_protocol(<source_files_var>
# PROTOCOL <xmlfile>
# BASENAME <basename>)
#
# Generate Wayland server protocol files from ``<xmlfile>`` XML
# definition for the ``<basename>`` interface and append those files
# to ``<source_files_var>``.
#
# Since 1.4.0.
#=============================================================================
# Copyright 2012-2014 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
#
# 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 copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the 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(${CMAKE_CURRENT_LIST_DIR}/ECMFindModuleHelpers.cmake)
ecm_find_package_version_check(WaylandScanner)
# Find wayland-scanner
find_program(WaylandScanner_EXECUTABLE NAMES wayland-scanner)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(WaylandScanner
FOUND_VAR
WaylandScanner_FOUND
REQUIRED_VARS
WaylandScanner_EXECUTABLE
)
mark_as_advanced(WaylandScanner_EXECUTABLE)
if(NOT TARGET Wayland::Scanner AND WaylandScanner_FOUND)
add_executable(Wayland::Scanner IMPORTED)
set_target_properties(Wayland::Scanner PROPERTIES
IMPORTED_LOCATION "${WaylandScanner_EXECUTABLE}"
)
endif()
include(FeatureSummary)
set_package_properties(WaylandScanner PROPERTIES
URL "https://wayland.freedesktop.org/"
DESCRIPTION "Executable that converts XML protocol files to C code"
)
function(ecm_add_wayland_client_protocol out_var)
# Parse arguments
set(oneValueArgs PROTOCOL BASENAME)
cmake_parse_arguments(ARGS "" "${oneValueArgs}" "" ${ARGN})
if(ARGS_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Unknown keywords given to ecm_add_wayland_client_protocol(): \"${ARGS_UNPARSED_ARGUMENTS}\"")
endif()
get_filename_component(_infile ${ARGS_PROTOCOL} ABSOLUTE)
set(_client_header "${CMAKE_CURRENT_BINARY_DIR}/wayland-${ARGS_BASENAME}-client-protocol.h")
set(_code "${CMAKE_CURRENT_BINARY_DIR}/wayland-${ARGS_BASENAME}-protocol.c")
set_source_files_properties(${_client_header} GENERATED)
set_source_files_properties(${_code} GENERATED)
set_property(SOURCE ${_client_header} PROPERTY SKIP_AUTOMOC ON)
add_custom_command(OUTPUT "${_client_header}"
COMMAND ${WaylandScanner_EXECUTABLE} client-header ${_infile} ${_client_header}
DEPENDS ${WaylandScanner_EXECUTABLE} ${_infile}
VERBATIM
)
add_custom_command(OUTPUT "${_code}"
COMMAND ${WaylandScanner_EXECUTABLE} private-code ${_infile} ${_code}
DEPENDS ${WaylandScanner_EXECUTABLE} ${_infile} ${_client_header}
VERBATIM
)
list(APPEND ${out_var} "${_client_header}" "${_code}")
set(${out_var} ${${out_var}} PARENT_SCOPE)
endfunction()
function(ecm_add_wayland_server_protocol out_var)
# Parse arguments
set(oneValueArgs PROTOCOL BASENAME)
cmake_parse_arguments(ARGS "" "${oneValueArgs}" "" ${ARGN})
if(ARGS_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Unknown keywords given to ecm_add_wayland_server_protocol(): \"${ARGS_UNPARSED_ARGUMENTS}\"")
endif()
ecm_add_wayland_client_protocol(${out_var}
PROTOCOL ${ARGS_PROTOCOL}
BASENAME ${ARGS_BASENAME})
get_filename_component(_infile ${ARGS_PROTOCOL} ABSOLUTE)
set(_server_header "${CMAKE_CURRENT_BINARY_DIR}/wayland-${ARGS_BASENAME}-server-protocol.h")
set_property(SOURCE ${_server_header} PROPERTY SKIP_AUTOMOC ON)
set_source_files_properties(${_server_header} GENERATED)
add_custom_command(OUTPUT "${_server_header}"
COMMAND ${WaylandScanner_EXECUTABLE} server-header ${_infile} ${_server_header}
DEPENDS ${WaylandScanner_EXECUTABLE} ${_infile}
VERBATIM
)
list(APPEND ${out_var} "${_server_header}")
set(${out_var} ${${out_var}} PARENT_SCOPE)
endfunction()

View File

@ -1,62 +0,0 @@
if (NOT NO_ISA_EXTENSIONS)
include(CheckCXXCompilerFlag)
if (CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "arm64")
CHECK_CXX_COMPILER_FLAG("-mcpu=native" COMPILER_SUPPORTS_MCPU_NATIVE)
if(COMPILER_SUPPORTS_MARCH_NATIVE)
add_compile_options(-mcpu=native)
endif()
else()
CHECK_CXX_COMPILER_FLAG("-march=native" COMPILER_SUPPORTS_MARCH_NATIVE)
if(COMPILER_SUPPORTS_MARCH_NATIVE)
add_compile_options(-march=native)
endif()
endif()
if(WIN32)
add_compile_options(/arch:AVX2)
endif()
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT LEGACY)
set(USE_WAYLAND ON)
else()
set(USE_WAYLAND OFF)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fexperimental-library>)
endif()
endif()
if(WIN32)
add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN -D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR)
add_compile_options(/MP)
endif()
if(EMSCRIPTEN)
add_compile_options(-pthread -DIMGUI_IMPL_OPENGL_ES2)
endif()
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT EMSCRIPTEN)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
find_program(MOLD_LINKER mold)
if(MOLD_LINKER)
set(CMAKE_LINKER_TYPE "MOLD")
endif()
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
add_compile_options(-fno-eliminate-unused-debug-types)
endif()
endif()
find_program(CCACHE ccache)
if(CCACHE)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
endif()
file(GENERATE OUTPUT .gitignore CONTENT "*")
set(CMAKE_COLOR_DIAGNOSTICS ON)

View File

@ -1,12 +0,0 @@
diff --git a/extra_symbols.txt b/extra_symbols.txt
index b95bb58..6b8f616 100644
--- a/extra_symbols.txt
+++ b/extra_symbols.txt
@@ -1,3 +1,7 @@
+glCompressedTexImage2D
+GL_LINEAR_MIPMAP_LINEAR
+GL_TEXTURE_WRAP_S
+GL_TEXTURE_WRAP_T
glReadPixels
glClearColor
glClear

View File

@ -1,14 +0,0 @@
diff '--color=auto' -ruN 72d8f61727dc878102157113d1998f86b852d20e/imconfig.h new/imconfig.h
--- 72d8f61727dc878102157113d1998f86b852d20e/imconfig.h 2024-09-27 14:28:05.568760349 +0200
+++ new/imconfig.h 2024-09-27 14:29:47.310243707 +0200
@@ -113,6 +113,10 @@
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
//#define ImDrawIdx unsigned int
+#ifdef __EMSCRIPTEN__
+#define ImDrawIdx unsigned int
+#endif
+
//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
//struct ImDrawList;
//struct ImDrawCmd;

View File

@ -1,56 +0,0 @@
diff --git a/backends/imgui_impl_opengl3_loader.h b/backends/imgui_impl_opengl3_loader.h
index d6ffa5a2d..e48372c64 100644
--- a/backends/imgui_impl_opengl3_loader.h
+++ b/backends/imgui_impl_opengl3_loader.h
@@ -179,6 +179,7 @@ typedef khronos_uint8_t GLubyte;
#define GL_VERSION 0x1F02
#define GL_EXTENSIONS 0x1F03
#define GL_LINEAR 0x2601
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
#define GL_TEXTURE_MAG_FILTER 0x2800
#define GL_TEXTURE_MIN_FILTER 0x2801
#define GL_TEXTURE_WRAP_S 0x2802
@@ -241,8 +242,10 @@ GLAPI void APIENTRY glGenTextures (GLsizei n, GLuint *textures);
#define GL_TEXTURE0 0x84C0
#define GL_ACTIVE_TEXTURE 0x84E0
typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glActiveTexture (GLenum texture);
+GLAPI void APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
#endif
#endif /* GL_VERSION_1_3 */
#ifndef GL_VERSION_1_4
@@ -478,7 +481,7 @@ GL3W_API GL3WglProc imgl3wGetProcAddress(const char *proc);
/* gl3w internal state */
union ImGL3WProcs {
- GL3WglProc ptr[59];
+ GL3WglProc ptr[60];
struct {
PFNGLACTIVETEXTUREPROC ActiveTexture;
PFNGLATTACHSHADERPROC AttachShader;
@@ -494,6 +497,7 @@ union ImGL3WProcs {
PFNGLCLEARPROC Clear;
PFNGLCLEARCOLORPROC ClearColor;
PFNGLCOMPILESHADERPROC CompileShader;
+ PFNGLCOMPRESSEDTEXIMAGE2DPROC CompressedTexImage2D;
PFNGLCREATEPROGRAMPROC CreateProgram;
PFNGLCREATESHADERPROC CreateShader;
PFNGLDELETEBUFFERSPROC DeleteBuffers;
@@ -559,6 +563,7 @@ GL3W_API extern union ImGL3WProcs imgl3wProcs;
#define glClear imgl3wProcs.gl.Clear
#define glClearColor imgl3wProcs.gl.ClearColor
#define glCompileShader imgl3wProcs.gl.CompileShader
+#define glCompressedTexImage2D imgl3wProcs.gl.CompressedTexImage2D
#define glCreateProgram imgl3wProcs.gl.CreateProgram
#define glCreateShader imgl3wProcs.gl.CreateShader
#define glDeleteBuffers imgl3wProcs.gl.DeleteBuffers
@@ -854,6 +859,7 @@ static const char *proc_names[] = {
"glClear",
"glClearColor",
"glCompileShader",
+ "glCompressedTexImage2D",
"glCreateProgram",
"glCreateShader",
"glDeleteBuffers",

View File

@ -1,35 +0,0 @@
set(TRACY_COMMON_DIR ${CMAKE_CURRENT_LIST_DIR}/../public/common)
set(TRACY_COMMON_SOURCES
tracy_lz4.cpp
tracy_lz4hc.cpp
TracySocket.cpp
TracyStackFrames.cpp
TracySystem.cpp
)
list(TRANSFORM TRACY_COMMON_SOURCES PREPEND "${TRACY_COMMON_DIR}/")
set(TRACY_SERVER_DIR ${CMAKE_CURRENT_LIST_DIR}/../server)
set(TRACY_SERVER_SOURCES
TracyMemory.cpp
TracyMmap.cpp
TracyPrint.cpp
TracySysUtil.cpp
TracyTaskDispatch.cpp
TracyTextureCompression.cpp
TracyThreadCompress.cpp
TracyWorker.cpp
)
list(TRANSFORM TRACY_SERVER_SOURCES PREPEND "${TRACY_SERVER_DIR}/")
add_library(TracyServer STATIC EXCLUDE_FROM_ALL ${TRACY_COMMON_SOURCES} ${TRACY_SERVER_SOURCES})
target_include_directories(TracyServer PUBLIC ${TRACY_COMMON_DIR} ${TRACY_SERVER_DIR})
target_link_libraries(TracyServer PUBLIC TracyCapstone libzstd PPQSort::PPQSort)
if(NO_STATISTICS)
target_compile_definitions(TracyServer PUBLIC TRACY_NO_STATISTICS)
endif()

View File

@ -1,222 +0,0 @@
# Vendor Specific CMake
# The Tracy project keeps most vendor source locally
set (ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/../")
# Dependencies are taken from the system first and if not found, they are pulled with CPM and built from source
include(FindPkgConfig)
include(${CMAKE_CURRENT_LIST_DIR}/CPM.cmake)
option(DOWNLOAD_CAPSTONE "Force download capstone" ON)
option(DOWNLOAD_GLFW "Force download glfw" OFF)
option(DOWNLOAD_FREETYPE "Force download freetype" OFF)
# capstone
pkg_check_modules(CAPSTONE capstone)
if(CAPSTONE_FOUND AND NOT DOWNLOAD_CAPSTONE)
message(STATUS "Capstone found: ${CAPSTONE}")
add_library(TracyCapstone INTERFACE)
target_include_directories(TracyCapstone INTERFACE ${CAPSTONE_INCLUDE_DIRS})
target_link_libraries(TracyCapstone INTERFACE ${CAPSTONE_LINK_LIBRARIES})
else()
CPMAddPackage(
NAME capstone
GITHUB_REPOSITORY capstone-engine/capstone
GIT_TAG 6.0.0-Alpha1
OPTIONS
"CAPSTONE_X86_ATT_DISABLE ON"
"CAPSTONE_ALPHA_SUPPORT OFF"
"CAPSTONE_HPPA_SUPPORT OFF"
"CAPSTONE_LOONGARCH_SUPPORT OFF"
"CAPSTONE_M680X_SUPPORT OFF"
"CAPSTONE_M68K_SUPPORT OFF"
"CAPSTONE_MIPS_SUPPORT OFF"
"CAPSTONE_MOS65XX_SUPPORT OFF"
"CAPSTONE_PPC_SUPPORT OFF"
"CAPSTONE_SPARC_SUPPORT OFF"
"CAPSTONE_SYSTEMZ_SUPPORT OFF"
"CAPSTONE_XCORE_SUPPORT OFF"
"CAPSTONE_TRICORE_SUPPORT OFF"
"CAPSTONE_TMS320C64X_SUPPORT OFF"
"CAPSTONE_M680X_SUPPORT OFF"
"CAPSTONE_EVM_SUPPORT OFF"
"CAPSTONE_WASM_SUPPORT OFF"
"CAPSTONE_BPF_SUPPORT OFF"
"CAPSTONE_RISCV_SUPPORT OFF"
"CAPSTONE_SH_SUPPORT OFF"
"CAPSTONE_XTENSA_SUPPORT OFF"
"CAPSTONE_BUILD_MACOS_THIN ON"
EXCLUDE_FROM_ALL TRUE
)
add_library(TracyCapstone INTERFACE)
target_include_directories(TracyCapstone INTERFACE ${capstone_SOURCE_DIR}/include/capstone)
target_link_libraries(TracyCapstone INTERFACE capstone)
endif()
# GLFW
if(NOT USE_WAYLAND AND NOT EMSCRIPTEN)
pkg_check_modules(GLFW glfw3)
if (GLFW_FOUND AND NOT DOWNLOAD_GLFW)
add_library(TracyGlfw3 INTERFACE)
target_include_directories(TracyGlfw3 INTERFACE ${GLFW_INCLUDE_DIRS})
target_link_libraries(TracyGlfw3 INTERFACE ${GLFW_LINK_LIBRARIES})
else()
CPMAddPackage(
NAME glfw
GITHUB_REPOSITORY glfw/glfw
GIT_TAG 3.4
OPTIONS
"GLFW_BUILD_EXAMPLES OFF"
"GLFW_BUILD_TESTS OFF"
"GLFW_BUILD_DOCS OFF"
"GLFW_INSTALL OFF"
EXCLUDE_FROM_ALL TRUE
)
add_library(TracyGlfw3 INTERFACE)
target_link_libraries(TracyGlfw3 INTERFACE glfw)
endif()
endif()
# freetype
pkg_check_modules(FREETYPE freetype2)
if (FREETYPE_FOUND AND NOT DOWNLOAD_FREETYPE)
add_library(TracyFreetype INTERFACE)
target_include_directories(TracyFreetype INTERFACE ${FREETYPE_INCLUDE_DIRS})
target_link_libraries(TracyFreetype INTERFACE ${FREETYPE_LINK_LIBRARIES})
else()
CPMAddPackage(
NAME freetype
GITHUB_REPOSITORY freetype/freetype
GIT_TAG VER-2-13-3
OPTIONS
"FT_DISABLE_HARFBUZZ ON"
"FT_WITH_HARFBUZZ OFF"
EXCLUDE_FROM_ALL TRUE
)
add_library(TracyFreetype INTERFACE)
target_link_libraries(TracyFreetype INTERFACE freetype)
endif()
# Zstd
CPMAddPackage(
NAME zstd
GITHUB_REPOSITORY facebook/zstd
GIT_TAG v1.5.7
OPTIONS
"ZSTD_BUILD_SHARED OFF"
EXCLUDE_FROM_ALL TRUE
SOURCE_SUBDIR build/cmake
)
# Diff Template Library
set(DTL_DIR "${ROOT_DIR}/dtl")
file(GLOB_RECURSE DTL_HEADERS CONFIGURE_DEPENDS RELATIVE ${DTL_DIR} "*.hpp")
add_library(TracyDtl INTERFACE)
target_sources(TracyDtl INTERFACE ${DTL_HEADERS})
target_include_directories(TracyDtl INTERFACE ${DTL_DIR})
# Get Opt
set(GETOPT_DIR "${ROOT_DIR}/getopt")
set(GETOPT_SOURCES ${GETOPT_DIR}/getopt.c)
set(GETOPT_HEADERS ${GETOPT_DIR}/getopt.h)
add_library(TracyGetOpt STATIC EXCLUDE_FROM_ALL ${GETOPT_SOURCES} ${GETOPT_HEADERS})
target_include_directories(TracyGetOpt PUBLIC ${GETOPT_DIR})
# ImGui
CPMAddPackage(
NAME ImGui
GITHUB_REPOSITORY ocornut/imgui
GIT_TAG v1.91.8-docking
DOWNLOAD_ONLY TRUE
PATCHES
"${CMAKE_CURRENT_LIST_DIR}/imgui-emscripten.patch"
"${CMAKE_CURRENT_LIST_DIR}/imgui-loader.patch"
)
set(IMGUI_SOURCES
imgui_widgets.cpp
imgui_draw.cpp
imgui_demo.cpp
imgui.cpp
imgui_tables.cpp
misc/freetype/imgui_freetype.cpp
backends/imgui_impl_opengl3.cpp
)
list(TRANSFORM IMGUI_SOURCES PREPEND "${ImGui_SOURCE_DIR}/")
add_library(TracyImGui STATIC EXCLUDE_FROM_ALL ${IMGUI_SOURCES})
target_include_directories(TracyImGui PUBLIC ${ImGui_SOURCE_DIR})
target_link_libraries(TracyImGui PUBLIC TracyFreetype)
target_compile_definitions(TracyImGui PRIVATE "IMGUI_ENABLE_FREETYPE")
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions(TracyImGui PRIVATE "IMGUI_DISABLE_DEBUG_TOOLS")
endif()
# NFD
if (NOT NO_FILESELECTOR AND NOT EMSCRIPTEN)
set(NFD_DIR "${ROOT_DIR}/nfd")
if (WIN32)
set(NFD_SOURCES "${NFD_DIR}/nfd_win.cpp")
elseif (APPLE)
set(NFD_SOURCES "${NFD_DIR}/nfd_cocoa.m")
else()
if (GTK_FILESELECTOR)
set(NFD_SOURCES "${NFD_DIR}/nfd_gtk.cpp")
else()
set(NFD_SOURCES "${NFD_DIR}/nfd_portal.cpp")
endif()
endif()
file(GLOB_RECURSE NFD_HEADERS CONFIGURE_DEPENDS RELATIVE ${NFD_DIR} "*.h")
add_library(TracyNfd STATIC EXCLUDE_FROM_ALL ${NFD_SOURCES} ${NFD_HEADERS})
target_include_directories(TracyNfd PUBLIC ${NFD_DIR})
if (APPLE)
find_library(APPKIT_LIBRARY AppKit)
find_library(UNIFORMTYPEIDENTIFIERS_LIBRARY UniformTypeIdentifiers)
target_link_libraries(TracyNfd PUBLIC ${APPKIT_LIBRARY} ${UNIFORMTYPEIDENTIFIERS_LIBRARY})
elseif (UNIX)
if (GTK_FILESELECTOR)
pkg_check_modules(GTK3 gtk+-3.0)
if (NOT GTK3_FOUND)
message(FATAL_ERROR "GTK3 not found. Please install it or set GTK_FILESELECTOR to OFF.")
endif()
add_library(TracyGtk3 INTERFACE)
target_include_directories(TracyGtk3 INTERFACE ${GTK3_INCLUDE_DIRS})
target_link_libraries(TracyGtk3 INTERFACE ${GTK3_LINK_LIBRARIES})
target_link_libraries(TracyNfd PUBLIC TracyGtk3)
else()
pkg_check_modules(DBUS dbus-1)
if (NOT DBUS_FOUND)
message(FATAL_ERROR "D-Bus not found. Please install it or set GTK_FILESELECTOR to ON.")
endif()
add_library(TracyDbus INTERFACE)
target_include_directories(TracyDbus INTERFACE ${DBUS_INCLUDE_DIRS})
target_link_libraries(TracyDbus INTERFACE ${DBUS_LINK_LIBRARIES})
target_link_libraries(TracyNfd PUBLIC TracyDbus)
endif()
endif()
endif()
# PPQSort
CPMAddPackage(
NAME PPQSort
GITHUB_REPOSITORY GabTux/PPQSort
VERSION 1.0.5
EXCLUDE_FROM_ALL TRUE
)

View File

@ -1,24 +0,0 @@
cmake_minimum_required(VERSION 3.10)
message("Parsing public/common/TracyVersion.hpp file")
file(READ "${CMAKE_CURRENT_LIST_DIR}/../public/common/TracyVersion.hpp" version)
# Note: This looks for a specific pattern in TracyVersion.hpp, if it changes
# this needs updating.
string(REGEX MATCH "Major = ([0-9]+)" _ ${version})
# This works do to the above () subexpression selection. See
# https://cmake.org/cmake/help/latest/command/string.html#regex-match for more
# details
set(TRACY_VERSION_MAJOR ${CMAKE_MATCH_1})
string(REGEX MATCH "Minor = ([0-9]+)" _ ${version})
set(TRACY_VERSION_MINOR ${CMAKE_MATCH_1})
string(REGEX MATCH "Patch = ([0-9]+)" _ ${version})
set(TRACY_VERSION_PATCH ${CMAKE_MATCH_1})
set(TRACY_VERSION_STRING "${TRACY_VERSION_MAJOR}.${TRACY_VERSION_MINOR}.${TRACY_VERSION_PATCH}")
message("VERSION ${TRACY_VERSION_STRING}")

View File

@ -3,25 +3,22 @@
#include <stdlib.h>
#if defined TRACY_ENABLE && !defined __EMSCRIPTEN__
#ifdef TRACY_ENABLE
# include "TracyApi.h"
# include "TracyForceInline.hpp"
# include "../client/tracy_rpmalloc.hpp"
# define TRACY_USE_RPMALLOC
#endif
namespace tracy
{
#ifdef TRACY_USE_RPMALLOC
#ifdef TRACY_ENABLE
TRACY_API void InitRpmalloc();
#else
static inline void InitRpmalloc() {}
#endif
static inline void* tracy_malloc( size_t size )
{
#ifdef TRACY_USE_RPMALLOC
#ifdef TRACY_ENABLE
InitRpmalloc();
return rpmalloc( size );
#else
@ -31,7 +28,7 @@ static inline void* tracy_malloc( size_t size )
static inline void* tracy_malloc_fast( size_t size )
{
#ifdef TRACY_USE_RPMALLOC
#ifdef TRACY_ENABLE
return rpmalloc( size );
#else
return malloc( size );
@ -40,7 +37,7 @@ static inline void* tracy_malloc_fast( size_t size )
static inline void tracy_free( void* ptr )
{
#ifdef TRACY_USE_RPMALLOC
#ifdef TRACY_ENABLE
InitRpmalloc();
rpfree( ptr );
#else
@ -50,7 +47,7 @@ static inline void tracy_free( void* ptr )
static inline void tracy_free_fast( void* ptr )
{
#ifdef TRACY_USE_RPMALLOC
#ifdef TRACY_ENABLE
rpfree( ptr );
#else
free( ptr );
@ -59,7 +56,7 @@ static inline void tracy_free_fast( void* ptr )
static inline void* tracy_realloc( void* ptr, size_t size )
{
#ifdef TRACY_USE_RPMALLOC
#ifdef TRACY_ENABLE
InitRpmalloc();
return rprealloc( ptr, size );
#else

View File

@ -9,14 +9,14 @@ namespace tracy
constexpr unsigned Lz4CompressBound( unsigned isize ) { return isize + ( isize / 255 ) + 16; }
enum : uint32_t { ProtocolVersion = 72 };
enum : uint16_t { BroadcastVersion = 3 };
enum : uint32_t { ProtocolVersion = 57 };
enum : uint16_t { BroadcastVersion = 2 };
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( 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 };
@ -34,7 +34,7 @@ enum HandshakeStatus : uint8_t
enum { WelcomeMessageProgramNameSize = 64 };
enum { WelcomeMessageHostInfoSize = 1024 };
#pragma pack( push, 1 )
#pragma pack( 1 )
// Must increase left query space after handling!
enum ServerQuery : uint8_t
@ -47,12 +47,13 @@ enum ServerQuery : uint8_t
ServerQueryFrameName,
ServerQueryParameter,
ServerQueryFiberName,
ServerQueryExternalName,
// Items above are high priority. Split order must be preserved. See IsQueryPrio().
ServerQueryDisconnect,
ServerQueryCallstackFrame,
ServerQueryExternalName,
ServerQuerySymbol,
ServerQuerySymbolCode,
ServerQueryCodeLocation,
ServerQuerySourceCode,
ServerQueryDataTransfer,
ServerQueryDataTransferPart
@ -126,43 +127,13 @@ 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 )
#pragma pack()
}

View File

@ -42,8 +42,6 @@ enum class QueueType : uint8_t
MemAllocCallstackNamed,
MemFreeCallstack,
MemFreeCallstackNamed,
MemDiscard,
MemDiscardCallstack,
GpuZoneBegin,
GpuZoneBeginCallstack,
GpuZoneBeginAllocSrcLoc,
@ -54,25 +52,22 @@ enum class QueueType : uint8_t
GpuZoneBeginAllocSrcLocSerial,
GpuZoneBeginAllocSrcLocCallstackSerial,
GpuZoneEndSerial,
PlotDataInt,
PlotDataFloat,
PlotDataDouble,
PlotData,
ContextSwitch,
ThreadWakeup,
GpuTime,
GpuContextName,
CallstackFrameSize,
SymbolInformation,
CodeInformation,
ExternalNameMetadata,
SymbolCodeMetadata,
SourceCodeMetadata,
FiberEnter,
FiberLeave,
Terminate,
KeepAlive,
ThreadContext,
GpuCalibration,
GpuTimeSync,
Crash,
CrashReport,
ZoneValidation,
@ -81,7 +76,6 @@ enum class QueueType : uint8_t
FrameMarkMsg,
FrameMarkMsgStart,
FrameMarkMsgEnd,
FrameVsync,
SourceLocation,
LockAnnounce,
LockTerminate,
@ -93,7 +87,6 @@ enum class QueueType : uint8_t
GpuNewContext,
CallstackFrame,
SysTimeReport,
SysPowerReport,
TidToPid,
HwSampleCpuCycle,
HwSampleInstructionRetired,
@ -110,7 +103,6 @@ enum class QueueType : uint8_t
SingleStringData,
SecondStringData,
MemNamePayload,
ThreadGroupHint,
StringData,
ThreadName,
PlotName,
@ -127,7 +119,7 @@ enum class QueueType : uint8_t
NUM_TYPES
};
#pragma pack( push, 1 )
#pragma pack( 1 )
struct QueueThreadContext
{
@ -171,9 +163,9 @@ struct QueueZoneValidationThread : public QueueZoneValidation
struct QueueZoneColor
{
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t g;
uint8_t b;
};
struct QueueZoneColorThread : public QueueZoneColor
@ -202,12 +194,6 @@ struct QueueFrameMark
uint64_t name; // ptr
};
struct QueueFrameVsync
{
int64_t time;
uint32_t id;
};
struct QueueFrameImage
{
uint32_t frame;
@ -227,9 +213,9 @@ struct QueueSourceLocation
uint64_t function; // ptr
uint64_t file; // ptr
uint32_t line;
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t g;
uint8_t b;
};
struct QueueZoneTextFat
@ -262,7 +248,6 @@ struct QueueFiberEnter
int64_t time;
uint64_t fiber; // ptr
uint32_t thread;
int32_t groupHint;
};
struct QueueFiberLeave
@ -293,15 +278,11 @@ struct QueueLockObtain
struct QueueLockRelease
{
uint32_t thread;
uint32_t id;
int64_t time;
};
struct QueueLockReleaseShared : public QueueLockRelease
{
uint32_t thread;
};
struct QueueLockMark
{
uint32_t thread;
@ -320,25 +301,24 @@ struct QueueLockNameFat : public QueueLockName
uint16_t size;
};
struct QueuePlotDataBase
enum class PlotDataType : uint8_t
{
Float,
Double,
Int
};
struct QueuePlotData
{
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;
PlotDataType type;
union
{
double d;
float f;
int64_t i;
} data;
};
struct QueueMessage
@ -348,9 +328,9 @@ struct QueueMessage
struct QueueMessageColor : public QueueMessage
{
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t g;
uint8_t b;
};
struct QueueMessageLiteral : public QueueMessage
@ -403,9 +383,7 @@ enum class GpuContextType : uint8_t
Vulkan,
OpenCL,
Direct3D12,
Direct3D11,
Metal,
Custom
Direct3D11
};
enum GpuContextFlags : uint8_t
@ -460,13 +438,6 @@ struct QueueGpuCalibration
uint8_t context;
};
struct QueueGpuTimeSync
{
int64_t gpuTime;
int64_t cpuTime;
uint8_t context;
};
struct QueueGpuContextName
{
uint8_t context;
@ -483,12 +454,6 @@ struct QueueMemNamePayload
uint64_t name;
};
struct QueueThreadGroupHint
{
uint32_t thread;
int32_t groupHint;
};
struct QueueMemAlloc
{
int64_t time;
@ -504,13 +469,6 @@ struct QueueMemFree
uint64_t ptr;
};
struct QueueMemDiscard
{
int64_t time;
uint32_t thread;
uint64_t name;
};
struct QueueCallstackFat
{
uint64_t ptr;
@ -574,6 +532,19 @@ struct QueueSymbolInformationFat : public QueueSymbolInformation
uint8_t needFree;
};
struct QueueCodeInformation
{
uint64_t symAddr;
uint32_t line;
uint64_t ptrOffset;
};
struct QueueCodeInformationFat : public QueueCodeInformation
{
uint64_t fileString;
uint8_t needFree;
};
struct QueueCrashReport
{
int64_t time;
@ -591,13 +562,6 @@ struct QueueSysTime
float sysTime;
};
struct QueueSysPower
{
int64_t time;
uint64_t delta;
uint64_t name; // ptr
};
struct QueueContextSwitch
{
int64_t time;
@ -637,9 +601,6 @@ struct QueuePlotConfig
{
uint64_t name; // ptr
uint8_t type;
uint8_t step;
uint8_t fill;
uint32_t color;
};
struct QueueParamSetup
@ -650,15 +611,9 @@ struct QueueParamSetup
int32_t val;
};
struct QueueSourceCodeNotAvailable
{
uint32_t id;
};
struct QueueCpuTopology
{
uint32_t package;
uint32_t die;
uint32_t core;
uint32_t thread;
};
@ -677,13 +632,6 @@ struct QueueSymbolCodeMetadata
uint32_t size;
};
struct QueueSourceCodeMetadata
{
uint64_t ptr;
uint32_t size;
uint32_t id;
};
struct QueueHeader
{
union
@ -712,7 +660,6 @@ struct QueueItem
QueueZoneValueThread zoneValueThread;
QueueStringTransfer stringTransfer;
QueueFrameMark frameMark;
QueueFrameVsync frameVsync;
QueueFrameImage frameImage;
QueueFrameImageFat frameImageFat;
QueueSourceLocation srcloc;
@ -723,13 +670,10 @@ struct QueueItem
QueueLockWait lockWait;
QueueLockObtain lockObtain;
QueueLockRelease lockRelease;
QueueLockReleaseShared lockReleaseShared;
QueueLockMark lockMark;
QueueLockName lockName;
QueueLockNameFat lockNameFat;
QueuePlotDataInt plotDataInt;
QueuePlotDataFloat plotDataFloat;
QueuePlotDataDouble plotDataDouble;
QueuePlotData plotData;
QueueMessage message;
QueueMessageColor messageColor;
QueueMessageLiteral messageLiteral;
@ -746,14 +690,11 @@ struct QueueItem
QueueGpuZoneEnd gpuZoneEnd;
QueueGpuTime gpuTime;
QueueGpuCalibration gpuCalibration;
QueueGpuTimeSync gpuTimeSync;
QueueGpuContextName gpuContextName;
QueueGpuContextNameFat gpuContextNameFat;
QueueMemAlloc memAlloc;
QueueMemFree memFree;
QueueMemDiscard memDiscard;
QueueMemNamePayload memName;
QueueThreadGroupHint threadGroupHint;
QueueCallstackFat callstackFat;
QueueCallstackFatThread callstackFatThread;
QueueCallstackAllocFat callstackAllocFat;
@ -765,10 +706,11 @@ struct QueueItem
QueueCallstackFrame callstackFrame;
QueueSymbolInformation symbolInformation;
QueueSymbolInformationFat symbolInformationFat;
QueueCodeInformation codeInformation;
QueueCodeInformationFat codeInformationFat;
QueueCrashReport crashReport;
QueueCrashReportThread crashReportThread;
QueueSysTime sysTime;
QueueSysPower sysPower;
QueueContextSwitch contextSwitch;
QueueThreadWakeup threadWakeup;
QueueTidToPid tidToPid;
@ -778,13 +720,11 @@ struct QueueItem
QueueCpuTopology cpuTopology;
QueueExternalNameMetadata externalNameMetadata;
QueueSymbolCodeMetadata symbolCodeMetadata;
QueueSourceCodeMetadata sourceCodeMetadata;
QueueSourceCodeNotAvailable sourceCodeNotAvailable;
QueueFiberEnter fiberEnter;
QueueFiberLeave fiberLeave;
};
};
#pragma pack( pop )
#pragma pack()
enum { QueueItemSize = sizeof( QueueItem ) };
@ -813,7 +753,7 @@ static constexpr size_t QueueDataSize[] = {
sizeof( QueueHeader ) + sizeof( QueueLockRelease ),
sizeof( QueueHeader ) + sizeof( QueueLockWait ), // shared
sizeof( QueueHeader ) + sizeof( QueueLockObtain ), // shared
sizeof( QueueHeader ) + sizeof( QueueLockReleaseShared ),
sizeof( QueueHeader ) + sizeof( QueueLockRelease ), // shared
sizeof( QueueHeader ) + sizeof( QueueLockName ),
sizeof( QueueHeader ) + sizeof( QueueMemAlloc ),
sizeof( QueueHeader ) + sizeof( QueueMemAlloc ), // named
@ -823,8 +763,6 @@ static constexpr size_t QueueDataSize[] = {
sizeof( QueueHeader ) + sizeof( QueueMemAlloc ), // callstack, named
sizeof( QueueHeader ) + sizeof( QueueMemFree ), // callstack
sizeof( QueueHeader ) + sizeof( QueueMemFree ), // callstack, named
sizeof( QueueHeader ) + sizeof( QueueMemDiscard ),
sizeof( QueueHeader ) + sizeof( QueueMemDiscard ), // callstack
sizeof( QueueHeader ) + sizeof( QueueGpuZoneBegin ),
sizeof( QueueHeader ) + sizeof( QueueGpuZoneBegin ), // callstack
sizeof( QueueHeader ) + sizeof( QueueGpuZoneBeginLean ),// allocated source location
@ -835,18 +773,16 @@ static constexpr size_t QueueDataSize[] = {
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( QueuePlotData ),
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 ) + sizeof( QueueCodeInformation ),
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
@ -854,7 +790,6 @@ static constexpr size_t QueueDataSize[] = {
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 ),
@ -863,7 +798,6 @@ static constexpr size_t QueueDataSize[] = {
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 ),
@ -875,7 +809,6 @@ static constexpr size_t QueueDataSize[] = {
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
@ -886,13 +819,12 @@ static constexpr size_t QueueDataSize[] = {
sizeof( QueueHeader ) + sizeof( QueuePlotConfig ),
sizeof( QueueHeader ) + sizeof( QueueParamSetup ),
sizeof( QueueHeader ), // server query acknowledgement
sizeof( QueueHeader ) + sizeof( QueueSourceCodeNotAvailable ),
sizeof( QueueHeader ), // source code not available
sizeof( QueueHeader ), // symbol code not available
sizeof( QueueHeader ) + sizeof( QueueCpuTopology ),
sizeof( QueueHeader ), // single string data
sizeof( QueueHeader ), // second string data
sizeof( QueueHeader ) + sizeof( QueueMemNamePayload ),
sizeof( QueueHeader ) + sizeof( QueueThreadGroupHint ),
// keep all QueueStringTransfer below
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // string data
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // thread name

View File

@ -21,9 +21,6 @@
# pragma warning(disable:4267)
# endif
# define poll WSAPoll
# ifdef _MSC_VER
# pragma comment(lib, "ws2_32.lib")
# endif
#else
# include <arpa/inet.h>
# include <sys/socket.h>
@ -356,7 +353,7 @@ int Socket::Recv( void* _buf, int len, int timeout )
}
}
int Socket::ReadUpTo( void* _buf, int len )
int Socket::ReadUpTo( void* _buf, int len, int timeout )
{
const auto sock = m_sock.load( std::memory_order_relaxed );
auto buf = (char*)_buf;
@ -681,10 +678,10 @@ bool UdpListen::Listen( uint16_t port )
#endif
#if defined _WIN32
unsigned long reuse = 1;
setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof( reuse ) );
setsockopt( m_sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof( reuse ) );
#else
int reuse = 1;
setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof( reuse ) );
setsockopt( m_sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof( reuse ) );
#endif
#if defined _WIN32
unsigned long broadcast = 1;

View File

@ -5,6 +5,8 @@
#include <stddef.h>
#include <stdint.h>
#include "TracyForceInline.hpp"
struct addrinfo;
struct sockaddr;
@ -29,7 +31,7 @@ public:
int Send( const void* buf, int len );
int GetSendBufSize();
int ReadUpTo( void* buf, int len );
int ReadUpTo( void* buf, int len, int timeout );
bool Read( void* buf, int len, int timeout );
template<typename ShouldExit>

View File

@ -26,13 +26,8 @@
# include <fcntl.h>
#elif defined __FreeBSD__
# include <sys/thr.h>
#elif defined __NetBSD__
# include <lwp.h>
#elif defined __DragonFly__
#elif defined __NetBSD__ || defined __DragonFly__
# include <sys/lwp.h>
#elif defined __QNX__
# include <process.h>
# include <sys/neutrino.h>
#endif
#ifdef __MINGW32__
@ -83,11 +78,6 @@ TRACY_API uint32_t GetThreadHandleImpl()
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.
//
@ -103,10 +93,16 @@ TRACY_API uint32_t GetThreadHandleImpl()
}
#ifdef TRACY_ENABLE
struct ThreadNameData
{
uint32_t id;
const char* name;
ThreadNameData* next;
};
std::atomic<ThreadNameData*>& GetThreadNameData();
#endif
#if defined _MSC_VER && !defined __clang__
#ifdef _MSC_VER
# pragma pack( push, 8 )
struct THREADNAME_INFO
{
@ -115,7 +111,7 @@ struct THREADNAME_INFO
DWORD dwThreadID;
DWORD dwFlags;
};
# pragma pack( pop )
# pragma pack(pop)
void ThreadNameMsvcMagic( const THREADNAME_INFO& info )
{
@ -130,11 +126,6 @@ void ThreadNameMsvcMagic( const THREADNAME_INFO& info )
#endif
TRACY_API void SetThreadName( const char* name )
{
SetThreadNameWithHint( name, 0 );
}
TRACY_API void SetThreadNameWithHint( const char* name, int32_t groupHint )
{
#if defined _WIN32
# ifdef TRACY_UWP
@ -150,7 +141,7 @@ TRACY_API void SetThreadNameWithHint( const char* name, int32_t groupHint )
}
else
{
# if defined _MSC_VER && !defined __clang__
# if defined _MSC_VER
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = name;
@ -182,21 +173,6 @@ TRACY_API void SetThreadNameWithHint( const char* name, int32_t groupHint )
#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
{
@ -206,7 +182,6 @@ TRACY_API void SetThreadNameWithHint( const char* name, int32_t groupHint )
buf[sz] = '\0';
auto data = (ThreadNameData*)tracy_malloc_fast( sizeof( ThreadNameData ) );
data->id = detail::GetThreadHandleImpl();
data->groupHint = groupHint;
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 ) ) {}
@ -214,22 +189,6 @@ TRACY_API void SetThreadNameWithHint( const char* name, int32_t groupHint )
#endif
}
#ifdef TRACY_ENABLE
ThreadNameData* GetThreadNameData( uint32_t id )
{
auto ptr = GetThreadNameData().load( std::memory_order_relaxed );
while( ptr )
{
if( ptr->id == id )
{
return ptr;
}
ptr = ptr->next;
}
return nullptr;
}
#endif
TRACY_API const char* GetThreadName( uint32_t id )
{
static char buf[256];
@ -243,65 +202,61 @@ TRACY_API const char* GetThreadName( uint32_t id )
}
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
#else
# 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 ) ) )
_GetThreadDescription( hnd, &tmp );
auto ret = wcstombs( buf, tmp, 256 );
CloseHandle( hnd );
if( ret != 0 )
{
auto ret = wcstombs( buf, tmp, 256 );
CloseHandle( hnd );
LocalFree( tmp );
if( ret != static_cast<size_t>( -1 ) )
{
return buf;
}
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;
};
# elif defined __linux__
int cs, fd;
char path[32];
# ifdef __ANDROID__
int tid = gettid();
# else
int tid = (int) syscall( SYS_gettid );
# endif
snprintf( path, sizeof( path ), "/proc/self/task/%d/comm", tid );
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;
# endif
#endif
sprintf( buf, "%" PRIu32, id );
return buf;
sprintf( buf, "%" PRIu32, id );
return buf;
}
TRACY_API const char* GetEnvVar( const char* name )

View File

@ -14,16 +14,6 @@ TRACY_API uint32_t GetThreadHandleImpl();
}
#ifdef TRACY_ENABLE
struct ThreadNameData
{
uint32_t id;
int32_t groupHint;
const char* name;
ThreadNameData* next;
};
ThreadNameData* GetThreadNameData( uint32_t id );
TRACY_API uint32_t GetThreadHandle();
#else
static inline uint32_t GetThreadHandle()
@ -33,10 +23,9 @@ static inline uint32_t GetThreadHandle()
#endif
TRACY_API void SetThreadName( const char* name );
TRACY_API void SetThreadNameWithHint( const char* name, int32_t groupHint );
TRACY_API const char* GetThreadName( uint32_t id );
TRACY_API const char* GetEnvVar( const char* name );
TRACY_API const char* GetEnvVar(const char* name);
}

View File

@ -1,7 +1,7 @@
#ifndef __TRACYYIELD_HPP__
#define __TRACYYIELD_HPP__
#if defined __SSE2__ || defined _M_AMD64 || (defined _M_IX86_FP && _M_IX86_FP == 2)
#if defined __SSE2__ || defined _M_AMD64 || _M_IX86_FP == 2
# include <emmintrin.h>
#else
# include <thread>
@ -14,7 +14,7 @@ namespace tracy
static tracy_force_inline void YieldThread()
{
#if defined __SSE2__ || defined _M_AMD64 || (defined _M_IX86_FP && _M_IX86_FP == 2)
#if defined __SSE2__ || defined _M_AMD64 || _M_IX86_FP == 2
_mm_pause();
#elif defined __aarch64__
asm volatile( "isb" : : );

View File

@ -0,0 +1,21 @@
# Extract the actual list of source files from a sibling Visual Studio project.
# Ensure these are simply-substituted variables, without changing their values.
SRC := $(SRC)
SRC2 := $(SRC2)
SRC3 := $(SRC3)
SRC4 := $(SRC4)
# Paths here are relative to the directory in which make was invoked, not to
# this file, so ../win32/$(PROJECT).vcxproj refers to the Visual Studio project
# of whichever tool is including this makefile fragment.
BASE := $(shell egrep 'ClCompile.*cpp"' ../win32/$(PROJECT).vcxproj | sed -e 's/.*\"\(.*\)\".*/\1/' | sed -e 's@\\@/@g')
BASE2 := $(shell egrep 'ClCompile.*c"' ../win32/$(PROJECT).vcxproj | sed -e 's/.*\"\(.*\)\".*/\1/' | sed -e 's@\\@/@g')
BASE4 := $(shell egrep 'None.*S"' ../win32/$(PROJECT).vcxproj | sed -e 's/.*\"\(.*\)\".*/\1/' | sed -e 's@\\@/@g')
# The tool-specific makefile may request that certain files be omitted.
SRC += $(filter-out $(FILTER),$(BASE))
SRC2 += $(filter-out $(FILTER),$(BASE2))
SRC3 += $(filter-out $(FILTER),$(BASE3))
SRC4 += $(filter-out $(FILTER),$(BASE4))

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/*
* LZ4 - Fast LZ compression algorithm
* Header File
* Copyright (C) 2011-2020, Yann Collet.
* Copyright (C) 2011-present, Yann Collet.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
@ -95,80 +95,39 @@
# 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_RELEASE 3 /* 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+ */
#define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION)
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+ */
LZ4LIB_API int LZ4_versionNumber (void); /**< library version number; useful to check dll version */
LZ4LIB_API const char* LZ4_versionString (void); /**< library version string; useful to check dll version */
/*-************************************
* 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.
* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
* Increasing memory usage improves compression ratio.
* Reduced memory usage may improve speed, 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
# define LZ4_MEMORY_USAGE 14
#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
@ -312,25 +271,8 @@ LZ4LIB_API int LZ4_decompress_safe_partial (const char* src, char* dst, int srcS
***********************************************/
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
@ -414,12 +356,8 @@ typedef union LZ4_streamDecode_u LZ4_streamDecode_t; /* tracking context */
* 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.
@ -469,10 +407,7 @@ LZ4LIB_API int LZ4_decoderRingBufferSize(int maxBlockSize);
* 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);
LZ4LIB_API int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int srcSize, int dstCapacity);
/*! LZ4_decompress_*_usingDict() :
@ -483,16 +418,7 @@ LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode,
* 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);
LZ4LIB_API int LZ4_decompress_safe_usingDict (const char* src, char* dst, int srcSize, int dstCapcity, const char* dictStart, int dictSize);
}
@ -575,15 +501,13 @@ LZ4LIB_STATIC_API int LZ4_compress_fast_extState_fastReset (void* state, const c
* 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);
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.
* for highly contrained 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.
@ -646,8 +570,6 @@ LZ4_attach_dictionary(LZ4_stream_t* workingStream,
#endif /* LZ4_STATIC_3504398509 */
#endif /* LZ4_STATIC_LINKING_ONLY */
#ifndef TRACY_LZ4_H_98237428734687
#define TRACY_LZ4_H_98237428734687
@ -677,26 +599,38 @@ namespace tracy
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;
const LZ4_byte* dictionary;
const LZ4_stream_t_internal* dictCtx;
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 */
typedef struct {
const LZ4_byte* externalDict;
size_t extDictSize;
const LZ4_byte* prefixEnd;
size_t prefixSize;
} LZ4_streamDecode_t_internal;
/*! LZ4_stream_t :
* Do not use below internal definitions directly !
* Declare or allocate an LZ4_stream_t instead.
* LZ4_stream_t can also be created using LZ4_createStream(), which is recommended.
* The structure definition can be convenient for static allocation
* (on stack, or as part of larger structure).
* Init this structure with LZ4_initStream() before first use.
* note : only use this definition in association with static linking !
* this definition is not API/ABI safe, and may change in future versions.
*/
#define LZ4_STREAMSIZE 16416 /* static size, for inter-version compatibility */
#define LZ4_STREAMSIZE_VOIDP (LZ4_STREAMSIZE / sizeof(void*))
union LZ4_stream_u {
char minStateSize[LZ4_STREAM_MINSIZE];
void* table[LZ4_STREAMSIZE_VOIDP];
LZ4_stream_t_internal internal_donotuse;
}; /* previously typedef'd to LZ4_stream_t */
@ -714,25 +648,21 @@ union LZ4_stream_u {
* 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
* information structure to track an LZ4 stream during decompression.
* init this structure using LZ4_setStreamDecode() before first use.
* note : only use in association with static linking !
* this definition is not API/ABI safe,
* and may change in a future version !
*/
#define LZ4_STREAMDECODESIZE_U64 (4 + ((sizeof(void*)==16) ? 2 : 0) /*AS-400*/ )
#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long))
union LZ4_streamDecode_u {
char minStateSize[LZ4_STREAMDECODE_MINSIZE];
unsigned long long table[LZ4_STREAMDECODESIZE_U64];
LZ4_streamDecode_t_internal internal_donotuse;
} ; /* previously typedef'd to LZ4_streamDecode_t */

View File

@ -1,6 +1,6 @@
/*
LZ4 HC - High Compression Mode of LZ4
Copyright (C) 2011-2020, Yann Collet.
Copyright (C) 2011-2017, Yann Collet.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
@ -42,7 +42,7 @@
* Select how default compression function will allocate workplace memory,
* in stack (0:fastest), or in heap (1:requires malloc()).
* Since workplace is rather large, heap mode is recommended.
**/
*/
#ifndef LZ4HC_HEAPMODE
# define LZ4HC_HEAPMODE 1
#endif
@ -102,20 +102,18 @@ static void LZ4HC_clearTables (LZ4HC_CCtx_internal* hc4)
static void LZ4HC_init_internal (LZ4HC_CCtx_internal* hc4, const BYTE* start)
{
size_t const bufferSize = (size_t)(hc4->end - hc4->prefixStart);
size_t newStartingOffset = bufferSize + hc4->dictLimit;
assert(newStartingOffset >= bufferSize); /* check overflow */
if (newStartingOffset > 1 GB) {
uptrval startingOffset = (uptrval)(hc4->end - hc4->base);
if (startingOffset > 1 GB) {
LZ4HC_clearTables(hc4);
newStartingOffset = 0;
startingOffset = 0;
}
newStartingOffset += 64 KB;
hc4->nextToUpdate = (U32)newStartingOffset;
hc4->prefixStart = start;
startingOffset += 64 KB;
hc4->nextToUpdate = (U32) startingOffset;
hc4->base = start - startingOffset;
hc4->end = start;
hc4->dictStart = start;
hc4->dictLimit = (U32)newStartingOffset;
hc4->lowLimit = (U32)newStartingOffset;
hc4->dictBase = start - startingOffset;
hc4->dictLimit = (U32) startingOffset;
hc4->lowLimit = (U32) startingOffset;
}
@ -124,15 +122,12 @@ LZ4_FORCE_INLINE void LZ4HC_Insert (LZ4HC_CCtx_internal* hc4, const BYTE* ip)
{
U16* const chainTable = hc4->chainTable;
U32* const hashTable = hc4->hashTable;
const BYTE* const prefixPtr = hc4->prefixStart;
U32 const prefixIdx = hc4->dictLimit;
U32 const target = (U32)(ip - prefixPtr) + prefixIdx;
const BYTE* const base = hc4->base;
U32 const target = (U32)(ip - base);
U32 idx = hc4->nextToUpdate;
assert(ip >= prefixPtr);
assert(target >= prefixIdx);
while (idx < target) {
U32 const h = LZ4HC_hashPtr(prefixPtr+idx-prefixIdx);
U32 const h = LZ4HC_hashPtr(base+idx);
size_t delta = idx - hashTable[h];
if (delta>LZ4_DISTANCE_MAX) delta = LZ4_DISTANCE_MAX;
DELTANEXTU16(chainTable, idx) = (U16)delta;
@ -201,14 +196,15 @@ LZ4HC_countPattern(const BYTE* ip, const BYTE* const iEnd, U32 const pattern32)
BYTE const byte = (BYTE)(pattern >> bitOffset);
if (*ip != byte) break;
ip ++; bitOffset -= 8;
} }
}
}
return (unsigned)(ip - iStart);
}
/* LZ4HC_reverseCountPattern() :
* pattern must be a sample of repetitive pattern of length 1, 2 or 4 (but not 3!)
* read using natural platform endianness */
* read using natural platform endianess */
static unsigned
LZ4HC_reverseCountPattern(const BYTE* ip, const BYTE* const iLow, U32 pattern)
{
@ -218,7 +214,7 @@ LZ4HC_reverseCountPattern(const BYTE* ip, const BYTE* const iLow, U32 pattern)
if (LZ4_read32(ip-4) != pattern) break;
ip -= 4;
}
{ const BYTE* bytePtr = (const BYTE*)(&pattern) + 3; /* works for any endianness */
{ const BYTE* bytePtr = (const BYTE*)(&pattern) + 3; /* works for any endianess */
while (likely(ip>iLow)) {
if (ip[-1] != *bytePtr) break;
ip--; bytePtr--;
@ -241,28 +237,28 @@ typedef enum { favorCompressionRatio=0, favorDecompressionSpeed } HCfavor_e;
LZ4_FORCE_INLINE int
LZ4HC_InsertAndGetWiderMatch (
LZ4HC_CCtx_internal* const hc4,
const BYTE* const ip,
const BYTE* const iLowLimit, const BYTE* const iHighLimit,
int longest,
const BYTE** matchpos,
const BYTE** startpos,
const int maxNbAttempts,
const int patternAnalysis, const int chainSwap,
const dictCtx_directive dict,
const HCfavor_e favorDecSpeed)
LZ4HC_CCtx_internal* hc4,
const BYTE* const ip,
const BYTE* const iLowLimit,
const BYTE* const iHighLimit,
int longest,
const BYTE** matchpos,
const BYTE** startpos,
const int maxNbAttempts,
const int patternAnalysis,
const int chainSwap,
const dictCtx_directive dict,
const HCfavor_e favorDecSpeed)
{
U16* const chainTable = hc4->chainTable;
U32* const HashTable = hc4->hashTable;
const LZ4HC_CCtx_internal * const dictCtx = hc4->dictCtx;
const BYTE* const prefixPtr = hc4->prefixStart;
const U32 prefixIdx = hc4->dictLimit;
const U32 ipIndex = (U32)(ip - prefixPtr) + prefixIdx;
const int withinStartDistance = (hc4->lowLimit + (LZ4_DISTANCE_MAX + 1) > ipIndex);
const U32 lowestMatchIndex = (withinStartDistance) ? hc4->lowLimit : ipIndex - LZ4_DISTANCE_MAX;
const BYTE* const dictStart = hc4->dictStart;
const U32 dictIdx = hc4->lowLimit;
const BYTE* const dictEnd = dictStart + prefixIdx - dictIdx;
const BYTE* const base = hc4->base;
const U32 dictLimit = hc4->dictLimit;
const BYTE* const lowPrefixPtr = base + dictLimit;
const U32 ipIndex = (U32)(ip - base);
const U32 lowestMatchIndex = (hc4->lowLimit + (LZ4_DISTANCE_MAX + 1) > ipIndex) ? hc4->lowLimit : ipIndex - LZ4_DISTANCE_MAX;
const BYTE* const dictBase = hc4->dictBase;
int const lookBackLength = (int)(ip-iLowLimit);
int nbAttempts = maxNbAttempts;
U32 matchChainPos = 0;
@ -284,13 +280,14 @@ LZ4HC_InsertAndGetWiderMatch (
assert(matchIndex < ipIndex);
if (favorDecSpeed && (ipIndex - matchIndex < 8)) {
/* do nothing */
} else if (matchIndex >= prefixIdx) { /* within current Prefix */
const BYTE* const matchPtr = prefixPtr + matchIndex - prefixIdx;
} else if (matchIndex >= dictLimit) { /* within current Prefix */
const BYTE* const matchPtr = base + matchIndex;
assert(matchPtr >= lowPrefixPtr);
assert(matchPtr < ip);
assert(longest >= 1);
if (LZ4_read16(iLowLimit + longest - 1) == LZ4_read16(matchPtr - lookBackLength + longest - 1)) {
if (LZ4_read32(matchPtr) == pattern) {
int const back = lookBackLength ? LZ4HC_countBack(ip, matchPtr, iLowLimit, prefixPtr) : 0;
int const back = lookBackLength ? LZ4HC_countBack(ip, matchPtr, iLowLimit, lowPrefixPtr) : 0;
matchLength = MINMATCH + (int)LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, iHighLimit);
matchLength -= back;
if (matchLength > longest) {
@ -299,25 +296,24 @@ LZ4HC_InsertAndGetWiderMatch (
*startpos = ip + back;
} } }
} else { /* lowestMatchIndex <= matchIndex < dictLimit */
const BYTE* const matchPtr = dictStart + (matchIndex - dictIdx);
assert(matchIndex >= dictIdx);
if ( likely(matchIndex <= prefixIdx - 4)
&& (LZ4_read32(matchPtr) == pattern) ) {
const BYTE* const matchPtr = dictBase + matchIndex;
if (LZ4_read32(matchPtr) == pattern) {
const BYTE* const dictStart = dictBase + hc4->lowLimit;
int back = 0;
const BYTE* vLimit = ip + (prefixIdx - matchIndex);
const BYTE* vLimit = ip + (dictLimit - matchIndex);
if (vLimit > iHighLimit) vLimit = iHighLimit;
matchLength = (int)LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, vLimit) + MINMATCH;
if ((ip+matchLength == vLimit) && (vLimit < iHighLimit))
matchLength += LZ4_count(ip+matchLength, prefixPtr, iHighLimit);
matchLength += LZ4_count(ip+matchLength, lowPrefixPtr, iHighLimit);
back = lookBackLength ? LZ4HC_countBack(ip, matchPtr, iLowLimit, dictStart) : 0;
matchLength -= back;
if (matchLength > longest) {
longest = matchLength;
*matchpos = prefixPtr - prefixIdx + matchIndex + back; /* virtual pos, relative to ip, to retrieve offset */
*matchpos = base + matchIndex + back; /* virtual pos, relative to ip, to retrieve offset */
*startpos = ip + back;
} } }
if (chainSwap && matchLength==longest) { /* better match => select a better chain */
if (chainSwap && matchLength==longest) { /* better match => select a better chain */
assert(lookBackLength==0); /* search forward only */
if (matchIndex + (U32)longest <= ipIndex) {
int const kTrigger = 4;
@ -333,7 +329,8 @@ LZ4HC_InsertAndGetWiderMatch (
distanceToNextMatch = candidateDist;
matchChainPos = (U32)pos;
accel = 1 << kTrigger;
} }
}
}
if (distanceToNextMatch > 1) {
if (distanceToNextMatch > matchIndex) break; /* avoid overflow */
matchIndex -= distanceToNextMatch;
@ -353,24 +350,23 @@ LZ4HC_InsertAndGetWiderMatch (
repeat = rep_not;
} }
if ( (repeat == rep_confirmed) && (matchCandidateIdx >= lowestMatchIndex)
&& LZ4HC_protectDictEnd(prefixIdx, matchCandidateIdx) ) {
const int extDict = matchCandidateIdx < prefixIdx;
const BYTE* const matchPtr = (extDict ? dictStart - dictIdx : prefixPtr - prefixIdx) + matchCandidateIdx;
&& LZ4HC_protectDictEnd(dictLimit, matchCandidateIdx) ) {
const int extDict = matchCandidateIdx < dictLimit;
const BYTE* const matchPtr = (extDict ? dictBase : base) + matchCandidateIdx;
if (LZ4_read32(matchPtr) == pattern) { /* good candidate */
const BYTE* const iLimit = extDict ? dictEnd : iHighLimit;
const BYTE* const dictStart = dictBase + hc4->lowLimit;
const BYTE* const iLimit = extDict ? dictBase + dictLimit : iHighLimit;
size_t forwardPatternLength = LZ4HC_countPattern(matchPtr+sizeof(pattern), iLimit, pattern) + sizeof(pattern);
if (extDict && matchPtr + forwardPatternLength == iLimit) {
U32 const rotatedPattern = LZ4HC_rotatePattern(forwardPatternLength, pattern);
forwardPatternLength += LZ4HC_countPattern(prefixPtr, iHighLimit, rotatedPattern);
forwardPatternLength += LZ4HC_countPattern(lowPrefixPtr, iHighLimit, rotatedPattern);
}
{ const BYTE* const lowestMatchPtr = extDict ? dictStart : prefixPtr;
{ const BYTE* const lowestMatchPtr = extDict ? dictStart : lowPrefixPtr;
size_t backLength = LZ4HC_reverseCountPattern(matchPtr, lowestMatchPtr, pattern);
size_t currentSegmentLength;
if (!extDict
&& matchPtr - backLength == prefixPtr
&& dictIdx < prefixIdx) {
if (!extDict && matchPtr - backLength == lowPrefixPtr && hc4->lowLimit < dictLimit) {
U32 const rotatedPattern = LZ4HC_rotatePattern((U32)(-(int)backLength), pattern);
backLength += LZ4HC_reverseCountPattern(dictEnd, dictStart, rotatedPattern);
backLength += LZ4HC_reverseCountPattern(dictBase + dictLimit, dictStart, rotatedPattern);
}
/* Limit backLength not go further than lowestMatchIndex */
backLength = matchCandidateIdx - MAX(matchCandidateIdx - (U32)backLength, lowestMatchIndex);
@ -380,28 +376,28 @@ LZ4HC_InsertAndGetWiderMatch (
if ( (currentSegmentLength >= srcPatternLength) /* current pattern segment large enough to contain full srcPatternLength */
&& (forwardPatternLength <= srcPatternLength) ) { /* haven't reached this position yet */
U32 const newMatchIndex = matchCandidateIdx + (U32)forwardPatternLength - (U32)srcPatternLength; /* best position, full pattern, might be followed by more match */
if (LZ4HC_protectDictEnd(prefixIdx, newMatchIndex))
if (LZ4HC_protectDictEnd(dictLimit, newMatchIndex))
matchIndex = newMatchIndex;
else {
/* Can only happen if started in the prefix */
assert(newMatchIndex >= prefixIdx - 3 && newMatchIndex < prefixIdx && !extDict);
matchIndex = prefixIdx;
assert(newMatchIndex >= dictLimit - 3 && newMatchIndex < dictLimit && !extDict);
matchIndex = dictLimit;
}
} else {
U32 const newMatchIndex = matchCandidateIdx - (U32)backLength; /* farthest position in current segment, will find a match of length currentSegmentLength + maybe some back */
if (!LZ4HC_protectDictEnd(prefixIdx, newMatchIndex)) {
assert(newMatchIndex >= prefixIdx - 3 && newMatchIndex < prefixIdx && !extDict);
matchIndex = prefixIdx;
if (!LZ4HC_protectDictEnd(dictLimit, newMatchIndex)) {
assert(newMatchIndex >= dictLimit - 3 && newMatchIndex < dictLimit && !extDict);
matchIndex = dictLimit;
} else {
matchIndex = newMatchIndex;
if (lookBackLength==0) { /* no back possible */
size_t const maxML = MIN(currentSegmentLength, srcPatternLength);
if ((size_t)longest < maxML) {
assert(prefixPtr - prefixIdx + matchIndex != ip);
if ((size_t)(ip - prefixPtr) + prefixIdx - matchIndex > LZ4_DISTANCE_MAX) break;
assert(base + matchIndex != ip);
if ((size_t)(ip - base) - matchIndex > LZ4_DISTANCE_MAX) break;
assert(maxML < 2 GB);
longest = (int)maxML;
*matchpos = prefixPtr - prefixIdx + matchIndex; /* virtual pos, relative to ip, to retrieve offset */
*matchpos = base + matchIndex; /* virtual pos, relative to ip, to retrieve offset */
*startpos = ip;
}
{ U32 const distToNextPattern = DELTANEXTU16(chainTable, matchIndex);
@ -420,12 +416,12 @@ LZ4HC_InsertAndGetWiderMatch (
if ( dict == usingDictCtxHc
&& nbAttempts > 0
&& ipIndex - lowestMatchIndex < LZ4_DISTANCE_MAX) {
size_t const dictEndOffset = (size_t)(dictCtx->end - dictCtx->prefixStart) + dictCtx->dictLimit;
size_t const dictEndOffset = (size_t)(dictCtx->end - dictCtx->base);
U32 dictMatchIndex = dictCtx->hashTable[LZ4HC_hashPtr(ip)];
assert(dictEndOffset <= 1 GB);
matchIndex = dictMatchIndex + lowestMatchIndex - (U32)dictEndOffset;
while (ipIndex - matchIndex <= LZ4_DISTANCE_MAX && nbAttempts--) {
const BYTE* const matchPtr = dictCtx->prefixStart - dictCtx->dictLimit + dictMatchIndex;
const BYTE* const matchPtr = dictCtx->base + dictMatchIndex;
if (LZ4_read32(matchPtr) == pattern) {
int mlt;
@ -433,11 +429,11 @@ LZ4HC_InsertAndGetWiderMatch (
const BYTE* vLimit = ip + (dictEndOffset - dictMatchIndex);
if (vLimit > iHighLimit) vLimit = iHighLimit;
mlt = (int)LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, vLimit) + MINMATCH;
back = lookBackLength ? LZ4HC_countBack(ip, matchPtr, iLowLimit, dictCtx->prefixStart) : 0;
back = lookBackLength ? LZ4HC_countBack(ip, matchPtr, iLowLimit, dictCtx->base + dictCtx->dictLimit) : 0;
mlt -= back;
if (mlt > longest) {
longest = mlt;
*matchpos = prefixPtr - prefixIdx + matchIndex + back;
*matchpos = base + matchIndex + back;
*startpos = ip + back;
} }
@ -449,13 +445,13 @@ LZ4HC_InsertAndGetWiderMatch (
return longest;
}
LZ4_FORCE_INLINE int
LZ4HC_InsertAndFindBestMatch(LZ4HC_CCtx_internal* const hc4, /* Index table will be updated */
const BYTE* const ip, const BYTE* const iLimit,
const BYTE** matchpos,
const int maxNbAttempts,
const int patternAnalysis,
const dictCtx_directive dict)
LZ4_FORCE_INLINE
int LZ4HC_InsertAndFindBestMatch(LZ4HC_CCtx_internal* const hc4, /* Index table will be updated */
const BYTE* const ip, const BYTE* const iLimit,
const BYTE** matchpos,
const int maxNbAttempts,
const int patternAnalysis,
const dictCtx_directive dict)
{
const BYTE* uselessPtr = ip;
/* note : LZ4HC_InsertAndGetWiderMatch() is able to modify the starting position of a match (*startpos),
@ -758,7 +754,7 @@ _last_literals:
} else {
*op++ = (BYTE)(lastRunSize << ML_BITS);
}
LZ4_memcpy(op, anchor, lastRunSize);
memcpy(op, anchor, lastRunSize);
op += lastRunSize;
}
@ -891,13 +887,13 @@ LZ4HC_compress_generic_dictCtx (
limitedOutput_directive limit
)
{
const size_t position = (size_t)(ctx->end - ctx->prefixStart) + (ctx->dictLimit - ctx->lowLimit);
const size_t position = (size_t)(ctx->end - ctx->base) - ctx->lowLimit;
assert(ctx->dictCtx != NULL);
if (position >= 64 KB) {
ctx->dictCtx = NULL;
return LZ4HC_compress_generic_noDictCtx(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit);
} else if (position == 0 && *srcSizePtr > 4 KB) {
LZ4_memcpy(ctx, ctx->dictCtx, sizeof(LZ4HC_CCtx_internal));
memcpy(ctx, ctx->dictCtx, sizeof(LZ4HC_CCtx_internal));
LZ4HC_setExternalDict(ctx, (const BYTE *)src);
ctx->compressionLevel = (short)cLevel;
return LZ4HC_compress_generic_noDictCtx(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit);
@ -960,15 +956,13 @@ int LZ4_compress_HC_extStateHC (void* state, const char* src, char* dst, int src
int LZ4_compress_HC(const char* src, char* dst, int srcSize, int dstCapacity, int compressionLevel)
{
int cSize;
#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
LZ4_streamHC_t* const statePtr = (LZ4_streamHC_t*)ALLOC(sizeof(LZ4_streamHC_t));
if (statePtr==NULL) return 0;
#else
LZ4_streamHC_t state;
LZ4_streamHC_t* const statePtr = &state;
#endif
cSize = LZ4_compress_HC_extStateHC(statePtr, src, dst, srcSize, dstCapacity, compressionLevel);
int const cSize = LZ4_compress_HC_extStateHC(statePtr, src, dst, srcSize, dstCapacity, compressionLevel);
#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
FREEMEM(statePtr);
#endif
@ -991,7 +985,6 @@ int LZ4_compress_HC_destSize(void* state, const char* source, char* dest, int* s
* Streaming Functions
**************************************/
/* allocation */
#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION)
LZ4_streamHC_t* LZ4_createStreamHC(void)
{
LZ4_streamHC_t* const state =
@ -1008,12 +1001,13 @@ int LZ4_freeStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr)
FREEMEM(LZ4_streamHCPtr);
return 0;
}
#endif
LZ4_streamHC_t* LZ4_initStreamHC (void* buffer, size_t size)
{
LZ4_streamHC_t* const LZ4_streamHCPtr = (LZ4_streamHC_t*)buffer;
/* if compilation fails here, LZ4_STREAMHCSIZE must be increased */
LZ4_STATIC_ASSERT(sizeof(LZ4HC_CCtx_internal) <= LZ4_STREAMHCSIZE);
DEBUGLOG(4, "LZ4_initStreamHC(%p, %u)", buffer, (unsigned)size);
/* check conditions */
if (buffer == NULL) return NULL;
@ -1039,13 +1033,9 @@ void LZ4_resetStreamHC_fast (LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLev
if (LZ4_streamHCPtr->internal_donotuse.dirty) {
LZ4_initStreamHC(LZ4_streamHCPtr, sizeof(*LZ4_streamHCPtr));
} else {
/* preserve end - prefixStart : can trigger clearTable's threshold */
if (LZ4_streamHCPtr->internal_donotuse.end != NULL) {
LZ4_streamHCPtr->internal_donotuse.end -= (uptrval)LZ4_streamHCPtr->internal_donotuse.prefixStart;
} else {
assert(LZ4_streamHCPtr->internal_donotuse.prefixStart == NULL);
}
LZ4_streamHCPtr->internal_donotuse.prefixStart = NULL;
/* preserve end - base : can trigger clearTable's threshold */
LZ4_streamHCPtr->internal_donotuse.end -= (uptrval)LZ4_streamHCPtr->internal_donotuse.base;
LZ4_streamHCPtr->internal_donotuse.base = NULL;
LZ4_streamHCPtr->internal_donotuse.dictCtx = NULL;
}
LZ4_setCompressionLevel(LZ4_streamHCPtr, compressionLevel);
@ -1096,14 +1086,14 @@ void LZ4_attach_HC_dictionary(LZ4_streamHC_t *working_stream, const LZ4_streamHC
static void LZ4HC_setExternalDict(LZ4HC_CCtx_internal* ctxPtr, const BYTE* newBlock)
{
DEBUGLOG(4, "LZ4HC_setExternalDict(%p, %p)", ctxPtr, newBlock);
if (ctxPtr->end >= ctxPtr->prefixStart + 4)
if (ctxPtr->end >= ctxPtr->base + ctxPtr->dictLimit + 4)
LZ4HC_Insert (ctxPtr, ctxPtr->end-3); /* Referencing remaining dictionary content */
/* Only one memory segment for extDict, so any previous extDict is lost at this stage */
ctxPtr->lowLimit = ctxPtr->dictLimit;
ctxPtr->dictStart = ctxPtr->prefixStart;
ctxPtr->dictLimit += (U32)(ctxPtr->end - ctxPtr->prefixStart);
ctxPtr->prefixStart = newBlock;
ctxPtr->dictLimit = (U32)(ctxPtr->end - ctxPtr->base);
ctxPtr->dictBase = ctxPtr->base;
ctxPtr->base = newBlock - ctxPtr->dictLimit;
ctxPtr->end = newBlock;
ctxPtr->nextToUpdate = ctxPtr->dictLimit; /* match referencing will resume from there */
@ -1122,11 +1112,11 @@ LZ4_compressHC_continue_generic (LZ4_streamHC_t* LZ4_streamHCPtr,
LZ4_streamHCPtr, src, *srcSizePtr, limit);
assert(ctxPtr != NULL);
/* auto-init if forgotten */
if (ctxPtr->prefixStart == NULL) LZ4HC_init_internal (ctxPtr, (const BYTE*) src);
if (ctxPtr->base == NULL) LZ4HC_init_internal (ctxPtr, (const BYTE*) src);
/* Check overflow */
if ((size_t)(ctxPtr->end - ctxPtr->prefixStart) + ctxPtr->dictLimit > 2 GB) {
size_t dictSize = (size_t)(ctxPtr->end - ctxPtr->prefixStart);
if ((size_t)(ctxPtr->end - ctxPtr->base) > 2 GB) {
size_t dictSize = (size_t)(ctxPtr->end - ctxPtr->base) - ctxPtr->dictLimit;
if (dictSize > 64 KB) dictSize = 64 KB;
LZ4_loadDictHC(LZ4_streamHCPtr, (const char*)(ctxPtr->end) - dictSize, (int)dictSize);
}
@ -1137,16 +1127,13 @@ LZ4_compressHC_continue_generic (LZ4_streamHC_t* LZ4_streamHCPtr,
/* Check overlapping input/dictionary space */
{ const BYTE* sourceEnd = (const BYTE*) src + *srcSizePtr;
const BYTE* const dictBegin = ctxPtr->dictStart;
const BYTE* const dictEnd = ctxPtr->dictStart + (ctxPtr->dictLimit - ctxPtr->lowLimit);
const BYTE* const dictBegin = ctxPtr->dictBase + ctxPtr->lowLimit;
const BYTE* const dictEnd = ctxPtr->dictBase + ctxPtr->dictLimit;
if ((sourceEnd > dictBegin) && ((const BYTE*)src < dictEnd)) {
if (sourceEnd > dictEnd) sourceEnd = dictEnd;
ctxPtr->lowLimit += (U32)(sourceEnd - ctxPtr->dictStart);
ctxPtr->dictStart += (U32)(sourceEnd - ctxPtr->dictStart);
if (ctxPtr->dictLimit - ctxPtr->lowLimit < 4) {
ctxPtr->lowLimit = ctxPtr->dictLimit;
ctxPtr->dictStart = ctxPtr->prefixStart;
} } }
ctxPtr->lowLimit = (U32)(sourceEnd - ctxPtr->dictBase);
if (ctxPtr->dictLimit - ctxPtr->lowLimit < 4) ctxPtr->lowLimit = ctxPtr->dictLimit;
} }
return LZ4HC_compress_generic (ctxPtr, src, dst, srcSizePtr, dstCapacity, ctxPtr->compressionLevel, limit);
}
@ -1174,7 +1161,7 @@ int LZ4_compress_HC_continue_destSize (LZ4_streamHC_t* LZ4_streamHCPtr, const ch
int LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int dictSize)
{
LZ4HC_CCtx_internal* const streamPtr = &LZ4_streamHCPtr->internal_donotuse;
int const prefixSize = (int)(streamPtr->end - streamPtr->prefixStart);
int const prefixSize = (int)(streamPtr->end - (streamPtr->base + streamPtr->dictLimit));
DEBUGLOG(5, "LZ4_saveDictHC(%p, %p, %d)", LZ4_streamHCPtr, safeBuffer, dictSize);
assert(prefixSize >= 0);
if (dictSize > 64 KB) dictSize = 64 KB;
@ -1182,13 +1169,12 @@ int LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int dictS
if (dictSize > prefixSize) dictSize = prefixSize;
if (safeBuffer == NULL) assert(dictSize == 0);
if (dictSize > 0)
LZ4_memmove(safeBuffer, streamPtr->end - dictSize, dictSize);
{ U32 const endIndex = (U32)(streamPtr->end - streamPtr->prefixStart) + streamPtr->dictLimit;
memmove(safeBuffer, streamPtr->end - dictSize, dictSize);
{ U32 const endIndex = (U32)(streamPtr->end - streamPtr->base);
streamPtr->end = (const BYTE*)safeBuffer + dictSize;
streamPtr->prefixStart = streamPtr->end - dictSize;
streamPtr->base = streamPtr->end - endIndex;
streamPtr->dictLimit = endIndex - (U32)dictSize;
streamPtr->lowLimit = endIndex - (U32)dictSize;
streamPtr->dictStart = streamPtr->prefixStart;
if (streamPtr->nextToUpdate < streamPtr->dictLimit)
streamPtr->nextToUpdate = streamPtr->dictLimit;
}
@ -1216,7 +1202,7 @@ int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* ctx, const char* src,
/* Deprecated streaming functions */
int LZ4_sizeofStreamStateHC(void) { return sizeof(LZ4_streamHC_t); }
int LZ4_sizeofStreamStateHC(void) { return LZ4_STREAMHCSIZE; }
/* state is presumed correctly sized, aka >= sizeof(LZ4_streamHC_t)
* @return : 0 on success, !=0 if error */
@ -1228,7 +1214,6 @@ int LZ4_resetStreamStateHC(void* state, char* inputBuffer)
return 0;
}
#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION)
void* LZ4_createHC (const char* inputBuffer)
{
LZ4_streamHC_t* const hc4 = LZ4_createStreamHC();
@ -1243,7 +1228,6 @@ int LZ4_freeHC (void* LZ4HC_Data)
FREEMEM(LZ4HC_Data);
return 0;
}
#endif
int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* src, char* dst, int srcSize, int cLevel)
{
@ -1257,11 +1241,11 @@ int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* src, c
char* LZ4_slideInputBufferHC(void* LZ4HC_Data)
{
LZ4_streamHC_t* const ctx = (LZ4_streamHC_t*)LZ4HC_Data;
const BYTE* bufferStart = ctx->internal_donotuse.prefixStart - ctx->internal_donotuse.dictLimit + ctx->internal_donotuse.lowLimit;
LZ4_streamHC_t *ctx = (LZ4_streamHC_t*)LZ4HC_Data;
const BYTE *bufferStart = ctx->internal_donotuse.base + ctx->internal_donotuse.lowLimit;
LZ4_resetStreamHC_fast(ctx, ctx->internal_donotuse.compressionLevel);
/* avoid const char * -> char * conversion warning :( */
return (char*)(uptrval)bufferStart;
return (char *)(uptrval)bufferStart;
}
@ -1344,7 +1328,7 @@ static int LZ4HC_compress_optimal ( LZ4HC_CCtx_internal* ctx,
{
int retval = 0;
#define TRAILING_LITERALS 3
#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
#ifdef LZ4HC_HEAPMODE
LZ4HC_optimal_t* const opt = (LZ4HC_optimal_t*)ALLOC(sizeof(LZ4HC_optimal_t) * (LZ4_OPT_NUM + TRAILING_LITERALS));
#else
LZ4HC_optimal_t opt[LZ4_OPT_NUM + TRAILING_LITERALS]; /* ~64 KB, which is a bit large for stack... */
@ -1362,7 +1346,7 @@ static int LZ4HC_compress_optimal ( LZ4HC_CCtx_internal* ctx,
const BYTE* ovref = NULL;
/* init */
#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
#ifdef LZ4HC_HEAPMODE
if (opt == NULL) goto _return_label;
#endif
DEBUGLOG(5, "LZ4HC_compress_optimal(dst=%p, dstCapa=%u)", dst, (unsigned)dstCapacity);
@ -1594,7 +1578,7 @@ _last_literals:
} else {
*op++ = (BYTE)(lastRunSize << ML_BITS);
}
LZ4_memcpy(op, anchor, lastRunSize);
memcpy(op, anchor, lastRunSize);
op += lastRunSize;
}
@ -1627,7 +1611,7 @@ if (limit == fillOutput) {
goto _last_literals;
}
_return_label:
#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
#ifdef LZ4HC_HEAPMODE
FREEMEM(opt);
#endif
return retval;

View File

@ -1,7 +1,7 @@
/*
LZ4 HC - High Compression Mode of LZ4
Header File
Copyright (C) 2011-2020, Yann Collet.
Copyright (C) 2011-2017, 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
@ -196,17 +196,14 @@ LZ4LIB_API int LZ4_saveDictHC (LZ4_streamHC_t* streamHCPtr, char* safeBuffer, in
#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 */
const LZ4_byte* base; /* All index relative to this position */
const LZ4_byte* dictBase; /* alternate base 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 */
@ -217,15 +214,20 @@ struct LZ4HC_CCtx_internal
const LZ4HC_CCtx_internal* dictCtx;
};
#define LZ4_STREAMHC_MINSIZE 262200 /* static size, for inter-version compatibility */
/* Do not use these definitions directly !
* Declare or allocate an LZ4_streamHC_t instead.
*/
#define LZ4_STREAMHCSIZE 262200 /* static size, for inter-version compatibility */
#define LZ4_STREAMHCSIZE_VOIDP (LZ4_STREAMHCSIZE / sizeof(void*))
union LZ4_streamHC_u {
char minStateSize[LZ4_STREAMHC_MINSIZE];
void* table[LZ4_STREAMHCSIZE_VOIDP];
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.
* This can be used to allocate statically, on state, or as part of a larger structure.
*
* Such state **must** be initialized using LZ4_initStreamHC() before first use.
*
@ -240,7 +242,7 @@ union LZ4_streamHC_u {
* 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);
LZ4LIB_API LZ4_streamHC_t* LZ4_initStreamHC (void* buffer, size_t size);
/*-************************************
@ -268,11 +270,9 @@ LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_comp
* 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_freeStreamHC() instead") LZ4LIB_API int LZ4_freeHC (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);
@ -300,7 +300,7 @@ LZ4LIB_API void LZ4_resetStreamHC (LZ4_streamHC_t* streamHCPtr, int compressionL
* 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.
* after successfull usage in real-life scenarios.
***************************************************/
#ifdef LZ4_HC_STATIC_LINKING_ONLY /* protection macro */
#ifndef TRACY_LZ4_HC_SLO_098092834

13
common/unix-debug.mk Normal file
View File

@ -0,0 +1,13 @@
ARCH := $(shell uname -m)
ifeq (1,$(shell $(CC) --version | grep clang > /dev/null && echo 1 || echo 0))
ifeq (1,$(shell ld.mold --version > /dev/null 2> /dev/null && echo 1 || echo 0))
LDFLAGS := -fuse-ld=mold
endif
endif
ifndef TRACY_NO_ISA_EXTENSIONS
ifeq ($(ARCH),x86_64)
CFLAGS += -msse4.1
endif
endif

19
common/unix-release.mk Normal file
View File

@ -0,0 +1,19 @@
ARCH := $(shell uname -m)
ifeq (0,$(shell $(CC) --version | grep clang > /dev/null && echo 1 || echo 0))
CFLAGS += -s
else
ifeq (1,$(shell ld.mold --version > /dev/null 2> /dev/null && echo 1 || echo 0))
LDFLAGS := -s -fuse-ld=mold
else
LDFLAGS := -s
endif
endif
ifndef TRACY_NO_ISA_EXTENSIONS
ifneq (,$(filter $(ARCH),aarch64 arm64))
CFLAGS += -mcpu=native
else
CFLAGS += -march=native
endif
endif

82
common/unix.mk Normal file
View File

@ -0,0 +1,82 @@
# Common code needed by most Tracy Unix Makefiles.
# Ensure these are simply-substituted variables, without changing their values.
LIBS := $(LIBS)
# Tracy does not use TBB directly, but the implementation of parallel algorithms
# in some versions of libstdc++ depends on TBB. When it does, you must
# explicitly link against -ltbb.
#
# Some distributions have pgk-config files for TBB, others don't.
ifeq (0,$(shell pkg-config --libs tbb >/dev/null 2>&1; echo $$?))
LIBS += $(shell pkg-config --libs tbb)
else ifeq (0,$(shell ld -ltbb -o /dev/null 2>/dev/null; echo $$?))
LIBS += -ltbb
endif
OBJDIRBASE := obj/$(BUILD)
OBJDIR := $(OBJDIRBASE)/o/o/o
OBJ := $(addprefix $(OBJDIR)/,$(SRC:%.cpp=%.o))
OBJ2 := $(addprefix $(OBJDIR)/,$(SRC2:%.c=%.o))
OBJ3 := $(addprefix $(OBJDIR)/,$(SRC3:%.m=%.o))
OBJ4 := $(addprefix $(OBJDIR)/,$(SRC4:%.S=%.o))
all: $(IMAGE)
$(OBJDIR)/%.o: %.cpp
$(CXX) -c $(INCLUDES) $(CXXFLAGS) $(DEFINES) $< -o $@
$(OBJDIR)/%.d : %.cpp
@echo Resolving dependencies of $<
@mkdir -p $(@D)
@$(CXX) -MM $(INCLUDES) $(CXXFLAGS) $(DEFINES) $< > $@.$$$$; \
sed 's,.*\.o[ :]*,$(OBJDIR)/$(<:.cpp=.o) $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
$(OBJDIR)/%.o: %.c
$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
$(OBJDIR)/%.d : %.c
@echo Resolving dependencies of $<
@mkdir -p $(@D)
@$(CC) -MM $(INCLUDES) $(CFLAGS) $(DEFINES) $< > $@.$$$$; \
sed 's,.*\.o[ :]*,$(OBJDIR)/$(<:.c=.o) $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
$(OBJDIR)/%.o: %.m
$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
$(OBJDIR)/%.d : %.m
@echo Resolving dependencies of $<
@mkdir -p $(@D)
@$(CC) -MM $(INCLUDES) $(CFLAGS) $(DEFINES) $< > $@.$$$$; \
sed 's,.*\.o[ :]*,$(OBJDIR)/$(<:.m=.o) $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
$(OBJDIR)/%.o: %.S
$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
$(OBJDIR)/%.d : %.S
@echo Resolving dependencies of $<
@mkdir -p $(@D)
@$(CC) -MM $(INCLUDES) $(CFLAGS) $(DEFINES) $< > $@.$$$$; \
sed 's,.*\.o[ :]*,$(OBJDIR)/$(<:.m=.o) $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
ifeq (yes,$(SHARED_LIBRARY))
$(IMAGE): $(OBJ) $(OBJ2) $(OBJ4)
$(CXX) $(CXXFLAGS) $(LDFLAGS) $(DEFINES) $(OBJ) $(OBJ2) $(OBJ4) $(LIBS) -shared -o $@
else
$(IMAGE): $(OBJ) $(OBJ2) $(OBJ3) $(OBJ4)
$(CXX) $(CXXFLAGS) $(LDFLAGS) $(DEFINES) $(OBJ) $(OBJ2) $(OBJ3) $(OBJ4) $(LIBS) -o $@
endif
ifneq "$(MAKECMDGOALS)" "clean"
-include $(addprefix $(OBJDIR)/,$(SRC:.cpp=.d)) $(addprefix $(OBJDIR)/,$(SRC2:.c=.d)) $(addprefix $(OBJDIR)/,$(SRC3:.m=.d)) $(addprefix $(OBJDIR)/,$(SRC4:.S=.d))
endif
clean:
rm -rf $(OBJDIRBASE) $(IMAGE)*
.PHONY: clean all

View File

@ -1,29 +0,0 @@
cmake_minimum_required(VERSION 3.16)
option(NO_ISA_EXTENSIONS "Disable ISA extensions (don't pass -march=native or -mcpu=native to the compiler)" OFF)
set(NO_STATISTICS OFF)
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/version.cmake)
set(CMAKE_CXX_STANDARD 20)
project(
tracy-csvexport
LANGUAGES C CXX
VERSION ${TRACY_VERSION_STRING}
)
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/config.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/vendor.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/server.cmake)
set(PROGRAM_FILES
src/csvexport.cpp
)
add_executable(${PROJECT_NAME} ${PROGRAM_FILES} ${COMMON_FILES} ${SERVER_FILES})
target_link_libraries(${PROJECT_NAME} PRIVATE TracyServer TracyGetOpt)
set_property(DIRECTORY ${CMAKE_CURRENT_LIST_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME})
install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})

View File

@ -0,0 +1,16 @@
all: release
debug:
@+make -f debug.mk all
release:
@+make -f release.mk all
clean:
@+make -f build.mk clean
db: clean
@bear -- $(MAKE) -f debug.mk all
@mv -f compile_commands.json ../../../
.PHONY: all clean debug release db

Some files were not shown because too many files have changed in this diff Show More