Compare commits

...

1707 Commits

Author SHA1 Message Date
Bartosz Taudul
280475ff3d Iterate ranges array when drawing ranges on timeline. 2026-06-23 23:45:41 +02:00
Bartosz Taudul
922604fe6a Do not include alpha in color entries in ranges array. 2026-06-23 23:45:11 +02:00
Bartosz Taudul
5b29550ded Move ranges setup to an appropriate file. 2026-06-23 23:29:33 +02:00
Bartosz Taudul
56eb3b776f Show ranges window after setting a range via timeline right-click popup.
Without this using the popup is quite unintuitive. Setting the range
apparently does not have an effect – because ranges are only shown if the
ranges window is open (or the windows appropriate for each of the ranges).
2026-06-23 23:07:27 +02:00
Bartosz Taudul
98ad778495 Iterate ranges array to handle range adjustments by mouse. 2026-06-23 23:06:02 +02:00
Bartosz Taudul
fa4c28af8a Iterate ranges array in timeline right-click menu. 2026-06-23 23:03:26 +02:00
Bartosz Taudul
a73a733644 Popup label is now just label, do not pass it twice. 2026-06-23 22:54:09 +02:00
Bartosz Taudul
d4cceb3e0d Use ranges array in DrawRangeEntry(). 2026-06-23 22:45:45 +02:00
Bartosz Taudul
b715c0c32e Add icon to annotation tooltip. 2026-06-23 22:41:18 +02:00
Bartosz Taudul
f71620c8c8 Use ranges array in DrawRanges(). 2026-06-23 22:33:07 +02:00
Bartosz Taudul
51e467d7b9 Make ranges private in View. 2026-06-23 21:50:22 +02:00
Bartosz Taudul
eba8c1e99a Setup ranges array. 2026-06-23 21:49:15 +02:00
Bartosz Taudul
9a785976c0 Ignore zero-length sections. 2026-06-23 02:00:11 +02:00
Bartosz Taudul
711e3a7bcf Add separator between timeline headers and content. 2026-06-23 01:58:35 +02:00
Bartosz Taudul
d84a085b71 Collapse small sections. 2026-06-23 01:58:35 +02:00
Bartosz Taudul
ae38665b95 Draw sections. 2026-06-22 19:17:01 +02:00
Bartosz Taudul
800e415400 Calculate section rows content. 2026-06-22 19:17:00 +02:00
Bartosz Taudul
f1dfedffaf Instrument program sections in dyna example. 2026-06-22 15:10:38 +02:00
Bartosz Taudul
67bb927d61 Store level name in World. 2026-06-22 15:10:28 +02:00
Bartosz Taudul
415197bd5d Remove semicolon from TracySetProgramName macro. 2026-06-22 14:57:25 +02:00
Bartosz Taudul
5177e587e9 Do not include semicolons in TracySectionEnter / TracySectionLeave macros. 2026-06-22 14:56:32 +02:00
Bartosz Taudul
ee7d2b4fd8 Track memory allocations in dyna example. 2026-06-21 23:25:42 +02:00
Bartosz Taudul
1d0806c374 Add frame image capture to the dyna example. 2026-06-21 23:12:52 +02:00
Bartosz Taudul
9cc8f3752e Mark zones in dyna example. 2026-06-21 23:05:20 +02:00
Bartosz Taudul
79e0efac96 Mark frame boundaries in dyna example. 2026-06-21 22:53:31 +02:00
Bartosz Taudul
8531e879a9 Use TracyNoop to ensure profiler library is linked with executable. 2026-06-21 22:47:34 +02:00
Bartosz Taudul
89a75d5c71 Integrate Tracy into dyna example. 2026-06-21 22:47:34 +02:00
Bartosz Taudul
e9e85ca6ee Add Dyna.net example. 2026-06-21 22:47:34 +02:00
Bartosz Taudul
3a6a23ca98 Save and load sections data. 2026-06-21 00:56:32 +02:00
Bartosz Taudul
3157dfae3e Merge pull request #1412 from jensenr30/fix-signed-int-comparison-warning
Fix warning [-Wsign-compare]
2026-06-21 00:32:51 +02:00
Ryan Jensen
978b720759 Fix warning [-Wsign-compare] 2026-06-20 17:09:26 -05:00
Bartosz Taudul
77c655eb7d Merge pull request #1411 from alandtse/feat/mcp-sections-accessor
feat(mcp): expose sections accessor in eval bindings
2026-06-20 11:49:45 +02:00
Alan Tse
bee6ac566e docs(mcp): drop dangling tracy://catalog reference
eval_guide.md referenced a tracy://catalog resource that was never
registered (only tracy://prompt and tracy://eval-guide exist), so an
agent following the guide would try to read a nonexistent resource.
Remove the references; the worked snippets the catalog described are
already inlined under "Common query patterns".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016EvfzHvUsDBSAwEzTfLTtA
2026-06-19 15:51:51 -07:00
Alan Tse
6e4041b14d feat(mcp): expose sections accessor in eval bindings
Bind Worker::GetSections() as get_sections() so the TracySectionEnter /
TracySectionLeave instrumentation added to the client is reachable from
the MCP eval tool's ctx object. Returns a list of {start, end, text}
dicts with nanosecond timestamps, matching the existing list-of-dict
accessor convention. Documented in eval_guide.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016EvfzHvUsDBSAwEzTfLTtA
2026-06-19 15:44:12 -07:00
Bartosz Taudul
1706ac57ac Separate id field is not needed. 2026-06-19 20:37:49 +02:00
Bartosz Taudul
72d62bea25 Display count of sections. 2026-06-19 20:37:49 +02:00
Bartosz Taudul
0ae37172dc Add sections accessor. 2026-06-19 20:37:45 +02:00
Bartosz Taudul
9502ab728d Merge pull request #1410 from shekhirin/alexey/mcp-streamable-http
feat(mcp): default to streamable-http transport
2026-06-19 19:45:51 +02:00
Alexey Shekhirin
7dd4dbc8a5 update docs 2026-06-19 18:36:03 +01:00
Alexey Shekhirin
96c681cf61 feat(mcp): default to streamable-http transport 2026-06-19 16:42:14 +01:00
Bartosz Taudul
2052aa2ab8 Regenerate markdown manual. 2026-06-19 15:05:58 +02:00
Bartosz Taudul
977218ea04 Document that ___tracy_alloc_srcloc strings must not be null-terminated. 2026-06-19 15:05:05 +02:00
Bartosz Taudul
fcd5944d5e Better default llm config. 2026-06-19 12:36:39 +02:00
Bartosz Taudul
34395f97ed Regenerate markdown manual. 2026-06-18 21:31:03 +02:00
Bartosz Taudul
c897729b74 Use safe file names for cache. 2026-06-18 21:30:07 +02:00
Bartosz Taudul
f8208ce5ef Add quick start guide for getting Tracy Assist running. 2026-06-18 21:21:15 +02:00
Bartosz Taudul
3516c96afd Retrieve available context on llama.cpp if not available on start.
In order for context size to be available, the model has to be loaded on
the server. However, the typical flow will be to load models on demand.
2026-06-18 21:00:25 +02:00
Bartosz Taudul
3bb5027565 Add llama.cpp tokenization support. 2026-06-18 20:58:40 +02:00
Bartosz Taudul
eefc7aee4b Detect llama.cpp router mode. 2026-06-18 20:56:07 +02:00
Bartosz Taudul
3ccda1d3c4 Add embedding model heuristic to not recognized llama API providers. 2026-06-18 20:51:53 +02:00
Bartosz Taudul
802e88585a Merge pull request #1407 from shekhirin/tracy-consistent-thread-order
feat: display threads in a consistent order
2026-06-18 14:41:20 +02:00
Alexey Shekhirin
74bbe5988b Use consistent thread order in more thread pickers 2026-06-18 09:41:45 +01:00
Alexey Shekhirin
066cb89f75 Display threads in a consistent order 2026-06-18 09:41:31 +01:00
Bartosz Taudul
8c289104d6 Regenerate markdown manual. 2026-06-18 00:39:26 +02:00
Bartosz Taudul
274e453bb6 Process section enter / leave events. 2026-06-17 22:37:31 +02:00
Bartosz Taudul
d89055908b Update manual. 2026-06-17 22:37:31 +02:00
Bartosz Taudul
801a34ea66 Add trigger parameter. 2026-06-17 22:37:31 +02:00
Bartosz Taudul
0cdb6d365e Initial section enter / leave instrumentation. 2026-06-17 22:37:31 +02:00
Bartosz Taudul
e3f4c72c85 Move TRACY_ATTRIBUTE_FORMAT_PRINTF to its own header. 2026-06-17 22:37:31 +02:00
Bartosz Taudul
eeab1bf1a9 Border sizes are scaled by ScaleAllSizes() since ImGui 1.92.7. 2026-06-17 22:37:30 +02:00
Bartosz Taudul
d26176baae Merge pull request #1406 from mcourteaux/fix-charconv
Implement C++ feature check for charconv.
2026-06-17 11:37:38 +02:00
Martijn Courteaux
021aa6a9e6 Implement C++ feature check for charconv. 2026-06-17 09:27:00 +02:00
Bartosz Taudul
8b86ada40e Fix checks. 2026-06-17 01:31:56 +02:00
Bartosz Taudul
616f33ff65 Consistent wait.time checks. 2026-06-17 01:31:01 +02:00
Bartosz Taudul
023cb20ba9 Only display wait reason or state if present. 2026-06-17 00:33:00 +02:00
Bartosz Taudul
073cd266ac Use proper thread id for wait stacks.
ContextSwitchData::Thread() is something related to fibers. Pass and use
known thread id from external context instead.
2026-06-17 00:21:51 +02:00
Bartosz Taudul
2e252d3988 Fix indentation level. 2026-06-17 00:14:03 +02:00
Bartosz Taudul
77978b68ca Explain wait stacks in callstack skill. 2026-06-16 23:53:41 +02:00
Bartosz Taudul
d9939362f5 Add wait stack data to the LLM attachment. 2026-06-16 23:53:40 +02:00
Bartosz Taudul
bba05bd3ad Update manual. 2026-06-16 23:33:16 +02:00
Bartosz Taudul
83a4a13cbd Display wait stack label and tooltip in callstack window. 2026-06-16 23:28:24 +02:00
Bartosz Taudul
9e9aabe9a1 Push CallstackViewWait to View::DrawCallstackTable(). 2026-06-16 23:18:40 +02:00
Bartosz Taudul
382a887ce9 Provide default values for View::DrawCallstackTable() parameters. 2026-06-16 23:17:47 +02:00
Bartosz Taudul
fbd1c55151 Extend View::ViewCallstack() to support optional wait stack data. 2026-06-16 23:10:43 +02:00
Bartosz Taudul
398bab8041 Store wait stack data in CallstackView. 2026-06-16 23:05:59 +02:00
Bartosz Taudul
69245e751b Cosmetics. 2026-06-16 23:05:58 +02:00
Bartosz Taudul
d571f2bd59 Fix integer trace parameter input field size. 2026-06-16 19:17:18 +02:00
Bartosz Taudul
781938317d Bump pugixml to 1.16. 2026-06-16 18:10:38 +02:00
Bartosz Taudul
f9365abe4f Do not use samplers in renderer.
Tracy requires some textures to have repeat wrapping mode set. The ImGui
implementation of samplers doesn't make it easy to achieve. Disalbe use
of samplers and rely on texture flags, as done originally.
2026-06-16 16:02:08 +02:00
Bartosz Taudul
3f91f35d59 Merge pull request #1403 from wolfpld/slomp/gl-feature-check
Add routine to check for GL features/extensions at run-time
2026-06-16 14:50:30 +02:00
Marcos Slomp
1de94aa856 add routine to check for GL features/extensions at run-time 2026-06-15 21:19:12 -07:00
Bartosz Taudul
ec1d5bd3d7 Merge pull request #1402 from wolfpld/slomp/webgpu-example-platform
Switch webgpu example to SDL3, plus patch edge-case for wgpu-native
2026-06-15 23:48:14 +02:00
Marcos Slomp
69af195c98 edge-case bug-fix (could cause wgpu-native to panic) 2026-06-15 13:14:28 -07:00
Marcos Slomp
60699c4a92 fixing win32 builds with SDL3 + WebGPU 2026-06-15 13:14:28 -07:00
Marcos Slomp
cc45cf6046 switch to SDL3 (no cmake fetch, just find_package) 2026-06-15 13:14:28 -07:00
Bartosz Taudul
62560a6429 Add 8-bit length string transfers to the protocol. 2026-06-15 20:43:55 +02:00
Bartosz Taudul
f7b4e177ff Change misleading etc1buf variable to texbuf. 2026-06-15 19:31:06 +02:00
Bartosz Taudul
084daf0516 Force inline send string strlen helpers. 2026-06-15 19:19:13 +02:00
Bartosz Taudul
a98956f2d9 Another typo. 2026-06-15 17:17:32 +02:00
Bartosz Taudul
ac6f0f88fa Actually describe the message severity levels. 2026-06-15 17:09:42 +02:00
Bartosz Taudul
33fccb3530 Typos. 2026-06-15 17:08:39 +02:00
Bartosz Taudul
45576f6972 Merge pull request #1400 from wolfpld/slomp/gl-example
adding OpenGL example (spinning triangle)
2026-06-14 21:39:54 +02:00
Marcos Slomp
17e13bc2e0 SDL2 -> SDL3 2026-06-14 12:18:06 -07:00
Marcos Slomp
ee0c73bf25 switch to SDL2 (no cmake fetch, just find_package) 2026-06-14 11:24:14 -07:00
Bartosz Taudul
343567a3f2 Regenerate markdown manual. 2026-06-14 17:31:49 +02:00
Bartosz Taudul
20b3535623 Use fancy quotes in the manual. 2026-06-14 17:31:32 +02:00
Bartosz Taudul
5298316480 Revert emscripten back to 5.0.7. There are threading problems with 6.0.0.
Specifically, click on the red power off button to go back to the welcome
screen, and the cleanup popup never goes away.
2026-06-14 16:24:13 +02:00
Bartosz Taudul
83719fb29b WASM_BIGINT is enabled by default since emscripten 4.0.0. 2026-06-14 15:17:32 +02:00
Bartosz Taudul
f7d789eddb Split emscripten link options to multiple lines. 2026-06-14 15:09:40 +02:00
Bartosz Taudul
3816b2485e Bump used emscripten version to 6.0.0. 2026-06-14 15:06:53 +02:00
Bartosz Taudul
f8aa88d522 Explicitly disable shared libs for md4c.
Fixes emscripten build.
2026-06-14 15:06:36 +02:00
Bartosz Taudul
b5ae187f76 Disable separate fast model by default. 2026-06-12 22:20:47 +02:00
Marcos Slomp
3f203806e2 X11 workaround check 2026-06-12 13:00:33 -07:00
Bartosz Taudul
15c6b49de2 Mark text embeds as TEXT. 2026-06-12 21:43:51 +02:00
Bartosz Taudul
a153f3a562 Extend Embed macro to support TEXT parameter enabling CRLF to LF conversion. 2026-06-12 21:43:12 +02:00
Bartosz Taudul
c2998310cf Add CRLF to LF conversion support to embed. 2026-06-12 21:42:45 +02:00
Bartosz Taudul
a43b74ed8f Update NEWS. 2026-06-12 21:08:33 +02:00
Bartosz Taudul
d3047f8069 Fix memory discard + callstack.
Bug (High Severity): Wrong queue type in MemDiscardCallstack

In the callstack path of MemDiscardCallstack, the wrong queue type is
sent:

  SendMemDiscard( QueueType::MemDiscard, thread, name );

Every other callstack variant correctly uses its callstack queue type
(MemAllocCallstack, MemFreeCallstack, etc.), but this one uses the
non-callstack type. The SendMemDiscard assertion at line 1026 confirms
MemDiscardCallstack is a valid value.

Impact: The callstack captured by SendCallstackSerial() will be orphaned.
The server processes the event via the non-callstack handler, leaving the
callstack serial data unconsumed, which desynchronizes the serial queue
and corrupts all subsequent events.
2026-06-12 20:30:59 +02:00
Bartosz Taudul
3804b2580a Regenerate markdown manual. 2026-06-12 19:58:06 +02:00
Bartosz Taudul
329ac6c9f1 Document memory discard macro. 2026-06-12 19:57:45 +02:00
Bartosz Taudul
a091bb4ad2 Remove "secure" variant of alloc/free.
Random crashes are not fun. Always use the "secure" code path.
2026-06-12 19:41:17 +02:00
Bartosz Taudul
86b5f43959 Provide proper test directory. 2026-06-12 19:23:28 +02:00
Marcos Slomp
39dc688340 adding Xrandr dependency 2026-06-12 08:44:46 -07:00
Marcos Slomp
832234838b better comments and messages 2026-06-12 07:33:06 -07:00
Marcos Slomp
daba5acfbc more explicit compiler warning message 2026-06-12 07:31:03 -07:00
Bartosz Taudul
07bfe3465e Merge pull request #1356 from wolfpld/slomp/tracy-webgpu
GPU: WebGPU back-end
2026-06-12 12:11:32 +02:00
Bartosz Taudul
0544440a34 Remove unused, extremely broken code. 2026-06-11 22:35:25 +02:00
Marcos Slomp
f287508772 addressing type conversion warning 2026-06-11 13:28:32 -07:00
Bartosz Taudul
f622b97436 Backdate init time when a producer token predates it.
A zone emitted from a shared object initializer runs before the
executable's constructors, so its timestamp precedes s_initTime, which
the server uses as the trace epoch (baseTime). Such a zone converts to
negative trace time and its end no longer satisfies IsEndValid(), which
excludes it from statistics reconstruction and makes it render as
never-ending.

Record the current time when a producer token is created before
s_initTime is constructed and use it as the init time, ensuring no event
timestamp precedes the trace epoch.
2026-06-11 20:05:59 +02:00
Bartosz Taudul
dfded9d55d Recover main thread producer orphaned by cross-module init order.
ELF init_priority only orders constructors within a single module. All of
a shared object's initializers run before any of the executable's, so an
instrumented dependency .so emitting a zone from its static initializer
creates the main thread producer token against the zero-initialized
s_queue. The queue constructor then resets the producer list, orphaning
that producer: every zone emitted on the main thread from that point on
is enqueued into blocks no consumer ever iterates and silently lost,
while sampling (worker thread producer) keeps working.

Re-link such a producer right after the queue is constructed. In the
common case, where nothing was emitted during shared object init, this
merely constructs the main thread token eagerly.
2026-06-11 20:05:57 +02:00
Marcos Slomp
a2555fbb33 fixing Windows/Linux build 2026-06-11 07:37:58 -07:00
Bartosz Taudul
7180ea381f Merge pull request #1401 from Lectem/fix/win32-non-desktop
`TRACY_WIN32_NO_DESKTOP` should use `GetVersionExW` explicitly.
2026-06-11 13:01:24 +02:00
Clément Grégoire
0c74658dd3 TRACY_WIN32_NO_DESKTOP should use GetVersionExW explicitly.
Since we use `RTL_OSVERSIONINFOW` we need to use W version explicitly
2026-06-11 12:06:34 +02:00
Marcos Slomp
debda1df55 scoping the GpuCtx constructor 2026-06-10 18:57:22 -07:00
Marcos Slomp
d98608b022 issue a Tracy warning message when timestamp queries are supported but not properly implemented 2026-06-10 18:52:57 -07:00
Marcos Slomp
eb88c6eba0 adding warning about TracyOpenGL usage on Apple devices 2026-06-10 18:52:09 -07:00
Marcos Slomp
e83429c926 replacing the various platform layers by RGFW 2026-06-10 18:38:48 -07:00
Bartosz Taudul
cc091a99a2 Support key modifiers on emscripten. 2026-06-10 23:39:08 +02:00
Marcos Slomp
1b207d3e2a adding OpenGL example (spinning triangle) 2026-06-10 14:14:54 -07:00
Bartosz Taudul
f89709e99e Prevent click-through when activating annotation. 2026-06-10 22:50:45 +02:00
Bartosz Taudul
a4c5f15312 Rewrite annotations drawing. 2026-06-10 22:42:05 +02:00
Bartosz Taudul
3455fd9f82 Fix regression making existing annotations non-editable after trace load. 2026-06-10 21:48:12 +02:00
Marcos Slomp
cfc046abcd refactoring requirements 2026-06-10 11:09:51 -07:00
Bartosz Taudul
9ab39d8af3 Merge pull request #1398 from Lectem/fix/concurrentqueue-and-malloc-define
WORKAROUND_malloc/free should properly route to tracy_malloc/free
2026-06-10 17:57:32 +02:00
Clément Grégoire
bfab6d03f4 WORKAROUND_malloc/free should properly route to tracy_malloc/free 2026-06-10 17:15:33 +02:00
Marcos Slomp
0d848c3042 proper device descriptor chaining 2026-06-10 08:03:18 -07:00
Marcos Slomp
54270d3fd5 move window to top when launching from console 2026-06-10 06:24:53 -07:00
Marcos Slomp
1341f98c61 cleanup 2026-06-10 06:24:32 -07:00
Marcos Slomp
6fc279eef4 more descriptive API name 2026-06-10 06:23:57 -07:00
Bartosz Taudul
66e4f5cef7 Merge pull request #1397 from MaximeCoutantSonos/master
Fixed typo inconsistency in Shared lock C api
2026-06-10 14:47:56 +02:00
MaximeCoutantSonos
7637971e9e Fixed typo inconsistency in Shared lock C api 2026-06-10 14:26:36 +02:00
Bartosz Taudul
4e3cffc4ba Add name bank related to games. 2026-06-10 01:34:40 +02:00
Marcos Slomp
28d3a91980 more changes to allow for null context 2026-06-09 16:26:51 -07:00
Bartosz Taudul
3956616fc2 Fix repeated entries. 2026-06-10 01:14:22 +02:00
Marcos Slomp
0fbb2eaaa4 typo 2026-06-09 16:00:43 -07:00
Marcos Slomp
b27dab4584 remove "spontaneous" callback (better determinism) 2026-06-09 15:59:38 -07:00
Marcos Slomp
75bee5370f cosmetics 2026-06-09 15:58:24 -07:00
Marcos Slomp
e7499458e9 allow scoped instrumentation to no-op with null context 2026-06-09 15:58:06 -07:00
Bartosz Taudul
d34c45fa5a Use variable structure for random name generator. 2026-06-10 00:27:18 +02:00
Bartosz Taudul
8fe5a511c9 Expand name generator banks. 2026-06-10 00:15:55 +02:00
Bartosz Taudul
afdd2e2f81 Regenerate markdown manual. 2026-06-09 23:49:57 +02:00
Bartosz Taudul
3c1b1b2f80 Update manual. 2026-06-09 23:48:14 +02:00
Bartosz Taudul
992134f85e Fix regression with no tooltips on disabled items. 2026-06-09 23:31:59 +02:00
Bartosz Taudul
37bc986584 Add button for re-rolling annotation name. 2026-06-09 23:27:07 +02:00
Bartosz Taudul
feb4e7c989 Generate random names for new annotations. 2026-06-09 23:24:58 +02:00
Bartosz Taudul
4a8fe6f56e Add button to generate random trace description. 2026-06-09 23:22:21 +02:00
Bartosz Taudul
a960a25285 Add random name generator. 2026-06-09 23:22:21 +02:00
Marcos Slomp
958cb8d7f8 WGPU_PATH fix 2026-06-09 12:56:34 -07:00
Marcos Slomp
59f17794a5 fixing MemWrite casts 2026-06-09 09:06:48 -07:00
Marcos Slomp
3b2c7dbacb fixing webgpu lib linkage based on WGPU_PATH 2026-06-09 09:06:48 -07:00
Marcos Slomp
56ed480ed2 relocating webgpu example 2026-06-09 09:06:48 -07:00
Marcos Slomp
0572c86551 Wayland woes... 2026-06-09 09:06:48 -07:00
Marcos Slomp
6499e3383b fix Linux build 2026-06-09 09:06:48 -07:00
Marcos Slomp
8278ace0c1 build fix 2026-06-09 09:06:48 -07:00
Marcos Slomp
5981eca141 adding webgpu example/demo 2026-06-09 09:06:48 -07:00
Marcos Slomp
1b2856b885 GPU context name 2026-06-09 09:06:48 -07:00
Marcos Slomp
118f18cf4b updating docs 2026-06-09 09:06:48 -07:00
Marcos Slomp
bfbc1d3bee missing interface, and more debugging 2026-06-09 09:06:48 -07:00
Marcos Slomp
831779508f minor fixes/comments 2026-06-09 09:06:48 -07:00
Marcos Slomp
286309af3f refactoring calibration estimations 2026-06-09 09:06:47 -07:00
Marcos Slomp
3db70a2237 refactoring 2026-06-09 09:06:47 -07:00
Marcos Slomp
da952f3f38 more refactoring 2026-06-09 09:06:47 -07:00
Marcos Slomp
efba4685ef more cleanup and refactoring 2026-06-09 09:06:47 -07:00
Marcos Slomp
598984c45d refactoring initial calibration 2026-06-09 09:06:47 -07:00
Marcos Slomp
860011c604 calibration stability 2026-06-09 09:06:47 -07:00
Marcos Slomp
0cdcbfc75d refactoring query resolve 2026-06-09 09:06:47 -07:00
Marcos Slomp
e5d4be95df getting rid of spontaneous callbacks 2026-06-09 09:06:47 -07:00
Marcos Slomp
7b3863d93d redesign... 2026-06-09 09:06:47 -07:00
Marcos Slomp
de2a18d964 initial prototype for WebGPU back-end 2026-06-09 09:06:47 -07:00
Marcos Slomp
9588912aa9 Speeding-up GitHub build-bots (#1392)
* disabling LTO when building the profiler on macos via the github workflow

* diagnosing where in the linking stage it's getting stuck

* fowrward declarations

* compilation time report

* trying clang build analyzer...

* reducing number of parallel workers

* limiting parallel workers on windows/linux as well

* re-enabling LTO on macos

* reverting forward declaration header include (emscripten is failing with them).

* reverting act changes

* removing comments
2026-06-09 11:21:09 +02:00
Bartosz Taudul
7ee4380f64 Merge pull request #1395 from MaximeCoutantSonos/master
Add support for Shared Locks in the C API
2026-06-08 17:34:17 +02:00
Bartosz Taudul
01e639db97 Merge pull request #1336 from bmilanich/rocm-on-demand-fix
TracyRocprof: fix on-demand profiling crash and missing context name
2026-06-08 17:06:45 +02:00
Basil Milanich
030e699eb5 Move rocprof on-demand repro to tests/ and convert to CMake
Conform to the new repo layout (master moved repros under tests/, e.g.
tests/cuda/repro/graph). Relocate examples/RocprofOnDemandRepro to
tests/rocprof/repro/on_demand and replace the hand-written Makefile with
a CMake build mirroring the CUDA repro: builds the HIP reproducer, wires
it as a ctest target, and optionally builds the check_gpu_ctx_name
verification helper against the Tracy server library.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 09:47:22 -05:00
Basil Milanich
16cdf3d645 Merge remote-tracking branch 'origin/master' into rocm-on-demand-fix
# Conflicts:
#	public/client/TracyRocprof.cpp
2026-06-08 09:43:07 -05:00
MaximeCoutantSonos
2f143491eb Fixed typo in grammar 2026-06-08 16:07:06 +02:00
MaximeCoutantSonos
796050ac1e Added documentation for the shared lock C API 2026-06-08 15:52:54 +02:00
MaximeCoutantSonos
31dbfef97d Added C shared lock to C-API 2026-06-08 15:19:00 +02:00
Bartosz Taudul
19519bbeb0 Merge pull request #1394 from bruno-dasilva/bruno/opengl-drift-correction
fix: add opengl drift correction for gpu zones
2026-06-07 22:50:40 +02:00
Bruno Da Silva
fc4f52e61d add opengl drift correction option to meson.options/meson.build 2026-06-07 20:14:36 +00:00
Bruno Da Silva
e2ac8f7973 fix: add opengl drift correction for gpu zones 2026-06-07 00:23:14 +00:00
Bartosz Taudul
e5aa8eba51 Merge pull request #1387 from Lectem/wip/offline-res-for-any-toolchain
Offline resolution for any toolchain
2026-06-06 14:48:54 +02:00
Clément Grégoire
7437c41514 Escape provided addr2line tool path 2026-06-06 14:47:24 +02:00
Bartosz Taudul
f441a5070b Wrap achievements column contents into child windows. 2026-06-06 13:19:56 +02:00
Bartosz Taudul
00b6abd67b Move achievements text to markdown files. 2026-06-06 13:19:55 +02:00
Bartosz Taudul
e4e3d75eb8 Add PDF link to built-in manual viewer. 2026-06-06 10:56:25 +02:00
Bartosz Taudul
fc5318dcad Some more markdown user manual compatibility fixes. 2026-06-06 01:53:05 +02:00
Bartosz Taudul
661c664b75 Converte LaTeX math in markdown to plain text. 2026-06-06 01:44:27 +02:00
Bartosz Taudul
6dbebca666 Reset user manual view scroll position after changing section from toc. 2026-06-06 01:28:24 +02:00
Bartosz Taudul
73d78ad517 Fix tables in markdown manual. 2026-06-06 01:25:49 +02:00
Bartosz Taudul
e5371d7987 Icons description separator must start at newline.
Otherwise it will clash with wrong things, like middle-of-line table header
separators.
2026-06-06 01:25:08 +02:00
Bartosz Taudul
9806f35714 Increase spacing between admonition icon and header text. 2026-06-06 00:43:09 +02:00
Bartosz Taudul
d40289d594 Add support for markdown admonitions. 2026-06-05 23:28:09 +02:00
Bartosz Taudul
86fbe529ed Bump font awesome to 7.2. 2026-06-05 23:28:09 +02:00
Bartosz Taudul
9b169ef3f9 Merge pull request #1391 from wolfpld/slomp/cuda-examples
Adding CUDA examples
2026-06-05 21:55:02 +02:00
Marcos Slomp
64797dc735 adding basic CUDA graph example 2026-06-05 12:52:08 -07:00
Bartosz Taudul
76797799c0 Merge pull request #1390 from wolfpld/slomp/cuda-tests
Relocating existing CUDA tests
2026-06-05 21:50:11 +02:00
Marcos Slomp
19549693a0 removing Makefile 2026-06-05 12:46:10 -07:00
Marcos Slomp
10d64d69b5 better ctest integration across the board 2026-06-05 12:46:10 -07:00
Marcos Slomp
d89c956394 CUPTI DLL paths... 2026-06-05 12:46:10 -07:00
Marcos Slomp
79467b4b31 cmake version shenanigans 2026-06-05 12:46:10 -07:00
Marcos Slomp
ae275f239d adding cmake recipe file 2026-06-05 12:46:10 -07:00
Marcos Slomp
77fb86155f relocating CUDAGraphRepro "example" to the tests folder 2026-06-05 12:46:10 -07:00
Bartosz Taudul
e627fcce98 Merge pull request #1386 from wolfpld/slomp/test-relocation
Relocating Tracy test app, plus GitHub actions
2026-06-05 21:19:22 +02:00
Bartosz Taudul
e80893ac20 Reset font size when displaying markdown tooltip. 2026-06-05 19:19:37 +02:00
Bartosz Taudul
912f8c048c Render footnotes in smaller size font. 2026-06-05 19:17:46 +02:00
Bartosz Taudul
d16f627cbc Header sizes are 1-6, remove extra entry. 2026-06-05 19:12:04 +02:00
Clément Grégoire
7cb98245ce Batch addr2line invocations by command-line length
The fixed batches of 1024 addresses could overflow the platform's command-line limit (`La ligne de commande est trop longue.` from cmd.exe on Windows, whose limit is ~8191 characters). Build each batch by appending addresses until a length budget is reached instead. A single conservative budget of 8000 stays under the smallest limit on every platform, and keeps batches in the same ballpark as before (several hundred addresses per invocation).
2026-06-05 19:10:19 +02:00
Bartosz Taudul
3974cc8026 Add support for proper rendering of markdown footnotes. 2026-06-05 19:09:49 +02:00
Clément Grégoire
55d5436fb9 Add option to reset callstack frame symbols to the unresolved state
The new `-R` option of tracy-update sets every callstack frame back to `[unresolved]` / `[unknown]`. Since failed lookups leave frames untouched and the image-relative offset in `symAddr` survives patching, this makes it possible to chain several resolution passes over the same capture, each with different `-p` path substitutions (e.g. one pass per symbol directory).
2026-06-05 19:03:35 +02:00
Clément Grégoire
2b11785b05 Allow offline symbol resolution with any addr2line-compatible tool
The addr2line backend of tracy-update now builds on every platform, including Windows, and can be pointed at any addr2line-compatible executable:

- `-a`: path to a custom symbol resolution tool (e.g. `llvm-addr2line` or a cross-compilation toolchain's `addr2line`). Works on all platforms and takes precedence over the platform default (DbgHelp on Windows, the `addr2line` found in `PATH` elsewhere). Path-like values are validated up front so a wrong path fails with an actionable message instead of a cryptic, localized shell error.
- `-A`: extra arguments passed verbatim to the tool, e.g. `--relative-address` so `llvm-addr2line`/`llvm-symbolizer` accept the image-relative offsets Tracy records for images with a non-zero preferred base (PE, Mach-O).
- `-v`: verbose output while patching symbols.
2026-06-05 19:03:35 +02:00
Bartosz Taudul
715815374d Rebuild markdown manual. 2026-06-05 18:42:50 +02:00
Bartosz Taudul
4f64b974c6 Update manual. 2026-06-05 18:42:24 +02:00
Bartosz Taudul
7c58db4c0a Add public sidecar icon. 2026-06-05 18:40:18 +02:00
Marcos Slomp
f9f772e507 quick (attempted) fix for the Linux workflow linkage error 2026-06-05 09:14:22 -07:00
Marcos Slomp
af2a369dff re-documenting each action step 2026-06-05 09:08:07 -07:00
Bartosz Taudul
bebf20846f Expose setting public sidecar in UI. 2026-06-05 17:45:58 +02:00
Bartosz Taudul
5f6bc2238a Public user data sidecar support. 2026-06-05 17:45:58 +02:00
Bartosz Taudul
4564a626b2 UserData::Save() returns success status. 2026-06-05 17:40:22 +02:00
Bartosz Taudul
e95a757e6c Store trace file path in UserData. 2026-06-05 17:32:46 +02:00
Marcos Slomp
2ebf18be7f adjusting relative path 2026-06-05 08:25:59 -07:00
Bartosz Taudul
fc97af4c68 Redirect unlink to _unlink with msvc. 2026-06-05 17:23:58 +02:00
Bartosz Taudul
8eada19734 Add a separate function to retrieve sidecar path. 2026-06-05 17:21:24 +02:00
Marcos Slomp
a56b08e539 adding test application to windows and macos github workflows 2026-06-05 08:19:07 -07:00
Marcos Slomp
9c9dca8ea5 relocating tracy test app, and consolidating github test action 2026-06-05 08:17:29 -07:00
Bartosz Taudul
268cab7f89 Remove UserData::GetConfigLocation(). 2026-06-05 17:03:23 +02:00
Bartosz Taudul
aeda64d36b Move saving user data to a separate function. 2026-06-05 15:58:07 +02:00
Bartosz Taudul
f5526d01a2 Merge pull request #1385 from nitrix/bump-cmake-313
Bump CMake min version to 3.13
2026-06-05 00:01:22 +02:00
Bartosz Taudul
20e6835da6 Fix remaining MemWrites. 2026-06-05 00:00:04 +02:00
Bartosz Taudul
6b92ec1a23 Message queue item is already in the right format.
After swapping ptr and tag in TaggedUserlandAddress, the tag part aligns
exactly with the metadata field.
2026-06-04 20:08:07 +02:00
Bartosz Taudul
45e90549aa Rewrite TaggedUserlandAddress.
Drop dead code. Move tag to low bits, keep ptr at high bits. Protocol bump,
as TaggedUserlandAddress is used to transmit "literal" messages.
2026-06-04 19:37:47 +02:00
Bartosz Taudul
1690ac0d9d Force inlining of TaggedUserlandAddress. 2026-06-04 12:31:08 +02:00
Bartosz Taudul
a8fab8c977 Cosmetics. 2026-06-04 12:30:51 +02:00
Bartosz Taudul
a0b50ee68e Tabs to spaces. 2026-06-04 12:27:03 +02:00
Bartosz Taudul
896a59d00b Simplify. 2026-06-04 12:11:14 +02:00
Bartosz Taudul
d3db50c201 Mingw fixes. 2026-06-04 12:08:53 +02:00
Alex Belanger
21434e9877 Bump CMake min version to 3.13 2026-06-04 00:27:43 -04:00
Bartosz Taudul
185482c0d9 MemRead deduces returned type from pointer. 2026-06-04 00:49:02 +02:00
Bartosz Taudul
a27dae3e88 Enforce same type in MemWrite. 2026-06-04 00:49:02 +02:00
Bartosz Taudul
7d139a7bf1 Use proper data types for MemWrite. 2026-06-04 00:49:02 +02:00
Bartosz Taudul
02e279bd38 Unaligned memory reads must go via MemRead. 2026-06-04 00:00:08 +02:00
Bartosz Taudul
4e593d91f5 Enable color diagnostics when building library. 2026-06-03 23:48:05 +02:00
Bartosz Taudul
75e721cf0c More subtle range limits visualization. 2026-06-03 23:38:58 +02:00
Bartosz Taudul
c4321bc83c Merge pull request #1383 from wolfpld/slomp/cuda-version
bumping "down" CUDA version
2026-06-03 20:35:54 +02:00
Marcos Slomp
224ff6d0e8 bumping "down" CUDA version 2026-06-03 11:05:06 -07:00
Bartosz Taudul
cc76d0f60e Save per-trace user options in a json sidecar. 2026-06-03 02:03:07 +02:00
Bartosz Taudul
d4d1f78263 Refactor TracyUserData. 2026-06-03 00:00:45 +02:00
Bartosz Taudul
c570288145 Store annotation pointers as shared_ptr. 2026-06-02 01:13:33 +02:00
Bartosz Taudul
98b61e0096 Rename Save* to Store* in TracyUserData. 2026-06-02 01:00:31 +02:00
Bartosz Taudul
5c75032cad Fix typo. 2026-06-02 00:09:27 +02:00
Bartosz Taudul
1381b427db Merge pull request #1379 from wolfpld/slomp/cuda-version-doc
Document and check for required CUDA version
2026-06-01 22:21:40 +02:00
Marcos Slomp
21b9f50cea CUDA version check 2026-06-01 11:25:40 -07:00
Marcos Slomp
cbad012980 typo 2026-06-01 11:09:01 -07:00
Marcos Slomp
d4298f7794 document CUDA version 2026-06-01 11:06:59 -07:00
Bartosz Taudul
f113bbb212 Do not mix loading file data with regex validation. 2026-06-01 00:44:11 +02:00
Bartosz Taudul
0b4128f76c Move source regex validation to a helper function. 2026-06-01 00:40:08 +02:00
Bartosz Taudul
bab8c8eb54 Remove compatibility with vastly obsolete user data file format. 2026-06-01 00:33:39 +02:00
Bartosz Taudul
cbe5347593 Cleanup. 2026-06-01 00:32:05 +02:00
Bartosz Taudul
189e8a1a89 Regenerate markdown manual. 2026-05-30 19:00:39 +02:00
Bartosz Taudul
a5316d525c Crash marker on the timeline also should directly open crash call stack. 2026-05-30 18:58:27 +02:00
Bartosz Taudul
c3e9ff17da Update manual. 2026-05-30 18:34:42 +02:00
Bartosz Taudul
0cf438a78e Add arrows to bottom-up / top-down tree labels. 2026-05-30 18:13:14 +02:00
Bartosz Taudul
e37b12aacb Add icon notification for chat suggestions. 2026-05-30 17:36:33 +02:00
Bartosz Taudul
dd53f721ac Go directly to crash callstack from crash notification. 2026-05-30 15:59:57 +02:00
Bartosz Taudul
058d5ca7c3 Center timeline on crash if clicked on crash text in callstack window. 2026-05-30 15:58:19 +02:00
Bartosz Taudul
eef525243d Add crash tooltip to crash callstack window. 2026-05-30 15:55:16 +02:00
Bartosz Taudul
1f2bbe918f Move Tracy Assist subsection to a section in the user manual. 2026-05-30 15:24:10 +02:00
Bartosz Taudul
0089fab94c Update NEWS. 2026-05-30 15:07:15 +02:00
Bartosz Taudul
0778ef85c6 Draw external frames dimmed in sample entry stacks. 2026-05-30 02:00:45 +02:00
Bartosz Taudul
5e6d872940 Symbol function address column was too narrow. 2026-05-30 01:26:43 +02:00
Bartosz Taudul
b7ed5bd9ef Dim external entries in symbol functions lists. 2026-05-30 01:24:10 +02:00
Bartosz Taudul
de1f84d52b Fix positioning of hotness indicators. 2026-05-29 18:16:14 +02:00
Bartosz Taudul
9f88bc6d04 Bump capstone. 2026-05-29 18:16:14 +02:00
Bartosz Taudul
bd0ba00513 Merge pull request #1377 from siliceum/fix/non-desktop-win32
Fix non desktop win32 build
2026-05-29 17:55:11 +02:00
Clément Grégoire
0e52e387bd gate GetUserNameExA behind TRACY_WIN32_NO_DESKTOP
Same as `GetUserNameA` in `GetUserLogin`
2026-05-29 17:51:33 +02:00
Clément Grégoire
e93ddd2aa7 When using the MSVC C runtime, fileno doesn't actually exist, use _fileno instead.
OLDNAMES.lib may not be linked if you use /NODEFAULTLIB.
Note: This uses `_MSC_VER` as a gate and not _WIN32 as MinGW apparently uses `fileno` and not `_fileno`.
2026-05-29 17:51:30 +02:00
Bartosz Taudul
33905b2f15 Dim external frames in local call stacks. 2026-05-29 00:34:05 +02:00
Bartosz Taudul
d06755652f Merge pull request #1374 from rmarker/flameView
Allow zooming and panning the flamegraph view.
2026-05-28 20:18:45 +02:00
Bartosz Taudul
dbdbd710d8 Add readme file for the user manual directory. 2026-05-28 18:39:00 +02:00
rmarker
15ee99ae41 Add animated zooming to the flame graph view. 2026-05-28 22:02:11 +09:30
rmarker
17f6be4ad4 Extract UpdateZoomAnimation.
This will allow for it to be used in the flame graph.
2026-05-28 22:01:03 +09:30
rmarker
30fd92de0f Handle partial panning in flame graph view.
When zoomed in very far the panning resolution can be so small that it
is less than one unit. In order to continue panning, we store partial
pans so that they can accumulate across frames.
2026-05-28 21:59:33 +09:30
rmarker
0b27b9ec1a Allow zooming in further to the flame graph. 2026-05-28 21:51:41 +09:30
rmarker
cc4b7dcea9 Add a reset view button to the flame graph. 2026-05-28 21:50:19 +09:30
rmarker
4a9e3ea095 Add a horizontal position bar to flame graph.
Now that the ruler just shows the delta time across the view it doesn't
indicate where the view is currently looking.
The new position bar fills this role to allow orientating oneself.
2026-05-28 21:48:14 +09:30
rmarker
55de5bc5ca Update flame graph ruler to measure the time shown in the current view.
It now starts at 0 and shows the time delta across the view.
2026-05-28 21:39:03 +09:30
rmarker
2e87eecc67 Support the live capture case in the flame graph view.
Zooming and panning in the flame graph view shouldn't cause visual
glitches when live data is being captured.
2026-05-28 21:37:01 +09:30
Bartosz Taudul
74eea83051 Merge pull request #1375 from wolfpld/slomp/vulkan-calibration-patch
GPU: Vulkan: upper-bound to the calibration loop
2026-05-28 11:37:00 +02:00
Marcos Slomp
c9fa58f2bb keep preprocessor directives idented to the margin 2026-05-27 16:12:24 -07:00
Marcos Slomp
b7fdc8c0eb newlines 2026-05-27 15:54:03 -07:00
Bartosz Taudul
f5581d7dcb Focus opened manual chapter in the manual tree. 2026-05-27 22:34:04 +02:00
Bartosz Taudul
b682a77f82 Focus the manual window on chapter change. 2026-05-27 22:34:04 +02:00
Bartosz Taudul
800334a953 Show nicer title page of embedded user manual. 2026-05-27 22:34:04 +02:00
Bartosz Taudul
9da66d4c6b Add icon texture accessor. 2026-05-27 22:33:56 +02:00
Bartosz Taudul
04c1a84159 Do not display icon explainer section in the built-in manual viewer. 2026-05-27 01:52:11 +02:00
Bartosz Taudul
b736e4590e Rebuild markdown manual. 2026-05-27 01:52:11 +02:00
Bartosz Taudul
6b28296ef3 Add icon explanations to aid in helping icons by what they show. 2026-05-27 01:52:11 +02:00
Bartosz Taudul
c11fd010d8 Rebuild markdown manual. 2026-05-27 00:10:33 +02:00
Bartosz Taudul
121e10c837 Convert latex font awesome markup to unicode codepoints matching the C defines. 2026-05-26 23:56:27 +02:00
Marcos Slomp
e57c0869df (take care of dead code warning) 2026-05-26 14:49:32 -07:00
Marcos Slomp
4cf754f3fe Calibrate no takes a max sample count 2026-05-26 14:39:12 -07:00
Bartosz Taudul
22d1c2d3c3 Properly convert bclogo blocks into markdown. 2026-05-26 22:34:45 +02:00
Marcos Slomp
884415264b error check 2026-05-26 07:53:01 -07:00
Marcos Slomp
ea8cbc849f adding an upper-bound to the calibration loop 2026-05-26 07:15:54 -07:00
Bartosz Taudul
20d7135c24 Merge pull request #1373 from siliceum/feature/unify-set-options
Options.cmake: unify `set_options*` and `tracy_set_options`
2026-05-26 12:58:45 +02:00
Clément Grégoire
aaf1304308 Options.cmake: unify set_options* and tracy_set_options
Renamed `tracy_*` versions to short version without prefix
2026-05-26 12:50:19 +02:00
rmarker
37750e27ab Allow zooming and panning the flamegraph view.
It could be challenging to examine fine details within the flamegraph.
The flamegraph has been enhanced so that it allows zooming with the
mouse wheel, and then panning around with the right mouse button.
This provides a familiar experience to the timeline view.
2026-05-26 19:30:29 +09:30
Bartosz Taudul
ab62c00be5 Add limit on disassembly tool reply. 2026-05-25 00:57:19 +02:00
Bartosz Taudul
757b582ae7 Include external function status in sampling stats. 2026-05-25 00:46:46 +02:00
Bartosz Taudul
b81ef061f8 Display LLM address during connection attempt. 2026-05-24 17:02:03 +02:00
Bartosz Taudul
702b16977b Set 5 second connection timeout on LLM API connection. 2026-05-24 17:02:02 +02:00
Bartosz Taudul
3f1e572a23 Update LLM API input hint to llama.cpp default port. 2026-05-24 17:02:02 +02:00
Bartosz Taudul
00d4e9ba21 Don't try connecting to LLM after each keystroke.
When typing in e.g. "127.0.0.1" the first character "1" as a valid address
that does not immediately fail the connection attempt. The result was that
any further interaction with the UI (including completing the input) was
blocked by the "please wait" screen during connection attempt.
2026-05-24 17:01:59 +02:00
Bartosz Taudul
ee37bb40f0 Merge pull request #1372 from wolfpld/slomp/nvcc-msvc-fix
NVCC (with MSVC/cl.exe) build fix
2026-05-24 16:29:58 +02:00
Bartosz Taudul
215199239f Merge pull request #1370 from siliceum/feature/custom-platform-hooks
Add `TRACY_PLATFORM_HEADER` hook for unsupported platforms
2026-05-24 15:48:43 +02:00
Clément Grégoire
f93d17a96f Add TRACY_PLATFORM_HEADER hook for unsupported platforms.
Extension point so private/unsupported platforms can plug in their own implementations of the kernel/libc primitives Tracy depends on, without patching the `#if`/`#elif` chains.

Projects supply a platform header via `-DTRACY_PLATFORM_HEADER="\"my_platform.h\""` at build time. Tracy includes it in any TU that needs the hooks. The header toggles per-category `TRACY_HAS_CUSTOM_*` macros and declares matching `tracy::Platform*` functions.

Available hooks:

- `TRACY_HAS_CUSTOM_THREAD_ID` → `PlatformGetThreadId`
- `TRACY_HAS_CUSTOM_USER_INFO` → `PlatformGetHostname`, `PlatformGetUserLogin`, `PlatformGetUserFullName`
- `TRACY_HAS_CUSTOM_SAFE_COPY` → `PlatformSafeMemcpy`
- `TRACY_HAS_CUSTOM_ALLOCATOR` → `PlatformMalloc`, `PlatformFree`, `PlatformRealloc`, `PlatformAllocatorInit`, `PlatformAllocatorThreadInit`, `PlatformAllocatorFinalize`, `PlatformAllocatorThreadFinalize`

Each hook is wired as the first arm of its respective `#if`/`#elif` chain, so existing supported platforms are unaffected.

Template files in `examples/CustomPlatform/` and a new subsection in `manual/tracy.tex` document the mechanism.
2026-05-24 15:42:42 +02:00
Clément Grégoire
84570487bf Move CMake option wrappers into cmake/options.cmake.
Move `tracy_set_option` and `tracy_set_option_value` from `CMakeLists.txt` into `cmake/options.cmake`. Add `tracy_set_option_value_as_string` for options whose value is embedded as a C string literal. All three accept an optional trailing target argument; when provided, the option is also propagated as a PUBLIC compile definition on that target.

Existing `set_option`/`set_option_value` are unchanged but will be replaced later by the `tracy_*` versions.
2026-05-24 15:42:42 +02:00
Bartosz Taudul
03227f7ae1 Update identify.cpp build instructions. 2026-05-24 15:35:43 +02:00
Bartosz Taudul
05c2638467 Remove option to build profiler GUI with no statistics. 2026-05-24 15:07:53 +02:00
Clément Grégoire
fd68959223 Rename InitRpmalloc to InitAllocator.
The function is about to dispatch between rpmalloc and a pluggable allocator hook, so the rpmalloc-specific name no longer fits. Pure rename plus a small consequence: the SymbolWorker call site no longer needs the TRACY_USE_RPMALLOC guard, since the no-op static-inline fallback in TracyAlloc.hpp makes InitAllocator() safe to call unconditionally.
2026-05-24 15:04:31 +02:00
Bartosz Taudul
5c0263c2f0 Disable display of hw samples by default. 2026-05-24 14:57:31 +02:00
Bartosz Taudul
5fd0dc569b Make impact option active only if hw samples are enabled. 2026-05-24 14:55:59 +02:00
Bartosz Taudul
ec1c2d4267 Display aggregation counts in bottom / up sample trees. 2026-05-24 14:23:59 +02:00
Bartosz Taudul
b7e405ebbd Use proper wait stacks grouping variable. 2026-05-24 14:15:53 +02:00
Bartosz Taudul
e8a0676c0b Fix regression that made propagate inlines always disabled if no child calls. 2026-05-24 13:35:48 +02:00
Bartosz Taudul
32b46a3b90 Cleanup. 2026-05-23 23:53:22 +02:00
Bartosz Taudul
cffd0007c5 Bump libs. 2026-05-23 23:41:39 +02:00
Marcos Slomp
564e0e1e71 removing scope qualifiers 2026-05-23 14:20:06 -07:00
Bartosz Taudul
6eb9bf81ad Fix out of bounds read. 2026-05-23 13:40:18 +02:00
Bartosz Taudul
f99a02505a Fix possible div-by-zero.
If as.ipMaxAsm.local is 0 and m_childCalls is false, GetHotnessColor(count, 0)
performs float(2 * count) / 0. The old code explicitly guarded against this
with the as.ipMaxAsm.local != 0 check.
2026-05-23 13:33:16 +02:00
Bartosz Taudul
f63c25fb79 Add glow to gutter markers. 2026-05-23 13:11:02 +02:00
Bartosz Taudul
a0af290db5 Rework symbol view gutter markers logic. 2026-05-23 12:26:24 +02:00
Bartosz Taudul
65db47ed0d Implement viewing assembly attachments. 2026-05-23 01:35:11 +02:00
Bartosz Taudul
d06c4ce816 Fix broken callstack display in zone tooltips if no local functions. 2026-05-23 00:37:57 +02:00
Bartosz Taudul
c91215bd99 Add function for checking if there are local functions in a callstack. 2026-05-23 00:30:47 +02:00
Bartosz Taudul
dfac4cb8a4 Defer initial system prompt update to the first draw. 2026-05-22 19:15:47 +02:00
Bartosz Taudul
34a1bb6107 DrawSourceTooltip() doesn't work with free-floating strings. 2026-05-22 17:54:26 +02:00
Bartosz Taudul
6957f968a4 Include trace time span in llm system message. 2026-05-22 02:06:58 +02:00
Bartosz Taudul
896cdc9462 Fade-out outdated assistant replies.
The "outdated" concept is strictly for chain of assistant replies with
nothing in between, i.e.:

"I will check this..."      <- outdated
<tool call>                 <- not displayed
"Now I will do that..."     <- outdated
<tool call>                 <- not displayed
"Let me consider..."        <- outdated
<reasoning>                 <- not displayed
"Now I have the answer..."

The first three messages are at this point considered outdated, as the
model provided a more recent message.

Note that in chain such as below there are NO outdated messages:

"How can I help..."
<user input>
"Ah, I see..."
<user input>
"You may try to..."

Similarly, if the tool calls or reasoning sections are explicitly enabled
in the chat UI, the messages are also not considered outdated.
2026-05-21 21:23:14 +02:00
Bartosz Taudul
efc33a09d9 Fix potential issue with last chat turn detection. 2026-05-21 20:51:58 +02:00
Bartosz Taudul
61875e1bd0 Add LLM tool for listing sampling statistics. 2026-05-21 20:27:54 +02:00
Bartosz Taudul
e003885946 Merge pull request #1369 from siliceum/feature/no-sys-param-for-bsd
Drop sys/param.h dependency for BSD detection
2026-05-21 17:57:16 +02:00
Bartosz Taudul
d40806caff Merge pull request #1368 from siliceum/fix/timeline-depth
Prevent unlimited recursion leading to stack overflow
2026-05-21 17:50:58 +02:00
Clément Grégoire
e7c71c991c Drop sys/param.h dependency for BSD detection
Replace `#ifdef BSD` (which requires including `<sys/param.h>` first) with explicit checks for `__FreeBSD__`, `__NetBSD__`, `__OpenBSD__` and `__DragonFly__`, matching how these BSDs are already enumerated elsewhere in the codebase (OS name strings, thread id helpers, etc.).

This also avoids leaking the `sys/param.h` requirement through public headers (`TracySysTime.hpp`, `TracyCallstack.h`), where consumers would otherwise need it to correctly see `TRACY_HAS_SYSTIME` / `TRACY_HAS_CALLSTACK`.
`libbacktrace/config.h` is left as-is — it's third-party and only included from .c files where the `BSD` macro can still be picked up locally.

Note: for `setsockopt( m_sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&val, sizeof( val ) );` I added `__APPLE__` too since this was the only place where it was not checked explicitely.
2026-05-21 10:18:30 +02:00
Clément Grégoire
69855a1416 Prevent unlimited recursion leading to stack overflow
This can happen notably when the user does not call ZoneEnd.

I used 256 arbitrarily as it seemed higher values would just make the UI freeze anyway due to perf reasons.
I added a warning in the notification area so that users can locate it.
2026-05-21 09:38:43 +02:00
Bartosz Taudul
60247b68d3 Merge pull request #1364 from siliceum/fix/zone-runtime
Fix and refactor zone running time
2026-05-20 19:29:29 +02:00
Bartosz Taudul
b48ef9a2ab Merge pull request #1366 from siliceum/fix/ondemand-no-callstack-hang
Fix ProfilerWorker hang when TRACY_HAS_CALLSTACK is not defined
2026-05-20 18:05:42 +02:00
Clément Grégoire
e59601cf1c Fix ProfilerWorker hang when TRACY_HAS_CALLSTACK is not defined 2026-05-20 17:51:42 +02:00
Bartosz Taudul
43472f1226 Merge pull request #1365 from siliceum/feature/fiber-tests
Add fiber to test app
2026-05-20 12:34:45 +02:00
Clément Grégoire
c1177a0cde Add fiber to test app
This simulates fibers on different threads. Was used to discover an issue reported on discord which led to #1364
2026-05-20 12:07:05 +02:00
Clément Grégoire
91c0b1e42b Fix and refactor zone running time
Many of the zones would have a negative running time due to a missing `cs->IsEndValid()` check.
This could end reporting context switches before the zone start, due to `cs->End()` returning -1.

This happened when systrace dropped event, or when using Fibers and `TracyFiberEnter` is called on the new thread once the fiber has been scheduled. (The manual actually does not really hint this is wrong, we should probably fix the manual or the server code.)

In both cases, we assume runtime to be 0 for that context switch. Since we have no actual information. Both options (counting full runtime or no runtime) are wrong, and most of the code handling `!cs->IsEndValid()` uses `Start` instead so that's what I did. This is still a net improvement over displaying negative values. If we want to change this handling, we'd need to review the other places that do `it->IsEndValid() ? it->End() : it->Start()` as well.

It also seems two different concepts were being mixed:
1. Do we have any context switch data at all ? (`it != ctx->v.end()` ie `count != 0`)
2. Do we have complete data for the last context switch (`eit != ctx->v.end()`)

This led to some places of the code not displaying or counting running time at all, notably when hovering a zone.

I think most of the time we wanted 1, as it reports correctly and assumes the last context switch is still running, which is a fair assumption if we didn't see one putting the thread to sleep.

I also fixed a case where we were overcounting runtime when range start was during a sleep.
2026-05-20 12:02:38 +02:00
Bartosz Taudul
14a1a3227e Add guidance about function context. 2026-05-20 02:26:14 +02:00
Bartosz Taudul
8582715fa5 Add information about addresses in callstacks. 2026-05-20 02:26:14 +02:00
Bartosz Taudul
d51634ad24 Include ip and base addr in json callstack frames. 2026-05-20 02:26:14 +02:00
Bartosz Taudul
4bbfe5edbd Add tool for getting symbol parent calls. 2026-05-20 02:26:14 +02:00
Bartosz Taudul
55c5348fad Make GetCallstackJson public. 2026-05-20 00:41:20 +02:00
Bartosz Taudul
5b4dcd4655 Add support for parent callstacks to GetCallstackJson. 2026-05-20 00:27:24 +02:00
Bartosz Taudul
a380046e17 Switch symbol disassembly tool to use symbol address parameter. 2026-05-19 23:52:20 +02:00
Bartosz Taudul
6494285283 Include hex address ofthe symbol in disassembly json. 2026-05-19 23:41:36 +02:00
Bartosz Taudul
ec92f2fac3 Update NEWS. 2026-05-19 22:50:11 +02:00
Bartosz Taudul
07b2600c08 Do not spam wikipedia. 2026-05-19 21:58:15 +02:00
Bartosz Taudul
562a120087 Merge pull request #1362 from alandtse/feature/mcp-save-trace
Add save_trace MCP tool for snapshotting live or loaded captures
2026-05-19 12:21:46 +02:00
Alan Tse
33fe84532e Add save_trace MCP tool for snapshotting live or loaded captures.
- save_worker binding: wraps Worker::Write under
  Worker::ObtainLockForMainThread() so live instances yield their
  receive thread cooperatively for the save's duration — the same
  pattern View::Save uses in the GUI.
- save_trace MCP tool: defaults to async_mode=True for multi-GB
  traces; reuses the existing Task/executor machinery so callers
  poll via the task tool. Path resolution mirrors load_capture.
- manual/tracy.tex: add save_trace bullet to the MCP tool list.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 01:23:31 -07:00
Bartosz Taudul
1f1738c221 Make glow bigger. 2026-05-18 01:00:38 +02:00
Bartosz Taudul
eb411b1138 Merge pull request #1361 from rmehri01/patch-2
fix: header definition of start/end sampling profiling
2026-05-17 21:57:22 +02:00
Bartosz Taudul
cf5325032e Make the symbol view hotness indicators more chonky.
The previous uniform glow rectangle was not appropriate anymore, so the
glow was changed to be a proper gradient.
2026-05-17 21:53:06 +02:00
Ryan Mehri
f74a452b89 fix: header definition of start/end sampling profiling 2026-05-17 15:16:45 -04:00
Bartosz Taudul
365c99e601 Restore frameData->imageName.Active() checks. 2026-05-17 18:58:29 +02:00
Bartosz Taudul
b8f68e3fae Add local call stacks to sample statistics inlines list. 2026-05-17 18:13:52 +02:00
Bartosz Taudul
5d4ba366ba DrawSourceTooltip reports if source was printed. 2026-05-17 17:58:22 +02:00
Bartosz Taudul
a7937d2710 Move local callstack printing to a separate function. 2026-05-17 17:56:14 +02:00
Bartosz Taudul
efd7ec262d Set default LLM address to llama.cpp port. 2026-05-17 17:50:33 +02:00
Bartosz Taudul
f0f579172b Force inline fast check. 2026-05-17 16:06:56 +02:00
Bartosz Taudul
4c6157d249 Remember last retrieved external check result. 2026-05-17 15:43:26 +02:00
Bartosz Taudul
6ae6fb741e Check if image is external once, before checking subframe filenames.
Cache is shared between image names and source file names, because the
underlying StringIdx storage makes indices unique. Both name sets should
be completely separate, but if you have conflicts here, you have much
more pressing problems to solve.
2026-05-17 15:30:03 +02:00
Bartosz Taudul
4ab7ef301e Split IsFrameExternalImpl into image + filename parts. 2026-05-17 15:30:03 +02:00
Bartosz Taudul
41f1172774 Change order of IsFrameExternal checks.
Check image first, then perform the expensive filename check.
2026-05-17 14:30:45 +02:00
Bartosz Taudul
b18d81cbbe Explicitly state which code paths are important to consider. 2026-05-17 14:08:54 +02:00
Bartosz Taudul
03e60c902f Clamp max percentage bar width. 2026-05-16 13:30:51 +02:00
Bartosz Taudul
0b88cbaa3c Fix z/x keys in source view when the child panes (src/asm) are focused. 2026-05-16 13:29:26 +02:00
Bartosz Taudul
5b180fdd5f Restore const qualifiers dropped in 744bd21 for global cache. 2026-05-14 22:59:10 +02:00
Bartosz Taudul
03f737a923 Use local external frame cache in BuildFlameGraph.
In terms of how much BuildFrameGraph execution time was spent in
IsFrameExternal:

1. no cache: 67%
2. global + shared_mutex: 84%
3. global + mutex: 80%
4. local: 41% (this commit)
2026-05-14 22:44:59 +02:00
Bartosz Taudul
4e0259148f Change IsFrameExternal interface to work with external cache.
Locks are dominating the execution time, making the global cache non-viable.
2026-05-14 22:29:51 +02:00
Bartosz Taudul
a3cadb2fce Protect against localtime failures. 2026-05-14 22:06:22 +02:00
Bartosz Taudul
6789e7d6f9 Cosmetics. 2026-05-14 20:36:55 +02:00
Bartosz Taudul
c3e3ea98ad Add basic information about the profiling session to system prompt. 2026-05-14 19:51:42 +02:00
Bartosz Taudul
c11c36f9f7 Add trace filename and user data accessors to View. 2026-05-14 19:51:41 +02:00
Bartosz Taudul
150ec1534c Store View in TracyLlm. 2026-05-14 19:51:41 +02:00
Bartosz Taudul
0dfd7fb20b Cache IsFrameExternal() queries. 2026-05-14 19:51:41 +02:00
Bartosz Taudul
b90e44a5f1 Add raw data accessor to StringIdx. 2026-05-14 19:33:21 +02:00
Bartosz Taudul
744bd21423 Change IsFrameExternal() interface to operate on StringIdx, move to Worker. 2026-05-14 19:01:04 +02:00
Marcos Slomp
4a58c42e2d Merge pull request #1316 from slomp/slomp/d3d12-ring
GPU: D3D12: remove NewFrame() API + drop unresolved queries when under pressure
2026-05-14 09:16:32 -07:00
Marcos Slomp
af9802e3f2 debugbreak only for msvc 2026-05-14 08:24:54 -07:00
Marcos Slomp
ad9c6f2f18 addressing code review 2026-05-14 08:13:59 -07:00
Bartosz Taudul
eb3df3b411 Fix blurred web page at fractional scaling. 2026-05-13 21:53:58 +02:00
Bartosz Taudul
7e9f66c987 Prefer switching to source/line within symbol in links from markdown. 2026-05-13 00:33:43 +02:00
Bartosz Taudul
f4b89278ef Switching to a specified filename and line within already opened symbol. 2026-05-13 00:32:54 +02:00
Bartosz Taudul
e0a8499376 Add information about symbol vs source code. 2026-05-12 18:03:45 +02:00
Bartosz Taudul
6ded0d1d7b Bump imgui to 1.92.8-docking. 2026-05-12 18:03:45 +02:00
Bartosz Taudul
77152da627 Make child sample counts consistent with child sample time formatting. 2026-05-12 02:03:16 +02:00
Bartosz Taudul
2a51d4acf1 Disable child calls controls if there are no child calls. 2026-05-12 02:02:05 +02:00
Bartosz Taudul
ea651eacce Give guidance for looking at external function calls. 2026-05-12 01:22:09 +02:00
Bartosz Taudul
3edcf37c58 Add guidance about links in inline code. 2026-05-12 01:03:17 +02:00
Bartosz Taudul
b0f00d20c8 Proper floating point charconv is available since libstdc++ 11 (April 2021). 2026-05-12 00:30:49 +02:00
Bartosz Taudul
453f2c1871 Display child calls time as a percentage. 2026-05-12 00:25:09 +02:00
Bartosz Taudul
e40497e02e No 'if' for BeginChild. 2026-05-12 00:16:05 +02:00
Bartosz Taudul
e124ae985d Add child call percentage relative to total symbol time. 2026-05-12 00:11:27 +02:00
Bartosz Taudul
efa1b1ef48 Convert child call distribution list to a table, add image column. 2026-05-12 00:11:27 +02:00
Bartosz Taudul
ec6c2618ca Add missing separator. 2026-05-11 23:23:34 +02:00
Bartosz Taudul
fe4c920794 Skip inline symbols. 2026-05-11 23:10:06 +02:00
Bartosz Taudul
afcefc7855 Add llm tool for getting disassembly + profiling data for a symbol. 2026-05-11 22:23:29 +02:00
Bartosz Taudul
22ec55f1d5 Store View reference in TracyLlmTools. 2026-05-11 22:09:27 +02:00
Bartosz Taudul
c026c98bbb Source file name is not needed for gathering assembly data. 2026-05-11 22:01:25 +02:00
Bartosz Taudul
205983e87f Recalculate AddrStatData in AttachRangeToLlm.
For consistency, always provide the OS-level sampling data, not the hardware
samples.

Always disable inline propagation, which is intended as a local area help
for a human. It does not make sense in context of an llm.
2026-05-11 21:48:00 +02:00
Bartosz Taudul
c9a9bbdab2 Move Gather{Additional,}IpStats from TracySourceView to TracyDisassembly. 2026-05-11 21:22:53 +02:00
Bartosz Taudul
ae56d79c7e Extract disassembly line formatting to a separate function. 2026-05-11 21:11:39 +02:00
Bartosz Taudul
860724d794 Cosmetics. 2026-05-11 20:27:53 +02:00
Bartosz Taudul
40199a42b3 Properly emit empty cost separators when line addres is not in ipCountAsm. 2026-05-11 20:27:04 +02:00
Bartosz Taudul
7c6e656fda Use existing reference to array entry. 2026-05-11 20:01:40 +02:00
Bartosz Taudul
9611069a4f Remove guidance about user replies from assembly attachments. 2026-05-11 19:51:39 +02:00
Bartosz Taudul
825960553a Give reasoning for always providing source file name + line number. 2026-05-11 19:51:06 +02:00
Bartosz Taudul
325fe71d30 Move AddrStatData from TracySourceView to TracyDisassembly. 2026-05-11 19:22:37 +02:00
Bartosz Taudul
beec259520 Extract symbol code disassembly into a separate source file.
Two bugs fixed in the process:

1. X86_REG_BPL is now properly set (previously there were duplicate
   X86_REG_BP entries).
2. maxLine is now properly calculated, instead of being set to the
   last line value.
2026-05-11 01:30:28 +02:00
Bartosz Taudul
1dcad83790 Include call costs in assembly attachments. 2026-05-10 14:05:31 +02:00
Bartosz Taudul
8dd606009c Require window focus for z/x key activation in source view. 2026-05-10 13:24:20 +02:00
Bartosz Taudul
17b6656c85 Provide program optimization strategies for llm. 2026-05-10 12:44:49 +02:00
Bartosz Taudul
edb5241bee Be more efficient with missing values in asm attachments. 2026-05-10 11:35:31 +02:00
Bartosz Taudul
5cb283073e Store kernel symbol end address, not size.
The end address is now readily available in lower_bound search, instead
of needing to be calculated constantly in the lambda.

The size can be equivalently calculated from the end address, but this
only happens once, after the symbol is found.
2026-05-10 00:15:18 +02:00
Bartosz Taudul
a6c72f1cc7 Do not repeatedly read from all ring buffers to find minimum time entry. 2026-05-09 20:41:29 +02:00
Bartosz Taudul
95416a4b9c Since active[] order doesn't matter, memmove can be replaced with a swap. 2026-05-09 17:48:57 +02:00
Bartosz Taudul
f7ab78893c Don't query inline-symbol frames as native addresses.
Frames whose symbol data is shipped inline with the callstack payload
(sel=1, e.g. Lua-side stack entries) were being passed to
GetCanonicalPointer() in the AddCallstackAllocPayload() query loop,
tripping its sel==0 assertion. They have no native pointer to query
and were already registered in callstackFrameMap earlier in the same
function, so just skip them.

Regression from c704f909, which hoisted the per-call-site dedup into
QueryCallstackFrame(). Three of the four updated call sites were
equivalent before and after, because the old guard and the new one
keyed on the same value. The fourth, this one, was not: the old guard
tested the frame as-is and matched the entry inserted a few lines above,
short-circuiting before GetCanonicalPointer() ran. The new guard keys on
PackPointer(addr), so GetCanonicalPointer() must run first to compute
addr, and the assert fires.
2026-05-09 12:13:45 +02:00
Bartosz Taudul
7de27ebffa Force inline RingBuffer::Read(). 2026-05-09 01:05:33 +02:00
Bartosz Taudul
70535435f2 Use masking instead of calculating remainder.
size is power-of-two (asserted).
2026-05-09 00:58:16 +02:00
Bartosz Taudul
61a6fb6780 Batch ring buffer reads. 2026-05-09 00:50:50 +02:00
Marcos Slomp
d5bce07a90 oopsie 2026-05-08 15:33:12 -07:00
Marcos Slomp
027a37409b addressing code review comments 2026-05-08 14:30:24 -07:00
Bartosz Taudul
1bfd3beab9 Add "how to fix this crash?" preset question to call stack window. 2026-05-08 01:57:43 +02:00
Bartosz Taudul
b864ff47e5 Implement disabling LLM summary and suggestion. 2026-05-08 01:48:19 +02:00
Bartosz Taudul
4d34163ade Allow accepting chat suggestion via Enter or Send button. 2026-05-08 01:17:31 +02:00
Bartosz Taudul
8ce05917db Prevent stale summary after chat reset. 2026-05-08 01:07:59 +02:00
Bartosz Taudul
d59c1e7bd2 Prevent stale suggestion after chat reset. 2026-05-08 01:07:54 +02:00
Bartosz Taudul
6fb7f6d095 Add LLM chat suggestions. 2026-05-08 00:34:14 +02:00
Bartosz Taudul
db8bfc9ba9 Prevent in-flight query notification flicker. 2026-05-07 22:34:48 +02:00
Bartosz Taudul
305382453d Add callstack sample events with 32 and 16 bit timestamps. 2026-05-07 02:16:53 +02:00
Bartosz Taudul
ccaef5ba0b ZoneBegin / ZoneBeginCallstack with 32 and 16 bit time data. 2026-05-07 02:16:53 +02:00
Bartosz Taudul
4d094c108d Add zone end messages with 32 and 16 byte time deltas.
Change in test application:
    compressed data: 130 Mpbps -> 105 Mbps
    uncompressed: 830 Mbps -> 740 Mbps
2026-05-06 19:09:19 +02:00
Bartosz Taudul
b1768b98a5 Protocol was bumped to 77 after 0.13.1. 2026-05-06 01:37:54 +02:00
Bartosz Taudul
d6e77b3f40 Remove server query fast path.
The profiler will typically want to send bursts of queries (e.g. 3 queries
to retrieve source location strings, or multiple queries to get all the call
stack frames, etc.).

Each of these queries will be sent immediately, if available space in the
network buffer permits. Each of these sends is a separate syscall.

Remove this and instead batch all queries with the already existing network
buffer overflow handling functionality.
2026-05-06 00:42:24 +02:00
Bartosz Taudul
58eaa330af Set TCP_NODELAY on profiler data channel. 2026-05-06 00:12:21 +02:00
Bartosz Taudul
8c2a970222 Merge pull request #1352 from wolfpld/slomp/apple-systrace
System tracing (callstack sampling) for Apple devices
2026-05-05 19:05:41 +02:00
Bartosz Taudul
173c58bb6e Merge pull request #1353 from siliceum/fix/winsdk-compat
Fix #1243 compatibility with WinSDK < 10.0.26100
2026-05-05 18:05:51 +02:00
Marcos Slomp
6a214ed419 refactoring globals 2026-05-05 08:28:15 -07:00
Marcos Slomp
df20e8ad84 refactoring 2026-05-05 08:05:56 -07:00
Marcos Slomp
761d50e8f5 debug cleanup 2026-05-05 07:49:15 -07:00
Clément Grégoire
2997a78872 Fix #1243 compatibility with WinSDK < 10.0.26100
After investigating (downloading and installing) all publicly available SDKs at https://learn.microsoft.com/en-us/windows/apps/windows-sdk/downloads-archive I concluded the `TRACEHANDLE` deprecation started in `10.0.26100`.
This defines `PROCESSTRACE_HANDLE` and `CONTROLTRACE_ID` as done by the SDK when using older versions. Using `WDK_NTDDI_VERSION` (and not `NTDDI_VERSION` which may change based on `_WIN32_WINNT` or user input seems to be the most reliable way to do it. While it says "WDK" it's been part of the SDK in `shared\sdkddkver.h`. Note it doesn't work for MinGW because it updates half of its sdk files for some reason.
Tested with both 10.0.26100 and 10.0.22621.0 which is the last one I found without the new types.
Also changes CONTROLTRACE_ID to ULONG64 on mingw which is correct (type used by `TRACEHANDLE` too in mingw fe2763863a/mingw-w64-headers/include/evntrace.h (L60) )
2026-05-05 16:14:21 +02:00
Marcos Slomp
6b4ed90323 remove modern c++ 2026-05-04 21:43:27 -07:00
Marcos Slomp
ace8f18adb handle ARM64 PAC 2026-05-04 16:21:19 -07:00
Marcos Slomp
8692f2a650 updating manual 2026-05-04 16:18:00 -07:00
Marcos Slomp
ee3120010a cleanup 2026-05-04 16:18:00 -07:00
Marcos Slomp
3d6129f8b0 dependent function ordering 2026-05-04 16:18:00 -07:00
Marcos Slomp
dbb17e50e3 relaxing atomics in hot multi-threaded path 2026-05-04 16:18:00 -07:00
Marcos Slomp
8b9c25f19c handle case where constructor (context initializaion) may fail 2026-05-04 16:18:00 -07:00
Marcos Slomp
33b5404033 early exit when MapTimestampBuffer fails 2026-05-04 16:18:00 -07:00
Marcos Slomp
1e5926b9c0 debug cleanup 2026-05-04 16:18:00 -07:00
Marcos Slomp
b452e84e53 removing debug code 2026-05-04 16:18:00 -07:00
Marcos Slomp
bb4c6bc5a9 removing debug pragma 2026-05-04 16:18:00 -07:00
Marcos Slomp
474b3dbdfb comments 2026-05-04 16:18:00 -07:00
Marcos Slomp
80e6087ff3 claim shared ownership of the queue to keep the queue (and device) alive 2026-05-04 16:18:00 -07:00
Marcos Slomp
c4d18c8291 refactoring Drain/Collect 2026-05-04 16:18:00 -07:00
Marcos Slomp
bf1222c4b1 re-enabling assert 2026-05-04 16:17:59 -07:00
Marcos Slomp
0ec1b29a66 debug cleanup 2026-05-04 16:17:59 -07:00
Marcos Slomp
035a2ba30d debug cleanup 2026-05-04 16:17:59 -07:00
Marcos Slomp
2242811004 refactoring 2026-05-04 16:17:59 -07:00
Marcos Slomp
099af6dd74 simplified private API 2026-05-04 16:17:59 -07:00
Marcos Slomp
2a7e2215e0 handling special wait cases, and misc comments 2026-05-04 16:17:59 -07:00
Marcos Slomp
8fc8b42221 simplify debug ZoneValue 2026-05-04 16:17:59 -07:00
Marcos Slomp
f538ac49c6 nomenclature 2026-05-04 16:17:59 -07:00
Marcos Slomp
c35acce915 debugger check 2026-05-04 16:17:59 -07:00
Marcos Slomp
77be1c8616 minor refactoring 2026-05-04 16:17:59 -07:00
Marcos Slomp
0fdc70a75f implementing Drain/Wait 2026-05-04 16:17:59 -07:00
Marcos Slomp
2b4e5250ed refactoring debug macros 2026-05-04 16:17:59 -07:00
Marcos Slomp
760eeb40e8 cleanup includes 2026-05-04 16:17:59 -07:00
Marcos Slomp
303680257f debugging 2026-05-04 16:17:59 -07:00
Marcos Slomp
952da01f33 comments about ResolveQueryData 2026-05-04 16:17:59 -07:00
Marcos Slomp
601c55bad2 track latest known GPU timestamp (to avoid "time-travel" later on in the server) 2026-05-04 16:17:59 -07:00
Marcos Slomp
ea7fb726ac refactoring Collect 2026-05-04 16:17:59 -07:00
Marcos Slomp
4f9de46d3d cleanup 2026-05-04 16:17:59 -07:00
Marcos Slomp
60935f2a25 refactoring 2026-05-04 16:17:59 -07:00
Marcos Slomp
7e70154e4e cleanup 2026-05-04 16:17:59 -07:00
Marcos Slomp
d94c484adc adopting new producer-consumer "panic" strategy 2026-05-04 16:17:59 -07:00
Marcos Slomp
0a27c61313 debugging 2026-05-04 16:17:59 -07:00
Marcos Slomp
b34966fe62 refactoring 2026-05-04 16:17:59 -07:00
Marcos Slomp
85789a8a13 minor refactoring 2026-05-04 16:17:59 -07:00
Marcos Slomp
333e4bcb05 comments and debugging 2026-05-04 16:17:58 -07:00
Marcos Slomp
b80fa52ba2 switching to a circular buffer with individual timeouts 2026-05-04 16:17:58 -07:00
Marcos Slomp
b638a3adff opportunistically collect next window whenever possible 2026-05-04 16:17:58 -07:00
Marcos Slomp
9b2f1266ea cosmetic changes 2026-05-04 16:17:58 -07:00
Marcos Slomp
bde92ffed2 timestamp relax (disabled) 2026-05-04 16:17:58 -07:00
Marcos Slomp
3bf371c4fb refactoring of Collect core 2026-05-04 16:17:58 -07:00
Marcos Slomp
c39d1d6441 fudge factors... 2026-05-04 16:17:58 -07:00
Marcos Slomp
1d8022c301 comments, debugging 2026-05-04 16:17:58 -07:00
Marcos Slomp
0afe331d1e consolidating map/unmap buffer logic 2026-05-04 16:17:58 -07:00
Marcos Slomp
19e48a843d conditional clarity 2026-05-04 16:17:58 -07:00
Marcos Slomp
9649302da8 Distance utility 2026-05-04 16:17:58 -07:00
Marcos Slomp
f06989e17c cleanup 2026-05-04 16:17:58 -07:00
Marcos Slomp
e1357d7a1b reworking destructor 2026-05-04 16:17:58 -07:00
Marcos Slomp
4f62a115fa adopting a "collect window" scheme to avoid race conditions and heavy synchronization 2026-05-04 16:17:58 -07:00
Marcos Slomp
cd1a2c7c6e re-enabbling post-collect calibration; rephrasing comments about race condition 2026-05-04 16:17:58 -07:00
Marcos Slomp
37628ed305 explaining the race condition 2026-05-04 16:17:58 -07:00
Marcos Slomp
e5cdb8b361 persistent map, debug toggle, etc 2026-05-04 16:17:58 -07:00
Marcos Slomp
65cb45ea97 re-enable range assert 2026-05-04 16:17:58 -07:00
Marcos Slomp
4f44b954ab reveting overflow suppresion 2026-05-04 16:17:58 -07:00
Marcos Slomp
d8aaa91379 disabling debug dump 2026-05-04 16:17:58 -07:00
Marcos Slomp
43b8a98091 timestamp aging and race debugging 2026-05-04 16:17:58 -07:00
Marcos Slomp
db9e82691c debugging the UI freaking out 2026-05-04 16:17:58 -07:00
Marcos Slomp
e7a503c47f misc 2026-05-04 16:17:58 -07:00
Marcos Slomp
7e0855d56b keep track of the last known emitted gpu timestamp, and use it to emit makeshift timestamps for dropped timestamps 2026-05-04 16:17:58 -07:00
Marcos Slomp
b0b3c8a335 collect timestamps in pairs 2026-05-04 16:17:58 -07:00
Marcos Slomp
1c2c1b5c17 comments and eminders 2026-05-04 16:17:57 -07:00
Marcos Slomp
b50876e77c eliminate NewFrame, and account for "abandoned" and "out-of-order" timestamp queries 2026-05-04 16:17:57 -07:00
Marcos Slomp
c877d0bcb4 TracySysTrace already manages the wprker thread lifetime... 2026-05-04 15:45:56 -07:00
Marcos Slomp
5a168f7ae4 initial prototype of system tracing for Apple devices 2026-05-04 15:29:24 -07:00
Bartosz Taudul
5bbafeabd7 Patch ppqsort to fix binary_semaphore release race. 2026-05-04 01:13:53 +02:00
Bartosz Taudul
04728994a5 Shorten external frames in call stack tooltips. 2026-05-04 01:05:02 +02:00
Bartosz Taudul
600227a30b More compact assembly code form.
For Qwen3.6-27B tokenizer:

AStar<> (3018 byte binary): 25546 -> 21099 tokens (82.6%)
LZ4_compress_fast_continue (10.47 KB): 84140 -> 69016 tokens (82%)
2026-05-02 16:31:59 +02:00
Bartosz Taudul
6d4a080da5 More compact symbol view source attachments. 2026-05-02 16:04:29 +02:00
Bartosz Taudul
7fac1ef8c9 Update NEWS. 2026-05-02 15:44:26 +02:00
Bartosz Taudul
7e043e21e7 Enable resizing of child call distribution box. 2026-05-02 15:42:34 +02:00
Bartosz Taudul
40b328dc95 Add drawable height splitter widget. 2026-05-02 15:42:18 +02:00
Bartosz Taudul
0a64f16c2d More compact time range limits window. 2026-05-02 12:41:12 +02:00
Bartosz Taudul
9965aff723 Use fractional max rows for visible threads display to imply scrolling. 2026-05-02 01:41:28 +02:00
Bartosz Taudul
6276f1b12a Rebuild markdown manual. 2026-05-02 00:38:44 +02:00
Bartosz Taudul
335403d860 Always dim out external frames. 2026-05-02 00:38:34 +02:00
Bartosz Taudul
4e6f7c2152 More return stack reinforcement. 2026-05-02 00:31:53 +02:00
Bartosz Taudul
8877a2527d Proper count of possibly visible threads in wait stacks window. 2026-05-01 22:03:39 +02:00
Bartosz Taudul
71fb624ec4 Update NEWS. 2026-05-01 21:23:14 +02:00
Bartosz Taudul
4394d79c39 Limit "visible threads" rows displayed at once. 2026-05-01 21:20:51 +02:00
Bartosz Taudul
3900890ef4 Show visible threads list in columns.
Options list is excluded, as that's drag-n-drop, and that's too much
complication.
2026-05-01 21:20:51 +02:00
Bartosz Taudul
a11e417e43 Provide detailed call stack analysis instructions. 2026-05-01 17:56:36 +02:00
Bartosz Taudul
78bac8dcbc Use correct tid field name. 2026-05-01 17:56:35 +02:00
Alan Tse
9a7233ced5 Add MCP server for AI-assisted trace analysis (#1347)
* Add MCP server for AI-assisted trace analysis.

Introduce an optional Model Context Protocol (MCP) server that lets AI
assistants analyze Tracy captures and live sessions through Tracy's own
server engine. The server runs as a Python sidecar and talks to the
existing C++ analysis code through new pybind11 bindings.

- python/bindings/ServerModule.cpp: TracyServerBindings module exposing
  Worker, file I/O, zones, GPU zones, frame data, plots, messages, locks,
  source locations, and summary statistics (zone/GPU child stats, frame
  timing, etc.).
- python/CMakeLists.txt: builds and installs TracyServerBindings alongside
  TracyClientBindings.
- extra/mcp/tracy_mcp.py: FastMCP SSE singleton with dynamic port
  discovery, PID-file based singleton detection, session-isolated worker
  instances, synchronous and background eval, task polling, and a
  shutdown tool to release the .pyd lock during development.
- extra/mcp/start_mcp.sh, .gitignore: launcher with local override hook;
  ignores generated port/pid files.
- manual/tracy.md: documents building, running, and integrating the
  server with an AI assistant.

* Improve Tracy MCP cold-start guidance.

Cold-start usability testing showed an LLM agent burned ~7 exploratory
calls discovering the ctx object model, time-unit conventions, and join
keys before producing useful analysis. Surface that information up front
through MCP resources and entry-point tool guidance.

- extra/mcp/eval_guide.md: new bindings-layer reference covering the
  Worker object graph (zone / GPU zone / frame / thread / message /
  plot / lock / memory entry points), nanosecond time units, ZoneStats
  field semantics including self-time via get_child_zone_stats, the
  opaque 'name (addr)[arch] <srcloc_id>' key format, and worked
  examples translating common queries into ctx Python.
- extra/mcp/tracy_mcp.py: expose system.prompt.md and eval_guide.md as
  MCP resources (tracy://prompt and tracy://eval-guide) so external
  agents and Tracy Assist share the same guidance source. Resource
  content is re-read per request — edits propagate without a server
  restart.
- Point load_capture and live_connect return values plus the eval tool
  description at the resources, so the agent reads them before its
  first eval rather than introspecting blind.
- Expand load_capture docstring: name the path parameter explicitly,
  show Windows path syntax, and direct agents to list_captures plus
  TRACY_CAPTURES_DIR for capture discovery.
- Probe is_connected() briefly after Worker construction in
  live_connect and surface an actionable error on silent handshake
  failures (typically a Tracy client/server version mismatch or
  TRACY_ON_DEMAND) instead of returning misleading success.

Reduces a fresh agent's cold-start overhead from 7 exploratory calls
to 4, where the remaining 4 are unavoidable harness/schema-fetch
overhead, not API-design friction.

* Detect Tracy protocol mismatches via UDP broadcast pre-flight.

Tracy clients announce themselves on UDP port 8086 every ~3 seconds with
a BroadcastMessage carrying the protocol version, listen port, and
program name (public/common/TracyProtocol.hpp). The Tracy GUI reads this
and refuses to attempt a TCP connection on protocol mismatch, surfacing
a precise error. live_connect previously had no equivalent check, so a
mismatch produced an opaque 2-second handshake timeout with no
diagnostic about what was wrong.

- Add a broadcast parser handling versions 0-3, with variable-length
  programName (Tracy sends only the actual name + null terminator on
  the wire, not the full 64-byte buffer).
- Add a non-blocking UDP listener that binds 8086 with SO_REUSEADDR
  and waits up to 3.5s — enough to guarantee catching at least one
  beat at the 3s broadcast cadence.
- Read our bindings' ProtocolVersion at startup by parsing
  TracyProtocol.hpp, so the comparison stays in sync with the build
  without new C++ wiring.
- live_connect runs the broadcast pre-flight before constructing
  Worker. On a matched listen_port with a differing protocol_version,
  it returns a single-line error naming the program, both versions,
  and the remediation, without ever opening a TCP connection. If no
  matching broadcast arrives, it falls through to the existing
  handshake probe, which now reports any other broadcasts seen as a
  hint (helpful when the target uses a non-default port).

* Add MCP Server section to LaTeX manual.

The markdown manual is auto-generated from the LaTeX source; add the
corresponding \subsection{MCP Server} so the two stay in sync.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Remove hand-written MCP section from tracy.md.

tracy.md is generated from tracy.tex via latex2md.sh. The MCP section
was previously written by hand directly in the markdown; now that the
LaTeX source has been updated, the markdown section should be
regenerated by running latex2md.sh rather than maintained manually.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 16:17:55 +02:00
Bartosz Taudul
460352d0d5 Allow opening callstack window from LLM attachment. 2026-04-30 21:42:22 +02:00
Bartosz Taudul
89bd8b2ba5 Add public View method for opening callstack window. 2026-04-30 21:41:53 +02:00
Bartosz Taudul
cf2c07d905 Mark GetSelectThread() const. 2026-04-30 21:38:33 +02:00
Bartosz Taudul
529c688ff2 Callstack thread display is not gated by LLM. 2026-04-30 18:40:54 +02:00
Bartosz Taudul
af665ef3dc Update NEWS. 2026-04-30 18:13:11 +02:00
Bartosz Taudul
6c5e0cdf1d Draw call stack thread name in call stack window. 2026-04-30 18:08:15 +02:00
Bartosz Taudul
80f504019f Store callstack window callstack id together with origin thread id. 2026-04-30 17:06:59 +02:00
Bartosz Taudul
6ccad8a94d Generic thread id naming in crash callstack attachments. 2026-04-30 12:48:58 +02:00
Bartosz Taudul
f0df6112dc Move callstack summary in callstack window to its own line. 2026-04-30 12:46:22 +02:00
Bartosz Taudul
170b0b4edf More compact listing format. 2026-04-30 12:19:13 +02:00
Bartosz Taudul
39cd16a92b Move specialized LLM skills out of the system prompt. 2026-04-30 02:41:48 +02:00
Bartosz Taudul
eaf66e7af9 Cleanup. 2026-04-28 00:27:27 +02:00
Bartosz Taudul
ab75aeeac9 Add section headers to the in-program user manual. 2026-04-27 23:32:34 +02:00
Bartosz Taudul
4fe2949033 Instruct LLM how to provide user manual links. 2026-04-27 23:21:49 +02:00
Bartosz Taudul
ac20896f57 Add links to manual search results. 2026-04-27 23:15:52 +02:00
Bartosz Taudul
afddce2538 Implement going to manual link. 2026-04-27 23:05:43 +02:00
Bartosz Taudul
14aa5dafe5 Add manual section link tooltips. 2026-04-27 22:47:10 +02:00
Bartosz Taudul
4d62b3a573 Move view and worker checks to initial isSource check. 2026-04-27 22:46:35 +02:00
Bartosz Taudul
d4241d987d Pass view, worker to user manual markdown renderer. 2026-04-27 22:23:08 +02:00
Bartosz Taudul
04d30fb487 Add manual chunk retrieval function. 2026-04-27 22:20:58 +02:00
Bartosz Taudul
d653e984b5 Really fix first-word-continuation word wrap.
The previous solution (75c173) didn't account for the fact that the text
to print may start with a space, in which case the text width calculation
results in 0. In effect, first word length was never greater than the
space left for printing, and the problem was still there.

Fix by walking through all initial spaces in firstWord.

If fwLen > left, then a line break is needed. In this case ignore initial
spaces in text.
2026-04-26 00:40:55 +02:00
Bartosz Taudul
afe51ec5f3 Merge pull request #1348 from Casqade/fix-multiline-messages-tooltips
Show tooltips for multiline messages
2026-04-25 18:54:24 +02:00
casqade
29d21fe1f7 Show tooltips for multiline messages 2026-04-25 17:27:13 +03:00
Bartosz Taudul
43643ba0b6 Update NEWS. 2026-04-25 13:08:01 +02:00
Bartosz Taudul
efb1973210 Dim out external frames in callstack tooltips. 2026-04-25 13:04:49 +02:00
Bartosz Taudul
0bd56feb2d Only reset start time when role changes to non-assistant.
Fixes time reset on tool replies.
2026-04-25 12:49:44 +02:00
Bartosz Taudul
83a31730ce Reply timing logic is only relevant for assistant replies. 2026-04-25 12:49:10 +02:00
Bartosz Taudul
5f7a36cf44 Do not assert on early TracyDebug calls.
TracyDebug fires from SysPower's ctor while it scans intel-rapl, which
runs as a Profiler member initializer -- before s_instance is set in
the Profiler ctor body. Under TRACY_MANUAL_LIFETIME without
TRACY_ON_DEMAND, the TracyInternalMessage path guarded this with
assert(ProfilerAvailable()), which aborted tracy-monitor whenever it
was run as root (only then is intel-rapl readable, so the log is
actually reached).

Soften the assert to an early-out, matching the TRACY_ON_DEMAND branch.
A TracyDebug issued before the profiler is up now silently skips
instead of aborting.
2026-04-24 21:27:58 +02:00
Bartosz Taudul
46bccd9a92 Refresh external image cache on symbolization misses.
FindExternalImageRefresh already re-parsed /proc/<pid>/maps on miss,
but only one of three external decode paths used it. Switch the
DecodeCallstackPtrFastExternal and DecodeSymbolAddressExternal paths
over so symbol-name and file/line lookups stay fresh after the target
dlopens a library.

Rate-limit the re-parse to once per wall-clock second so samples
landing on permanently unresolvable regions (JIT, vDSO, stacks) do
not trigger a full parse each time.
2026-04-24 21:16:42 +02:00
Bartosz Taudul
7448c0fbe1 Cover all target threads in tracy-monitor.
perf_event_open(pid>0, cpu>=0) binds to a single task, so the previous
setup only sampled the target's main thread. In monitor mode, enumerate
/proc/<pid>/task/ and open one per-task event per existing thread with
cpu=-1; inherit=1 then covers every descendant. Self-profiling behavior
is preserved byte-for-byte: the iter list becomes (currentPid, i) for
each CPU, exactly what the old code did inline.
2026-04-24 21:14:33 +02:00
Bartosz Taudul
2755166543 Flush stdout before perf preflight, so it's printed before stderr. 2026-04-24 21:10:11 +02:00
Bartosz Taudul
cbfa625fb9 Harden tracy-monitor startup and shutdown paths.
- Loop startup waitpid on EINTR; kill and reap the child on fatal error
  or when interrupted, instead of leaking a ptrace-stopped process.
- Treat PTRACE_DETACH failure as fatal -- otherwise the child is stuck
  stopped forever.
- Zero-initialize procName so the memcpy into ___tracy_magic_process_name
  does not copy uninitialized stack past the NUL.
- Forward SIGINT to the child from the signal handler when in forked
  mode, so Ctrl-C during a blocking waitpid unblocks cleanly.
- Preflight perf_event_open on the target before StartupProfiler so
  permission failures surface with actionable guidance instead of
  silently producing no samples.
- Also handle SIGHUP and SIGQUIT.
2026-04-24 21:07:41 +02:00
Bartosz Taudul
23930e998b Display label with assistant model name and reply duration for each message. 2026-04-24 19:53:45 +02:00
Bartosz Taudul
9b708c433f Store model and response time for assistant messages. 2026-04-24 18:15:49 +02:00
Bartosz Taudul
2c6adfb416 Regenerate markdown manual. 2026-04-23 00:28:59 +02:00
Bartosz Taudul
bde6e06cd7 Update manual. 2026-04-23 00:24:09 +02:00
Bartosz Taudul
4022494934 Update NEWS. 2026-04-22 22:07:39 +02:00
Bartosz Taudul
68ee8704d2 Merge pull request #1335 from siliceum/feature/check-macros-mismatch
Detecting macro definitions mismatches at link time
2026-04-21 18:12:32 +02:00
Bartosz Taudul
8d9a8494b8 Merge pull request #1344 from siliceum/fix/etw-compat
Fix TracyETW_compat.h structs and values based on docs
2026-04-21 18:11:01 +02:00
Clément Grégoire
c1ab158f6c Update manual with mismatch detection info 2026-04-21 13:51:24 +02:00
Clément Grégoire
ca076b4a60 Add TracyMangle.hpp file to centralize config name mangling
Also rename MANGLED_NAME_BASED_ON_DEFINES => MANGLED_NAME_BASED_ON_CONFIG
2026-04-21 13:28:48 +02:00
Clément Grégoire
a4f245550b Macro incompatibility experiment
We redirect GetProfiler() (most likely used by any project consuming tracy, since it's used by `tracy::ScopedZone`) to its implementation which now has a different function name based on the macros that can impact ABI (and enabled/disabled).
That way, when linking with mismatched defines you'd get an error such as

> main.obj : error LNK2019: unresolved external symbol "int __cdecl GetProfiler_CFG_E0_OD0_DI0_ML0_F0_DHT0_TF0(void)" (?GetProfiler_CFG_E0_OD0_DI0_ML0_F0_DHT0_TF0@@YAHXZ) referenced in function "int __cdecl GetProfiler(void)" (?GetProfiler@@YAHXZ)

Or

>[build] /usr/bin/ld: CMakeFiles/app.dir/main.cpp.o: in function `GetProfiler()':
[build] /..../TracyProfiler.hpp:143: undefined reference to `GetProfiler_CFG_E1_OD0_DI0_ML0_F0_DHT0_TF0()'

Reason for going with acronym+0/1 instead of just acronym when enabled is for us to be able to tell users easily which define is wrong by just looking at the error if needed.

The only thing we don't really detect is user not having TRACY_ENABLE but tracy having been built with it. This is because macros become noops in that case, with no reference to `GetProfiler`.
There may be a way to do it by introducing a local variable into each TU, but I don't really like that idea.
We could also add pragma detect mismatch for a more user-friendly error on windows (https://learn.microsoft.com/en-us/cpp/preprocessor/detect-mismatch?view=msvc-170).
2026-04-21 13:28:48 +02:00
Clément Grégoire
1711d024dd Fix TracyETW_compat.h structs and values based on docs
https://learn.microsoft.com/fr-fr/windows/win32/api/evntprov/ns-evntprov-event_filter_event_id
https://learn.microsoft.com/fr-fr/windows/win32/etw/system-providers

Note: WinSDK does not use ULL in keyword constants so I removed them too.
2026-04-21 13:20:48 +02:00
Bartosz Taudul
217bdcf5a9 Merge pull request #1343 from siliceum/fix/better-tracefs-detection
Better tracefs detection
2026-04-21 11:55:10 +02:00
Clément Grégoire
4aac9e677d Fix formating/whitespaces in SysTraceStart 2026-04-21 09:51:43 +02:00
Clément Grégoire
aba343e429 Pick first debugfs entry only 2026-04-21 09:51:42 +02:00
Bartosz Taudul
25f09bee2c Merge pull request #1342 from siliceum/fix/1337-respect-max-sample-rate
Fix #1337 : On Linux respect max sample rate
2026-04-20 19:33:14 +02:00
Clément Grégoire
cb9ef7814e Use ReadFile and atoi 2026-04-20 18:05:31 +02:00
Clément Grégoire
8f208d732a Fix extra space 2026-04-20 18:04:41 +02:00
Clément Grégoire
8816dd0557 Allow finding tracefs through debugfs as a fallback for older kernels/systems that only mount debugfs 2026-04-20 15:04:33 +02:00
Clément Grégoire
0a5647b20f Use mnt_type instead of mnt_fsname for tracefs discovery
This is to be consistent with what libtracefs does: 6fad6a14ba/src/tracefs-utils.c (L104)
In theory one may mount tracefs with another name, though unlikely.
2026-04-20 15:00:37 +02:00
Clément Grégoire
d48794024d Log why SysTrace does not start on Linux 2026-04-20 14:49:57 +02:00
Clément Grégoire
95b6fdeed3 Fixes #1337: On Linux, respect perf_event_max_sample_rate to avoid lost events
This may be especially useful for low performance machines. We also warn about this behaviour through TracyDebug which ends up in Messages.
2026-04-20 14:31:41 +02:00
Clément Grégoire
e550e15ce6 Turn GetSamplingPeriod into SamplingFrequencyToPeriodNs
This forces to (re)use frequency values as input, which may be changed by the platform code later on. This way we have a single "source of truth" for sample freq.
Also removed the Win32 `GetSamplingInterval` which was a wrapper above `GetSamplingPeriod` but its value would be divided again anyway.
2026-04-20 14:29:35 +02:00
Bartosz Taudul
4e670fcaf5 Merge pull request #1338 from imsarllc/fix_32bit_arm_issue
Add static cast to uint64_t for std::min
2026-04-17 18:44:09 +02:00
Erik van Zwol
70fc86536c Add static cast to uint64_t for std::min
On 32-bit arm, phdr.p_vaddr is 32-bit, which causes a compilation
error because std::min expects both arguments to be of the same
type. Adding the static cast handles this case explicitly.
2026-04-17 09:45:43 -06:00
Bartosz Taudul
1c3691a57b Add llm chat topic. 2026-04-17 01:27:38 +02:00
Basil Milanich
ebd3d9c3e6 Also defer GpuContextName for on-demand profiling
Without this, a late-connecting client receives the deferred
GpuNewContext but not the GpuContextName, so the GPU context appears
unnamed in the profiler.

Add check_gpu_ctx_name tool to verify context names in captured traces.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 09:27:47 -05:00
Basil Milanich
bc8d8f5302 Add repro case for rocprofiler on-demand crash
Minimal HIP program that demonstrates the assertion failure in
tracy-capture when connecting to a TRACY_ON_DEMAND + TRACY_ROCPROF
application. See examples/RocprofOnDemandRepro/README.md for details.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 16:02:36 -05:00
Basil Milanich
b049746853 Fix on-demand profiling support for rocprofiler backend
Two issues prevented the rocprofiler GPU backend from working with
TRACY_ON_DEMAND:

1. GpuNewContext not deferred: When a Tracy client connects late (on-demand
   mode), it never receives the GPU context creation message because the
   GpuNewContext queue item was not buffered via DeferItem. This caused an
   assertion failure (ctx == nullptr) in the capture/profiler when
   processing GPU zone events. Add the same DeferItem pattern used by the
   CUDA backend.

2. Kernel symbols dropped before init: The data->init guard at the top of
   tool_callback_tracing_callback() blocked kernel symbol registrations
   (CODE_OBJECT_DEVICE_KERNEL_SYMBOL_REGISTER) which happen at HIP init
   time, before any Tracy client connects. Move the init guard after the
   code_object block so symbols are always recorded, while dispatch and
   memory-copy events are still gated on initialization.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 15:56:31 -05:00
Bartosz Taudul
ebf3f02264 Merge pull request #1330 from bmilanich/cuda-graph-fallback
TracyCUDA: show GPU zones for CUDA Graph-launched kernels
2026-04-15 21:14:09 +02:00
Basil Milanich
0a0566abc5 Update stale MEMORY2 comment to reflect cbid tracker removal
The comment still described consuming/not-consuming cudaCallSiteInfo
entries, but memory CBIDs are no longer tracked so no entry exists.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 10:28:13 -05:00
Basil Milanich
58809f95ff Use atomic flag for retirement check to avoid mutex on hot path
Replace the mutex-guarded empty check in OnBufferCompleted with an
std::atomic<bool> dirty flag. The mutex is now only acquired when
there is actual retirement work to do. Also update stale comment
on cudaGraphCurrentLaunch that said "let them leak".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 10:23:42 -05:00
Basil Milanich
8f6249c12f Restore insert_or_assign over operator[] for graphLaunchCache
operator[] on ConcurrentHashMap returns a reference after releasing the
read lock — the subsequent assignment happens with no lock held. This is
a latent data race if the map is ever accessed from multiple threads.

insert_or_assign performs the lookup and assignment atomically under a
single write lock, which is the correct pattern for a ConcurrentHashMap.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 10:23:42 -05:00
Basil Milanich
da878d29d1 Address PR review feedback from slomp
- Add `using GraphID = uint32_t` typedef and use it throughout for
  graphId-typed variables (PersistentState, matchGraphActivityToAPICall,
  getGraphIdFromRecord, retirement set, buffer loop).

- Move matchError from matchGraphActivityToAPICall to caller sites
  (KERNEL, MEMCPY, MEMSET handlers). Keeping the error at the caller
  provides more debugging context about which activity kind failed.
  Remove the now-unnecessary `kind` parameter from the function.

- Replace insert_or_assign with operator[] assignment in
  matchGraphActivityToAPICall. Access to graphLaunchCache is
  single-threaded (CUPTI worker), so the simpler syntax is sufficient.
  Remove the insert_or_assign method from ConcurrentHashMap entirely.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 10:23:42 -05:00
Basil Milanich
b22c8e86ba Remove memory API calls from cbid tracker maps
cudaMalloc/cudaFree (and driver equivalents) were tracked in
cbidRuntimeTrackers/cbidDriverTrackers, creating a cudaCallSiteInfo
entry on each API call. But the MEMORY2 handler never calls
matchActivityToAPICall (and never calls EmitGpuZone) — it only needs
the address, size, and timestamp from the activity record itself. Since
no activity handler consumes these entries, they leaked indefinitely.

Remove the 6 memory API CBIDs from both tracker maps so no entry is
created. This eliminates the leak with no change in visible behavior:
the MEMORY2 handler already operates independently of cudaCallSiteInfo.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 10:23:42 -05:00
Basil Milanich
ec7805fd92 Retire cudaGraphCurrentLaunch entries on cudaGraphExecDestroy
Without retirement, the cache grows by one entry per unique exec handle
ever launched and never shrinks. While bounded by the number of distinct
execs in the application, long-running programs creating and destroying
many exec handles accumulate stale entries indefinitely.

Retirement mechanism:
- At cudaGraphExecDestroy (ENTER, while handle is still valid): call
  cuptiGetGraphExecId to translate exec handle → graphId and add to a
  pending-retirement set. Works for both runtime (cudaGraphExecDestroy)
  and driver (cuGraphExecDestroy) APIs. No new subscription needed —
  the existing cuptiEnableDomain already routes all API callbacks here.

- Deferral in OnBufferCompleted: erasure is not done immediately because
  cudaGraphExecDestroy does not wait for GPU completion. CUPTI may still
  have undelivered activity records for the last launch in its internal
  buffers. We defer the erase until a full buffer arrives that contains
  no records bearing the retired graphId, indicating all in-flight
  records have been delivered.

- getGraphIdFromRecord: new helper that extracts the graphId field from
  CONCURRENT_KERNEL / MEMCPY / MEMSET activity records (the three kinds
  that carry a graphId) for use in the per-buffer tracking.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 10:23:42 -05:00
Bartosz Taudul
a64b9a2029 Proper mutex wrapper use.
In the JSON exception catch handler, m_jobsLock.lock() is called directly
on the mutex instead of through the jobsLock unique_lock. When the function
returns, jobsLock's destructor runs but it doesn't own the lock (it was
unlocked earlier at line 1134), and m_jobsLock is never released. This
causes a permanent deadlock the next time anything tries to acquire
m_jobsLock.
2026-04-11 17:29:44 +02:00
Bartosz Taudul
0269a196a4 Add TracyTaggedUserlandAddress.hpp to include list in meson. 2026-04-11 13:16:47 +02:00
Bartosz Taudul
010d25be06 Merge pull request #1332 from Brainzman/fix-missing-installed-include
Fix missing TracyTaggedUserlandAddress.hpp include due to it not being installed
2026-04-11 13:15:24 +02:00
Jonas Holzman
0de97789dd Fix missing TracyTaggedUserlandAddress.hpp due to it not being installed
Currently including the Tracy.hpp header from a set of installed Tracy
headers will result in the following error:

In file included from <...>/tracy/include/tracy/tracy/Tracy.hpp:133:
In file included from <...>/tracy/include/tracy/tracy/../client/TracyLock.hpp:9:
In file included from <...>/tracy/include/tracy/tracy/../client/TracyProfiler.hpp:18:
<...>/tracy/include/tracy/tracy/../client/../common/TracyQueue.hpp:6:10: fatal error: 'TracyTaggedUserlandAddress.hpp' file not found
    6 | #include "TracyTaggedUserlandAddress.hpp"
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

Apparently introduced in f981330, which included the
TracyTaggedUserlandAddress.hpp header in TracyQueue.hpp without adding
it to the list of installed common header. Fixed by making the necessary
CMake change to install the header.

Ran into this issue while integrating Tracy as a dependency within
Blender[^1], where we use the latest main instead of stable for WoA
support, and use the install target to harvest the static lib and
headers for our libraries.

[^1]: https://projects.blender.org/blender/blender/pulls/156661
2026-04-11 12:27:40 +02:00
Bartosz Taudul
f71c74aaf7 Change TRACY_ENABLE default to OFF to match documentation.
The documentation states that Tracy is disabled by default, but the
build system defaults were ON/true. Change CMake and Meson defaults to
OFF/false. Projects that need profiling enabled must now opt in
explicitly. Add explicit TRACY_ENABLE=ON / tracy_enable=true to CI
steps and the test project to preserve existing behavior.
2026-04-10 18:49:04 +02:00
Bartosz Taudul
82560c8c0e Fix emscripten CI job. 2026-04-10 17:06:34 +02:00
Basil Milanich
12dc23f67e Add graphId recycle investigation test
Tests whether CUPTI recycles graphId values after cudaGraphExecDestroy,
which would be the only scenario where the graphLaunchCache in TracyCUDA
could serve stale entries for a non-matching exec handle.

Result (H100, CUDA 12, CUPTI): graphId is a monotonically increasing
counter that is never recycled. 22 create/instantiate/launch/destroy
cycles produced unique IDs ranging from 2 to 65 (incrementing by 3 per
cycle — one unit per node created during graph construction).

This confirms that the stale-cache concern raised in code review is not
a real risk in practice: two distinct exec handles always have distinct
graphIds.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 09:34:51 -05:00
Basil Milanich
c807367099 Add correlationId investigation test for CUDA Graph launches
Tests two questions:
1. Does relaunching the same cudaGraphExec produce a new correlationId
   each time, or is it reused?
2. Do two different cudaGraphExec handles from the same cudaGraph share
   a graphId?

Results on H100, CUDA 13.1:
- Each launch of the same exec handle gets a strictly unique, monotonically
  increasing correlationId. CPU callback corrId == GPU activity corrId.
  This is formally documented in cupti_activity.h:
    "Each graph launch is assigned a unique correlation ID that is
     identical to the correlation ID in the driver API activity record
     that launched the graph."
- graphId identifies the exec handle (instantiation), not the graph
  definition. Two cudaGraphInstantiate calls on the same graph produce
  different graphIds.

These findings confirm that the cudaGraphCurrentLaunch cache in
matchGraphActivityToAPICall is always refreshed by the first activity
of each new launch before the graphId fallback path is ever used.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 09:28:34 -05:00
Basil Milanich
9e36e5d1ad Fix MEMORY2 handler: don't consume cudaCallSiteInfo entry
Calling matchActivityToAPICall in the MEMORY2 handler was consuming
the cudaCallSiteInfo entry for the graph launch correlationId. If a
graph mixes alloc nodes with kernel/memcpy nodes, all activities share
the same correlationId — consuming it here would cause
matchGraphActivityToAPICall to fail for the kernel/memcpy records that
follow, silently dropping their GPU zones.

Since apiCall is never used by the MEMORY2 handler (only address, size,
and timestamp from the activity record are needed), remove the call
entirely and leave the entry for the kernel/memcpy to consume and cache.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 16:01:41 -05:00
Basil Milanich
b6222ae28b Fix MEMORY2 handler: don't gate memory tracking on API call correlation
CUpti_ActivityMemory3 has no graphId field, so graph-launched alloc
nodes and pre-profiling allocations can't be correlated to an API call.
The handler only needs address, size, and timestamp from the activity
record — apiCall is never used. Remove the early return so memory
tracking works in all cases.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 15:33:41 -05:00
Basil Milanich
703df05529 Document known MEMORY2 limitation for graph-launched alloc nodes
CUpti_ActivityMemory3 has no graphId field, so matchGraphActivityToAPICall
cannot be applied. Graph-launched cudaGraphAddMemAllocNode emits multiple
MEMORY2 records sharing the launch correlationId; only the first is
tracked, subsequent ones fire a spurious matchError.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 15:30:27 -05:00
Basil Milanich
c8ebc6f21e Review fixes: correct stale comments, fix fetch() missing lock, tidy helper
- Fix wrong comments on graph launch tracker entries: they claimed
  correlation works "via CUPTI_ACTIVITY_KIND_GRAPH_TRACE", but that
  approach was rejected (GRAPH_TRACE suppresses per-kernel records).
  The actual mechanism is the shared correlationId across all nodes
  in one graph launch.
- Fix ConcurrentHashMap::fetch() missing its read lock — a pre-existing
  data race now exercised by the new graph correlation hot path.
- Cache PersistentState::Get().cudaGraphCurrentLaunch in a local ref
  inside matchGraphActivityToAPICall instead of calling Get() twice.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 14:00:01 -05:00
Basil Milanich
0b6e27934d ConcurrentHashMap: add insert_or_assign to replace erase+emplace
The cudaGraphCurrentLaunch cache update was acquiring the write lock
twice (once for erase, once for emplace). Wrapping
std::unordered_map::insert_or_assign under a single write lock lets
the caller do it in one operation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 13:48:53 -05:00
Basil Milanich
d9a1cc06c1 Fix repro build: add -arch=native to use correct GPU architecture
NVCC 13.1 defaults to a PTX version incompatible with the installed
driver (580.105.08), causing kernels to silently fail with "provided
PTX was compiled with an unsupported toolchain". Use -arch=native so
NVCC auto-detects the target GPU (H100, sm_90) at build time.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 13:33:05 -05:00
Basil Milanich
f74dd21573 Refactor: extract matchGraphActivityToAPICall helper
The kernel, memcpy, and memset cases all had identical logic for
handling graph-launched activities. Extract it into a single helper
next to matchActivityToAPICall.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 13:08:39 -05:00
Basil Milanich
4ccaea9f08 Expand repro: multiple graphs, multiple kernels, interleaved launches
Tests:
- Two distinct graphs (different graphIds) on the same stream
- Graph A: kernel + memcpy + kernel (3 nodes)
- Graph B: scale + add + scale (3 nodes)
- 5 interleaved launches of each, stressing the graphId cache
- Expected 30 graph GPU zones total

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 11:54:08 -05:00
Basil Milanich
d36ca27041 Fix graph correlation: use shared correlationId, not GRAPH_TRACE
CUPTI discovery: all kernels launched by one cuGraphLaunch share the
same correlationId as the launch call itself. GRAPH_TRACE was the
wrong approach — enabling it suppresses per-kernel CONCURRENT_KERNEL
records entirely, replacing them with graph-level summaries.

New approach:
- Drop CUPTI_ACTIVITY_KIND_GRAPH_TRACE (it conflicts with CONCURRENT_KERNEL)
- Drop two-pass buffer processing (no longer needed)
- On the first kernel/memcpy/memset from a graph launch, matchActivityToAPICall
  succeeds (consuming the cuGraphLaunch entry) and the result is cached in
  cudaGraphCurrentLaunch[graphId]
- Subsequent operations from the same launch find the cached entry via graphId

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 11:36:14 -05:00
Basil Milanich
2e5b076175 Also track cudaGraphLaunch runtime API for graph correlation
The repro uses cudaGraphLaunch (runtime API) not cuGraphLaunch (driver
API). Add cudaGraphLaunch_v10000 and its _ptsz variant to
cbidRuntimeTrackers so that graphs launched via the runtime API also
get their CPU call site captured for GPU zone correlation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 11:18:20 -05:00
Basil Milanich
7bca9dcd90 Fix CUDA Graph GPU zones with proper cuGraphLaunch correlation
Replace the synthetic APICallInfo hack with proper correlation via
CUPTI_ACTIVITY_KIND_GRAPH_TRACE. When cuGraphLaunch fires an API
callback, its correlationId is stored in cudaCallSiteInfo. The
GRAPH_TRACE activity record carries the same correlationId plus the
graphId, which lets us build a graphId→APICallInfo map. Kernel/memcpy/
memset activities then look up this map via their graphId field.

Key changes:
- Add cuGraphLaunch/cuGraphLaunch_ptsz to cbidDriverTrackers so the
  API callback machinery captures the CPU call site
- Enable CUPTI_ACTIVITY_KIND_GRAPH_TRACE and handle it in
  DoProcessDeviceEvent to populate cudaGraphCurrentLaunch[graphId]
- Add cudaGraphCurrentLaunch map to PersistentState
- Two-pass buffer processing in OnBufferCompleted so GRAPH_TRACE
  records (which complete last on GPU) are processed before the
  kernel/memcpy/memset records that depend on them
- Replace graphId=0 fallback in kernel/memcpy/memset with proper
  cudaGraphCurrentLaunch lookup; fall through to matchError if
  the graphId is not found
- Update repro to include TracyCUDA headers and properly test
  GPU zone correlation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 11:03:58 -05:00
Bartosz Taudul
00a069d608 Perform meson build in mingw workflow. 2026-04-03 21:11:03 +02:00
Bartosz Taudul
adf3a5b998 Build test application with CMake on mingw. 2026-04-03 20:10:06 +02:00
Bartosz Taudul
09d6a674c4 No -rdynamic on Windows. 2026-04-03 20:10:06 +02:00
Bartosz Taudul
ab61777896 Fix mingw GUID definitions. 2026-04-03 20:10:05 +02:00
Bartosz Taudul
c564b163d3 Client code must target C++11. 2026-04-03 20:10:03 +02:00
Bartosz Taudul
43c0f67353 Enable mingw CI builds on push and pull request. 2026-04-03 02:11:54 +02:00
Bartosz Taudul
44b1de2d71 Target win10 with mingw. 2026-04-03 02:11:16 +02:00
Bartosz Taudul
803b10fd6b Do not block vsync capture on mingw. 2026-04-03 02:11:13 +02:00
Bartosz Taudul
3ac364ebcb Add mingw ETW compat header. 2026-04-03 01:56:46 +02:00
Marcos Slomp
842420439d fix LogString wire in the DequeueSerial path (#1328) 2026-04-03 00:37:16 +02:00
Marcos Slomp
ee976f8146 Prevent CMake from re-generating files in the data folder every time (#1327) 2026-04-03 00:24:39 +02:00
Bartosz Taudul
bb1d4ad580 Revert usearch bump – broken on windows. 2026-04-02 21:05:35 +02:00
Bartosz Taudul
d5eb85e4c4 Bump deps. 2026-04-02 21:00:14 +02:00
Bartosz Taudul
08f82dc0be Add mingw CI build setup. 2026-04-02 01:02:18 +02:00
Bartosz Taudul
0fb2f8d75d Build client library with CMake and Meson again on Linux. 2026-04-02 00:42:16 +02:00
Bartosz Taudul
a861c6671c Reenable LTO, disable parallel build on GitHub runners. 2026-04-01 00:38:40 +02:00
Bartosz Taudul
b18b7461e4 Disable LTO on Linux CI. 2026-03-31 23:15:15 +02:00
Bartosz Taudul
d8139f2058 Allow disabling LTO, mold linker, ccache. 2026-03-31 23:15:15 +02:00
Bartosz Taudul
af5f1c4d52 Use CMake option macros. 2026-03-31 23:15:15 +02:00
Bartosz Taudul
5877db5411 Move NO_ISA_EXTENSIONS option to config.cmake. 2026-03-31 23:15:14 +02:00
Bartosz Taudul
eb81bdc3f8 NO_STATISTICS is not an option in most of the tools. 2026-03-31 23:15:14 +02:00
Bartosz Taudul
b6b1eed1d5 Externalize option setting macros. Add one for non-booleans. 2026-03-31 23:15:14 +02:00
Bartosz Taudul
e89eadf91a Fix copy pasta. 2026-03-31 23:15:11 +02:00
Bartosz Taudul
785eaeac86 Merge pull request #1324 from siliceum/fix/linux-comp-issue
Fix #1321 linux compilation issue
2026-03-31 14:02:28 +02:00
Clément Grégoire
313d5b681e Fix #1321 linux compilation issue introduc 2026-03-31 13:43:36 +02:00
Bartosz Taudul
16f7cd3c68 Merge pull request #1321 from siliceum/refactor/tracycallstack
Small cosmetic changes + symsrv.dll detection
2026-03-31 12:25:12 +02:00
Bartosz Taudul
a0b3a71212 Add monitor utility. 2026-03-31 02:06:01 +02:00
Bartosz Taudul
850cfd90f7 Add callstack decode functionality for external processes. 2026-03-31 01:18:51 +02:00
Bartosz Taudul
f8c6f4a7ba Cosmetics. 2026-03-31 01:18:51 +02:00
Bartosz Taudul
eca9609f52 Shut up about anonymous namespaces. 2026-03-31 01:18:50 +02:00
Bartosz Taudul
739123d005 Add a way to override profiled program name and PID. 2026-03-31 01:18:50 +02:00
Bartosz Taudul
53439ea5e2 Add external image cache machinery. 2026-03-31 01:18:50 +02:00
Clément Grégoire
da4b95bf59 Use CopyString(Fast) where possible in TracyCallstack 2026-03-30 22:33:43 +02:00
Clément Grégoire
79f7d99b02 Add SymSrv.dll check
This is often a source of missing symbols or incomprehension as to why they are not getting resolved. Having a debug log will help debugging such cases.
2026-03-30 22:33:43 +02:00
Clément Grégoire
8c5724d125 Fix formating in DbgHelpInit 2026-03-30 22:33:43 +02:00
Clément Grégoire
cf33cbd33f Extract MakeUnresolvedCallstackEntryData 2026-03-30 22:33:42 +02:00
Bartosz Taudul
c53d94f538 Set color diagnostics in test CMakeLists.txt. 2026-03-30 21:47:45 +02:00
Bartosz Taudul
b3aaac43ca Move ELF headers definition to a separate header file. 2026-03-30 20:56:45 +02:00
Bartosz Taudul
7974a74580 Add external_file support to libbacktrace
- Add external_file field to backtrace_state struct
- Add backtrace_create_state_for_file() function that marks
  state for external ELF files not loaded in current process
- In backtrace_initialize, use external_file flag to:
  - Pass exe=0 to elf_add for ET_DYN files (allows DWARF loading)
  - Skip dl_iterate_phdr enumeration (avoids noise from current process)

This enables symbol resolution from arbitrary ELF files on disk,
with caller responsible for address translation.
2026-03-30 19:52:12 +02:00
Bartosz Taudul
2f1fc19f88 libbacktrace: use correct names in #undef of ELF macros (b9e4006) 2026-03-30 19:40:30 +02:00
Bartosz Taudul
52607f70fe libbacktrace: add casts to avoid undefined shifts (78af4ff, 0034e33) 2026-03-30 19:38:45 +02:00
Bartosz Taudul
d79b7d4176 libbacktrace: don't get confused by overlapping address ranges (3d0be55) 2026-03-30 19:33:37 +02:00
Bartosz Taudul
6010770879 Update uops.info data. 2026-03-30 02:23:33 +02:00
Bartosz Taudul
c8a93adb01 Add merge utility to CI builds for linux, macos, and windows 2026-03-28 22:43:07 +01:00
Bartosz Taudul
1dee03e4f2 Rename workflow job names for uniqueness across workflows 2026-03-28 22:30:29 +01:00
Bartosz Taudul
0312a77390 Add GIT_REV to tools config in CI setup. 2026-03-28 21:59:10 +01:00
Bartosz Taudul
fddbb5d990 Print tracy version in all tools. 2026-03-28 21:38:47 +01:00
Bartosz Taudul
8bd49317ca Set include list for GitRef. 2026-03-28 21:38:27 +01:00
Bartosz Taudul
1b34592d80 Move git ref CMake extractor to a separate file. 2026-03-28 19:23:15 +01:00
Bartosz Taudul
6f91104542 Include git ref in profiler's --help output. 2026-03-28 12:44:12 +01:00
Bartosz Taudul
e300d56f68 Force resort of possibly broken plots. 2026-03-27 20:16:27 +01:00
Bartosz Taudul
8351daea73 Add ability to mark the SortedVector unsorted. 2026-03-27 20:16:27 +01:00
Bartosz Taudul
b5a322d122 Fix SortedVector regression.
Sort unsorted part of the vector, not the already sorted part.
2026-03-27 17:49:49 +01:00
Bartosz Taudul
77a53e2b5b No need to do strcmp here. 2026-03-24 23:47:40 +01:00
Bartosz Taudul
ef41e12ba8 Fix missing outer loop exit. 2026-03-24 22:51:02 +01:00
Basil Milanich
6c6999bf01 Add CUDA Graph GPU zone repro
Minimal reproducer showing that CUDA Graph-launched kernels produce
0 GPU zones in Tracy. The repro creates a simple graph (2 kernels +
1 memcpy), launches it 10 times, and expects ~30 GPU zones. Without
the fallback patch, all activity records are dropped by matchError().

Tested on NVIDIA H100, CUDA 13.1.
2026-03-24 09:37:50 -05:00
Basil Milanich
aa657d5438 Fix missing GPU zones for CUDA Graph-launched kernels
When kernels are launched via CUDA Graphs (cuGraphLaunch), CUPTI delivers
CONCURRENT_KERNEL, MEMCPY, and MEMSET activity records but no
corresponding API callback fires for the individual operations. This
means matchActivityToAPICall() always fails, and every GPU activity
record is silently dropped by matchError().

Fix this by falling back to a synthetic APICallInfo using the GPU
timestamps from the activity record when no API correlation exists.
This produces correct GPU zones with kernel names and timing — just
without the CPU-to-GPU launch correlation arrow.

Tested on NVIDIA H100 with CUDA 13.1: before this fix, 0 GPU zones
appeared for CUDA Graph workloads; after, all kernel and memcpy zones
are visible in the Tracy timeline.
2026-03-24 09:24:23 -05:00
Bartosz Taudul
e1143fd985 Try to remove excess frames from reconstructed callstack. 2026-03-24 01:14:38 +01:00
Bartosz Taudul
fb9912db5c Merge pull request #1315 from slomp/slomp/d3d12-opsie
D3D12 opsie
2026-03-23 23:45:51 +01:00
Marcos Slomp
a59ff2dcbb Update TracyD3D12.hpp
opsie
2026-03-23 15:43:36 -07:00
Bartosz Taudul
e792752104 Ignore completely non-local samples. 2026-03-22 17:04:31 +01:00
Bartosz Taudul
3c283187c3 Extract functionality for counting local frames in a callstack. 2026-03-22 17:00:15 +01:00
Bartosz Taudul
1967f2c79b Do proper frame matching instead of relying just on callstack size. 2026-03-22 16:51:55 +01:00
Bartosz Taudul
f5df9f9c24 Remove dead code. 2026-03-21 23:36:15 +01:00
Bartosz Taudul
5040412813 Simplify search for max-local call stack root. 2026-03-21 22:35:25 +01:00
Bartosz Taudul
9326227bcd Display reconstructed callstack in zone info window. 2026-03-21 01:48:00 +01:00
Bartosz Taudul
b52af15504 Change DrawCallstackTable interface to accept data + size pair. 2026-03-21 01:47:26 +01:00
Bartosz Taudul
e1381d1beb Draw reconstructed callstack trace in zone tooltips. 2026-03-21 01:27:12 +01:00
Bartosz Taudul
c4f42b1bc9 Basic heuristics for reconstruction of zone callstack from sample data. 2026-03-21 01:26:40 +01:00
Bartosz Taudul
d0222ef7d9 Worker::GetZoneEnd() can be const. 2026-03-19 19:53:58 +01:00
Bartosz Taudul
87781fd75c Merge pull request #1312 from YaLTeR/patch-1
Add missing cstdint include
2026-03-19 18:18:50 +01:00
Ivan Molodetskikh
16af373a7e Add missing cstdint include
Fixes build on new gcc on Fedora 44.
2026-03-19 17:57:57 +03:00
Amy
e9314add15 clang visibility for TRACY_API (#1310) 2026-03-18 23:59:33 +01:00
Bartosz Taudul
145efd63c9 Change GetCallstackJson interface to data ptr + size. 2026-03-18 00:52:34 +01:00
Bartosz Taudul
0905e203e3 Add DrawCallstackCalls( data, size, ... ) interface. 2026-03-18 00:42:21 +01:00
Bartosz Taudul
4fbbfb410d Merge pull request #1307 from slomp/slomp/d3d12-callstack-patch
Fix callstack and transient zones in D3D12
2026-03-17 21:20:08 +01:00
Marcos Slomp
36aaa19ae9 instrumenting relevant events of D3D12 2026-03-17 13:14:15 -07:00
Marcos Slomp
8b1e413db5 fix handling of D3D12 callstacks and/or transient zones 2026-03-17 13:13:24 -07:00
Bartosz Taudul
54f778c204 Display ellipsis in single-line callstack printout, when frames remain. 2026-03-17 02:29:12 +01:00
Bartosz Taudul
3876d33a15 Display callstacks in zone tooltips. 2026-03-17 01:32:24 +01:00
Bartosz Taudul
94e5ff2cfb Add inline callstack display to zone info window. 2026-03-17 01:00:21 +01:00
Bartosz Taudul
79d165190a Improve parent zones display. 2026-03-17 00:07:47 +01:00
Bartosz Taudul
83b7d3a267 Simplify "zone trace" into "parent zones". 2026-03-16 01:44:57 +01:00
Bartosz Taudul
a51efcc974 Proper CMake setup for TRACY_CALLSTACK. 2026-03-15 22:17:26 +01:00
Bartosz Taudul
1476afb992 Do not force enable CMake configure on open in VS Code. 2026-03-15 22:17:18 +01:00
Bartosz Taudul
80b8e8284e Allow attaching zone histogram to llm. 2026-03-11 00:42:53 +01:00
Bartosz Taudul
8f9392cae7 Merge pull request #1304 from slomp/slomp/windows-opsie
Windows x64 vs ARM opsie
2026-03-09 21:35:48 +01:00
Marcos Slomp
01bd20c30a Windows x64 vs ARM opsie 2026-03-09 13:24:08 -07:00
Bartosz Taudul
b0dd2b291d Make a separate fast model optional. 2026-03-08 14:42:18 +01:00
Bartosz Taudul
9f432d5fa2 Cosmetics. 2026-03-08 13:20:15 +01:00
Bartosz Taudul
2f90aac0ac Force enable thinking for chat model, force disable for fast model. 2026-03-08 13:16:14 +01:00
Bartosz Taudul
869ad0a02d Include news, locations, videos from brave search results. 2026-03-07 22:33:32 +01:00
Bartosz Taudul
928de7ae6c Use common functionality for gathering brave search results. 2026-03-07 22:33:32 +01:00
Bartosz Taudul
feb07e476a Merge pull request #1289 from slomp/slomp/windows-on-arm
Support for Windows on ARM
2026-03-06 23:55:02 +01:00
Bartosz Taudul
460944ef42 Cosmetics. 2026-03-06 23:53:13 +01:00
Bartosz Taudul
f1bc3ef4c7 Merge pull request #1300 from slomp/slomp/c-api-get-time
Adding C API for Profiler::GetTime()
2026-03-06 12:18:05 +01:00
Marcos Slomp
cc21988537 adding C API for Profiler::GetTime() 2026-03-06 01:33:01 -08:00
Bartosz Taudul
db0082de3f Add brave search. 2026-03-06 02:07:21 +01:00
Bartosz Taudul
bbc937c309 Refactor FetchWebPage to FetchHttp with custom headers support 2026-03-05 23:59:27 +01:00
Bartosz Taudul
71c5494414 Move web search engine implementations to separate functions. 2026-03-05 20:57:44 +01:00
Bartosz Taudul
2157e0a1b6 Better handle duckduckgo error responses. 2026-03-05 20:57:44 +01:00
Bartosz Taudul
cf09a04e92 Add missing include. 2026-03-05 20:57:01 +01:00
Bartosz Taudul
aba6efd24a Merge pull request #1296 from slomp/slomp/spsc-notify-wait
Add notify/wait to SPSCQueue (reduce latency of Symbol Worker)
2026-03-05 20:14:50 +01:00
Marcos Slomp
4460e64f3a addressing code review 2026-03-05 11:10:43 -08:00
Marcos Slomp
c696cb7f63 rever tracy_SPSCQueue.h 2026-03-04 21:42:14 -08:00
Marcos Slomp
332bbf2310 don't modify tracy_SPSCQueue.h 2026-03-04 17:35:05 -08:00
Marcos Slomp
ab2c32e52f use SPSC queue notify/wait in the symbol queue to reduce the response latency of the symbol worker 2026-03-04 12:14:19 -08:00
Marcos Slomp
eaa376be05 adding minimalist notify/wait interface and implementation to SPSC queue 2026-03-04 12:13:20 -08:00
Bartosz Taudul
53fa2ba67b Fix includes. 2026-03-02 23:58:16 +01:00
Bartosz Taudul
80c849a2aa Fix client identification in tracy-capture-daemon
Use '<pid>_<ip>_<port>' string as client ID instead of IP+port hash.
This allows:
- Same program restarting (new PID) to be recognized as new client
- Multiple instances of same program (different PIDs) to capture separately
2026-03-02 23:00:42 +01:00
Bartosz Taudul
add9a77396 Document tracy-capture-daemon and reorganize merge section
- Add subsection about tracy-capture-daemon in the capturing section
- Move merge tool documentation to follow capture daemon section
- Both tools are now documented as part of the capture workflow
2026-03-02 22:39:18 +01:00
Bartosz Taudul
e6aae0c18e Add tracy-capture-daemon for multi-client capture
A discovery-and-capture daemon that listens for UDP broadcasts from
Tracy clients, automatically connects to discovered clients, and
captures each to a separate file.

Features:
- Continuous discovery until Ctrl+C
- Per-client capture threads
- Terminal display with per-client stats
- Output files named: <program>_<ip>_<port>.tracy
- Collision handling with _1, _2 suffix
- Graceful shutdown on signal

Based on the multicapture design by Grégoire Roussel, but simplified
to output separate files instead of merging (use tracy-merge for that).

Co-authored-by: Grégoire Roussel <gregoire.roussel@wandercraft.eu>
2026-03-02 22:32:45 +01:00
Bartosz Taudul
03f01b9c49 Include fixes. 2026-03-02 21:34:35 +01:00
Bartosz Taudul
2341dee04a Refactor capture utilities into CaptureOutput
Extract common output functions from capture.cpp into a proper library:

- InitTerminalDetection()/IsTerminal() - terminal detection
- AnsiPrintf() - printf with ANSI escape codes
- WaitForConnection() - blocks until connected, returns error code
- PrintCaptureProgress() - prints throughput/memory/time stats
- PrintWorkerFailure() - prints failure details with callstack

Functions are declared in CaptureOutput.hpp and implemented in
CaptureOutput.cpp. Both tracy-capture and future tools can share
this code.

Co-authored-by: Grégoire Roussel <gregoire.roussel@wandercraft.eu>
2026-03-02 21:28:22 +01:00
Bartosz Taudul
f5545f864d Document tracy-merge utility in the manual 2026-03-02 20:36:22 +01:00
Bartosz Taudul
2e82525fb4 Fix plot handling in tracy-merge
- Always export plots (remove -p/--export-plots option)
- Add plot name disambiguation: prefix with process name
- Include PID in name when same process/plot appears in multiple traces
2026-03-02 20:35:23 +01:00
Bartosz Taudul
0dc6be27f3 Add tracy-merge tool for combining trace files
Merges multiple .tracy files into a single combined trace using the
Import API. Each trace's threads are remapped using compound TIDs
encoding (pid << 32) | tid to prevent collisions.

Thread names are prefixed with process name. If the same process/thread
name combination appears in multiple traces, PID is included to
disambiguate (e.g., myapp[12345]/MainThread).

Co-authored-by: Grégoire Roussel <gregoire.roussel@wandercraft.eu>
2026-03-02 20:35:20 +01:00
Bartosz Taudul
49590756a0 Extract broadcast message parsing into TracyBroadcast
Move broadcast message parsing logic from profiler/src/main.cpp into
server/TracyBroadcast.cpp/hpp. This reduces code duplication and enables
reuse by other tools (e.g., multi-capture).

ParseBroadcastMessage() handles all broadcast protocol versions (0-3) and
returns std::optional<BroadcastMessage>. ClientUniqueID() generates a unique
identifier from IP address and port.

Co-authored-by: Grégoire Roussel <gregoire.roussel@wandercraft.eu>
2026-03-02 19:45:48 +01:00
Bartosz Taudul
9442517f30 Remove trailing whitespace. 2026-03-02 19:40:41 +01:00
Marcos Slomp
93036b6877 code review: implement in header, but don't bring windows.h along for the ride 2026-03-01 08:14:10 -08:00
Marcos Slomp
42b0512517 fix copy-pasta... 2026-02-28 20:02:21 -08:00
Marcos Slomp
83707a9c2f updated support list 2026-02-28 20:02:17 -08:00
Marcos Slomp
0f170f51c6 report GUI initialization error before terminating 2026-02-28 20:00:11 -08:00
Marcos Slomp
960911f263 update manual with remarks about Windows on ARM 2026-02-28 20:00:11 -08:00
Marcos Slomp
e41ae15f27 using ARM64 intrinsics on Windows on ARM 2026-02-28 20:00:11 -08:00
Bartosz Taudul
aa30c611a8 Merge pull request #1286 from slomp/slomp/touchpad-zoom-fix
Have Touchpad gestures either scroll or zoom the timeline, but not both together
2026-02-28 22:55:25 +01:00
Marcos Slomp
20932eae88 formatting 2026-02-27 19:30:35 -08:00
Marcos Slomp
54c63c11d4 ensure touchpad gestures either scroll or zoom the timeline, but not both simultaneously 2026-02-27 19:30:35 -08:00
Bartosz Taudul
d6620568e5 Make tool reply size limit configurable in LLM settings
Add option to configure the maximum tool reply size in the advanced
settings of the LLM assistant. The limit can be enabled/disabled via
a checkbox, with the value stored in bytes. The context-based limit
is now displayed alongside the configured limit for transparency.
2026-02-26 22:40:51 +01:00
Bartosz Taudul
ad659b8f8e Update manual. 2026-02-26 22:33:50 +01:00
Bartosz Taudul
8420a1d7d6 Let's try automatic upload of release artifacts. 2026-02-20 00:27:41 +01:00
Bartosz Taudul
730dce67e6 Split build.yml into windows.yml and macos.yml. 2026-02-20 00:10:57 +01:00
Bartosz Taudul
a9070da72e Cache CPM on CI. 2026-02-19 23:07:00 +01:00
Bartosz Taudul
0abf0083be Enable workflow dispatch for CI jobs. 2026-02-19 23:06:33 +01:00
Bartosz Taudul
2bc3b87a2d Fix TracyLlm initialization when LLM is disabled. 2026-02-19 18:33:45 +01:00
Bartosz Taudul
95661c24df Revert "Bump usearch to 2.24.0."
This reverts commit 6de054002d.
2026-02-19 18:03:51 +01:00
Bartosz Taudul
27a4091975 Merge pull request #1284 from slomp/slomp/syminit-path-win32
Ensure executable path is inspected when looking for PDB files
2026-02-19 12:27:42 +01:00
Marcos Slomp
853144214b buffer checks and typo 2026-02-18 16:13:26 -08:00
Bartosz Taudul
574e0d17ec Reorder symbol statistics checkboxes and disable kernel when external is off.
External symbols checkbox now appears before kernel symbols, and kernel
is disabled when external is not selected since kernel symbols are a
subset of external symbols.
2026-02-19 00:51:04 +01:00
Bartosz Taudul
cea95bdede Do not show external symbols, frame by default. 2026-02-19 00:45:44 +01:00
Marcos Slomp
12da626fd1 ensure executable path is inspected when looking for pdb files 2026-02-17 14:27:07 -08:00
Bartosz Taudul
6de054002d Bump usearch to 2.24.0. 2026-02-17 22:06:06 +01:00
Bartosz Taudul
9079baf0b3 Bump capstone to 6.0.0-Alpha7. 2026-02-17 22:01:39 +01:00
Bartosz Taudul
a754bbe3a4 Bump imgui to 1.92.6-docking. 2026-02-17 21:49:11 +01:00
Bartosz Taudul
2ecb45d8c0 Font data must be always available. 2026-02-17 21:48:43 +01:00
Bartosz Taudul
ebd9df6ab9 Merge pull request #1283 from navvyswethgraphics/support_windows_arm64_msvc
Add native Windows ARM64 (MSVC) support across profiler, server, and ToyPathTracer sample
2026-02-17 17:38:19 +01:00
Naveen Regulla
99b502f9a4 simplify and clarify leading zeros calculation 2026-02-17 17:13:36 +05:30
Naveen Regulla
9879a31fc5 Add Windows on ARM64 with MSVC support for Tracy Profiler
Introduce Windows ARM64(native) support across ToyPathTracer,
profiler, and server code paths when building with MSVC(_M_ARM64).

Key changes:
- MathSimd.h/Maths.h:
   - Fix NEON movemask constants for MSVC/ARM64 by loading from a uint32_t[]
    via vld1q_u32() and using vdupq_n_u32() for highbit.
- enkiTS/TaskScheduler.cpp:
   - Provide Pause() implementation on _M_ARM64 using __yield().
- profiler/winmain.cpp:
   -  AVX feature checks to x86/x64 only and skip on ARM64.
- server/TracyPopcnt.hpp:
   - Implement TracyCountBits using ARM NEON intrinsics.
   - Implement TracyLzcnt using _BitScanReverse64().
2026-02-17 16:42:50 +05:30
Bartosz Taudul
75320a3353 Fix race condition when regenerating LLM reply.
The chat regenerate/trash button handling had a monolithic lock that
blocked the worker thread during token counting. The token counting
is performed by calling TracyLlmApi::Tokenize(), which issues a
blocking HTTP POST request to the LLM API - on the UI thread.

To avoid blocking both the worker and freezing the UI during HTTP
calls, the lock was split into m_jobsLock and m_chatLock. However,
this introduced a race condition.

For the assistant role (regenerate message action), the code:
1. Stops the current job and queues a new one (under m_jobsLock)
2. Releases the lock
3. Performs token counting via HTTP calls (no lock held)
4. Re-acquires m_jobsLock and stops m_currentJob again

Between steps 2 and 4, the worker thread can complete the old job
and pick up the newly queued job. The stop at step 4 then incorrectly
stops the new regenerate job instead of the old one.

Under the original monolithic lock, the worker couldn't access
m_currentJob until after step 4, so the stop always applied to the
correct job. After the split, the second stop became harmful for
the assistant case.

The fix makes the second stop conditional on user role only (thrash
action), since that's the case where no new job is queued and we
genuinely need to stop any running generation before the user edits
their message.
2026-02-17 00:04:53 +01:00
Bartosz Taudul
c1556a0a73 Merge pull request #1281 from slomp/slomp/fix-zoom-hang
Fix UI hangs due to mouse-wheel zooming
2026-02-12 18:55:35 +01:00
Bartosz Taudul
02a229b12f Merge pull request #1282 from DaniPopes/dani/fix-wasm-paste
fix: handle paste events in wasm backend
2026-02-12 13:24:38 +01:00
DaniPopes
7d27fe6ff9 fix: handle paste events in wasm backend
Listen for browser paste events and directly inject clipboard text via
AddInputCharactersUTF8. Also suppress character input when Ctrl/Meta is
held to prevent 'v' from being typed on Cmd+V.
2026-02-11 23:42:45 -05:00
Marcos Slomp
f61fa7b0e4 ensure that t0 <= t1 to prevent time-point crossover (leading to UI hangs) 2026-02-11 14:45:38 -08:00
Bartosz Taudul
0d3b5b8a04 Merge pull request #1280 from DaniPopes/dani/apple-thread-name-no-truncate
Don't truncate thread names to 15 chars on Apple platforms
2026-02-11 22:39:06 +01:00
Bartosz Taudul
2d9bed27f2 Merge pull request #1279 from DaniPopes/dani/fix-macos-zoom-scale
fix: UI zoom scale not applying on macOS
2026-02-11 22:34:56 +01:00
DaniPopes
d47344187d fix: don't truncate thread names to 15 chars on Apple platforms 2026-02-11 16:25:42 -05:00
DaniPopes
12a964d3be fix: UI zoom scale not applying on macOS
On macOS with Retina displays, dpiScale is 2.0 but gets overridden to
userScale alone under __APPLE__. The early-return check compared
prevScale against the pre-override value (dpiScale * userScale), which
for 50% zoom evaluates to 2.0 * 0.5 = 1.0, matching the previous
prevScale of 1.0 and causing an early return before the scale change
could take effect. Moving the __APPLE__ override before the early-return
check ensures the comparison uses the actual effective scale.
2026-02-10 16:33:02 -05:00
Bartosz Taudul
ea8eca6a45 Merge pull request #1273 from siliceum/WSL-and-vm-support
Better support for WSL2/VMs
2026-02-09 11:45:55 +01:00
Clément Grégoire
b890719fdd Remove stray newline in TracySysTrace.cpp 2026-02-09 11:44:16 +01:00
Clément Grégoire
e9073800d5 Remove extraneous newline in meson.build 2026-02-09 11:41:11 +01:00
Clément Grégoire
d089c3e1b0 CMake: Enforce TRACY_TIMER_FALLBACK when TRACY_DISALLOW_HW_TIMER is set. 2026-02-09 11:40:07 +01:00
Clément Grégoire
b778b67676 Fix trailing whitespace 2026-02-09 11:37:07 +01:00
Clément Grégoire
2b2fafbcfc Start cleaning TRACY_HW_TIMER checks.
Ideally I think we might want to have TRACY_HW_TIMER mean only TSC/CNTVCT, and define TRACY_TIMER_FALLBACK for platforms that don't have them or have a special case such as iOS.
But for now, keep the same behaviour.
2026-02-09 11:30:24 +01:00
Bartosz Taudul
21086a25d6 Merge pull request #1275 from The-Briel-Deal/message_l_regress
Fix regression in TracyCMessageL*() functions
2026-02-08 23:04:54 +01:00
Gabriel Ford
08969fde4b Fix regression in TracyCMessageL*() functions
Fixes: https://github.com/wolfpld/tracy/issues/1274
2026-02-08 16:42:13 -05:00
Clément Grégoire
b27561c21e Add TRACY_DISALLOW_HW_TIMER for VMs / WSL2 2026-02-08 17:10:24 +01:00
Clément Grégoire
79cb60025d Monotonic clock fallback for systrace 2026-02-08 17:07:00 +01:00
Bartosz Taudul
04f24cb222 Merge pull request #1272 from DaniPopes/wasm-clipboard
Implement clipboard support for WASM backend
2026-02-07 12:58:09 +01:00
DaniPopes
a23e910d5f Implement clipboard support for WASM backend
The Emscripten backend was missing Platform_SetClipboardTextFn/GetClipboardTextFn,
so ImGui::SetClipboardText was a no-op in the browser.
Hook navigator.clipboard.writeText for writes and keep a local copy for reads.
2026-02-07 03:36:25 +01:00
Bartosz Taudul
c93c9bce6f Improve how tool calls are presented to user.
1. Tool replies are now integrated with tool calls.
2. Tool calls now have textual descriptions.
2026-02-06 18:37:01 +01:00
Bartosz Taudul
0b02b097a9 Pass current and end chat iterators to TracyLlmChat::Turn(). 2026-02-06 17:33:59 +01:00
Bartosz Taudul
9d78cca5ff Redo LLM locks. 2026-02-06 02:28:14 +01:00
Bartosz Taudul
a31ab53d26 Check if the response contains finish_reason before getting its value. 2026-02-05 18:31:05 +01:00
Bartosz Taudul
66cc77bd5f Don't access ghost zones before they are ready. 2026-02-05 00:42:42 +01:00
Bartosz Taudul
5a41f422fe Merge pull request #1269 from DaniPopes/thread-sort
Sort threads by ID after name
2026-02-04 14:08:26 +01:00
DaniPopes
5c5af7c1e5 Sort threads by ID after name
The "sort" button for threads uses an unstable sort, so threads with
the same name will shuffle around without ever stabilizing.

Use `id` to sort after comparing the name.
2026-02-04 06:51:43 +01:00
Bartosz Taudul
ca5ef812a3 Apple is also busted. 2026-02-01 20:39:53 +01:00
Bartosz Taudul
a9ea7ec1c9 Workaround libc++ issues. 2026-02-01 18:57:49 +01:00
Bartosz Taudul
8f0c83dbf9 Fix View ptr assignment. 2026-02-01 18:55:53 +01:00
Bartosz Taudul
2b201e6f59 RetrieveThread() uses a cache that cannot be shared between threads.
Note: IsThreadFiber() uses the same functionality, but is only called from
the main thread.
2026-02-01 18:01:39 +01:00
Bartosz Taudul
c86549a3bb View is accessed concurrently. 2026-02-01 17:29:34 +01:00
Bartosz Taudul
aba3ae2869 View's m_wasActive is used concurrently. 2026-02-01 16:55:46 +01:00
Bartosz Taudul
d1e831f69d Proper way of setting sanitizer parameters. 2026-02-01 16:44:15 +01:00
Bartosz Taudul
1d2b6cca24 Pack source code attachments.
Example source file, glm-4.7-flash:

5519 -> 4699 tokens (85%)
2026-02-01 16:37:42 +01:00
Bartosz Taudul
d71a38632c Nice formatting for host info. 2026-02-01 14:53:22 +01:00
Bartosz Taudul
d4d9339d95 Provide name of the profiled program to LLM. 2026-02-01 14:53:22 +01:00
Bartosz Taudul
0ad8767903 Explicitly mark non-inline frames as non-inline in LLM attachment. 2026-02-01 14:53:19 +01:00
Bartosz Taudul
1c383d8589 Merge pull request #1268 from siliceum/reenable-tracy-debug-as-log
Reenable TracyDebug LogString except under TRACY_DELAYED_INIT and not TRACY_MANUAL_LIFETIME
2026-02-01 14:53:02 +01:00
Clément Grégoire
55ce01c69e Reenable TracyDebug LogString except under TRACY_DELAYED_INIT and not TRACY_MANUAL_LIFETIME 2026-02-01 14:50:37 +01:00
Bartosz Taudul
e1fa883fbb Merge pull request #1267 from siliceum/fix/test-suppport-manual-lifetime
Tests should work under TRACY_MANUAL_LIFETIME.
2026-02-01 14:46:13 +01:00
Clément Grégoire
be78dc4bfb Tests should work under TRACY_MANUAL_LIFETIME.
This calls tracy::StartupProfiler(); before any other tracy call (in static init) if TRACY_MANUAL_LIFETIME is set
2026-02-01 14:45:00 +01:00
Bartosz Taudul
bc122d5c3d Do not call Glue() in PrintTextExt(). 2026-02-01 02:35:26 +01:00
Bartosz Taudul
b60ab86fa5 Extend link support to code sections, separators, etc. 2026-02-01 02:14:42 +01:00
Bartosz Taudul
32fae40c4e Extract link hover functionality to a separate function. 2026-02-01 02:05:08 +01:00
Bartosz Taudul
324ecdcb99 Change source code separator in LLM attachments. 2026-02-01 01:48:55 +01:00
Bartosz Taudul
c886c8fa00 Remove remains of vision in tool replies. 2026-01-31 19:21:24 +01:00
Bartosz Taudul
925732914a Draw source code preview in source file link tooltip. 2026-01-31 19:17:44 +01:00
Bartosz Taudul
d1ae380cc2 Make View::DrawSourceTooltip() public. 2026-01-31 19:17:07 +01:00
Bartosz Taudul
9d33668c9d Proper check for source file validity. 2026-01-31 18:54:43 +01:00
Bartosz Taudul
903b6b198f Retrieve source file string index and line number only once. 2026-01-31 18:42:07 +01:00
Bartosz Taudul
30ea4ed341 Print a nice tooltip for source links. 2026-01-31 18:35:37 +01:00
Bartosz Taudul
5b7a6bf447 Add instructions for providing source file links. 2026-01-31 18:03:31 +01:00
Bartosz Taudul
4fe8d16a20 Add support for source file links in markdown renderer. 2026-01-31 18:03:11 +01:00
Bartosz Taudul
7cc7e484b9 Make source search results more compact. 2026-01-30 22:55:55 +01:00
Bartosz Taudul
cfcc8af5c3 Remove indentation from tool replies. 2026-01-30 22:37:50 +01:00
Bartosz Taudul
3ce2905582 Default value does not need to be repeated. 2026-01-30 22:36:16 +01:00
Bartosz Taudul
67b75ac7fb Restore attachment indentation when viewing contents in UI. 2026-01-30 22:31:25 +01:00
Bartosz Taudul
99b70f7a6e Remove indentation from LLM attachments.
This has quite large effect on number of tokens. Example assembly attachment:

glm-4.7-flash: 7452 -> 5799 (77%)
gpt-oss-20b:   6896 -> 5245 (76%)
2026-01-30 22:27:55 +01:00
Bartosz Taudul
de002ed071 Update NEWS. 2026-01-30 21:49:17 +01:00
Bartosz Taudul
50eae09cda Source location may be missing a line number.
The valid check here is for the source file index being set (active).
The line number might be zero.

This fixes the "black" unknown source location in assembly listing.
2026-01-30 21:44:24 +01:00
Bartosz Taudul
b9a4bf4f7b Use the intended weighting order in ManageContext(). 2026-01-30 20:58:56 +01:00
Bartosz Taudul
d6e62b3c1f Spell out (long!) source file names in assembly attachments only once. 2026-01-30 01:38:20 +01:00
Bartosz Taudul
e017f504c6 Split source_file parameter context into context and context_back. 2026-01-30 01:07:15 +01:00
Bartosz Taudul
81e8b1a4d8 Update NEWS. 2026-01-29 23:05:40 +01:00
Bartosz Taudul
b7c54253ff Include TracyCrashHandler in a list of frames to cut on crash on Linux. 2026-01-29 22:44:23 +01:00
Bartosz Taudul
eb18dafb22 Check for a substring match in CutCallstack. 2026-01-29 22:44:13 +01:00
Bartosz Taudul
3ddb96b9af Change CutCallstack/SendCallstack interface to accept an array. 2026-01-29 22:41:21 +01:00
Bartosz Taudul
0c6b551afa Make TracyCrashHandler visible externally. 2026-01-29 22:39:24 +01:00
Bartosz Taudul
5a1ff2496c Rename CrashHandler to TracyCrashHandler. 2026-01-29 22:19:50 +01:00
Bartosz Taudul
7ef92c3547 Add crash reason and thread information to LLM attachment, if appropriate. 2026-01-29 22:09:01 +01:00
Bartosz Taudul
73572e6d7f Display notification that crash callstack is crash callstack. 2026-01-29 21:50:47 +01:00
Bartosz Taudul
ebc2c9e28a Use ranges. 2026-01-29 21:48:17 +01:00
Bartosz Taudul
ea9dbe5643 Prefer removal of older tool responses. 2026-01-28 21:34:19 +01:00
Bartosz Taudul
237058420f Make the forget message explain what happened. 2026-01-28 21:25:23 +01:00
Bartosz Taudul
b0704ba35f Adjust minimum available context logic.
Increase the context quota from 70% to 80%, as the previous value was too
conservative with large contexts.

Add a minimum bound of 4K to make small context workable.
2026-01-28 21:15:59 +01:00
Bartosz Taudul
9b98bce193 Reword no network access response. 2026-01-28 21:15:00 +01:00
Bartosz Taudul
41dd81ef7e Tighter packing of source file contents. 2026-01-28 20:59:33 +01:00
Bartosz Taudul
55f4f5f704 Change LLM API timeout from 5 to 20 minutes. 2026-01-28 18:47:14 +01:00
Bartosz Taudul
a371325346 Bump dependencies. 2026-01-26 20:48:15 +01:00
Bartosz Taudul
d1148377ae Insert hint in a valid way. 2026-01-26 11:56:43 +01:00
Bartosz Taudul
cf001a38df Adjust max size calculation. 2026-01-25 21:05:36 +01:00
Bartosz Taudul
841af4795c System prompt update. 2026-01-25 21:01:09 +01:00
Bartosz Taudul
daef2f4c6b Remove span tag duplication in retrieved web pages. 2026-01-25 20:12:34 +01:00
Bartosz Taudul
0a58d88be2 Go back to regex paths in source search. 2026-01-25 16:29:53 +01:00
Bartosz Taudul
27ecaed76e Use regex in source search. 2026-01-25 16:12:45 +01:00
Bartosz Taudul
beb4cd4ea6 Perform query transformation only once. 2026-01-25 16:12:25 +01:00
Bartosz Taudul
d4a56c9a37 Tweak system prompt. 2026-01-25 15:47:08 +01:00
Bartosz Taudul
a4324d595d Add optional file globbing to SourceSearch. 2026-01-25 02:41:00 +01:00
Bartosz Taudul
63c6e48562 Optional string parameter macro. 2026-01-25 02:14:45 +01:00
Bartosz Taudul
1f4b2dd45f Try to show some search results, if no space for full data. 2026-01-25 02:07:25 +01:00
Bartosz Taudul
7a2aaa6e8e Refine system prompt. 2026-01-25 01:14:16 +01:00
Bartosz Taudul
b2dcd55d95 Better handling of error responses. 2026-01-25 00:35:18 +01:00
Bartosz Taudul
9c096a31f0 Fix copy paste error. 2026-01-24 19:57:33 +01:00
Bartosz Taudul
cdec805cc9 Underline links. 2026-01-24 14:23:15 +01:00
Bartosz Taudul
7c54c824ab Add support for markdown strikethrough. 2026-01-24 14:16:16 +01:00
Bartosz Taudul
a7ed5e1fb3 Support rendering markdown task lists. 2026-01-24 13:50:39 +01:00
Bartosz Taudul
73694c7a24 Cleanup enums. 2026-01-24 01:50:11 +01:00
Bartosz Taudul
bc6cf23f08 No line breaks in Lua locations. 2026-01-24 01:25:35 +01:00
Bartosz Taudul
b624ada00a Cosmetics. 2026-01-24 01:16:28 +01:00
Bartosz Taudul
5e078ed0dd Fix Lua integration with test. 2026-01-24 01:10:56 +01:00
Bartosz Taudul
26b1782b89 Remove TracyDebug() logging.
TracyDebug() is in the profiler init path, and logging the message causes
the profiler to be initialized (the second time), which deadlocks in
GetProfilerData().
2026-01-24 00:49:25 +01:00
Bartosz Taudul
cfb5f5595a Rewrite system prompt. 2026-01-23 23:22:59 +01:00
Bartosz Taudul
b8cb7a1883 Merge pull request #1262 from kubkon/capture-queue-backlog
capture: Display current query backlog
2026-01-23 17:00:47 +01:00
Jakub Konka
e5646b1f6a capture: Display current query backlog 2026-01-23 15:26:07 +01:00
Bartosz Taudul
07147111b2 Merge pull request #1258 from liungkejin/patch-1
fix a nullptr crash on android devices
2026-01-18 12:28:53 +01:00
Kejin
d6597b0bdd Check if pw_gecos is non-empty on Android
Ensure pw_gecos is not empty before returning.
2026-01-18 14:01:19 +08:00
Bartosz Taudul
805d4bf6fd Better table sizing flags? 2026-01-17 01:55:26 +01:00
Bartosz Taudul
faade0f871 Merge pull request #1259 from davidkern/macos-scaling
fix: 2x scaling on macos with ImGui 1.92
2026-01-16 02:42:45 +01:00
David Kern
0a438193ba fix: 2x scaling on macos with ImGui 1.92 2026-01-15 17:01:40 -08:00
Bartosz Taudul
ba677b725b Merge pull request #1230 from slomp/slomp/etw-refactor-2
Toggling EnableFlags after the "NT Kernel Logger" session has started
2026-01-15 23:00:51 +01:00
Bartosz Taudul
00ce663136 Allow attaching symbol source code to LLM, with execution costs. 2026-01-15 22:14:10 +01:00
Bartosz Taudul
2bc09a42cb Use contains(). 2026-01-15 21:56:19 +01:00
Bartosz Taudul
a34d7fb01a Add icons to models. 2026-01-15 21:40:47 +01:00
Bartosz Taudul
c4207dec75 Allow attaching source code to LLM in simple view. 2026-01-15 21:38:12 +01:00
Bartosz Taudul
ef77600bae Description is optional. 2026-01-15 20:55:13 +01:00
Marcos Slomp
839b38d2ec removing implicit/default argument value 2026-01-15 11:29:49 -08:00
Marcos Slomp
44696c47c6 formatting 2026-01-15 11:27:49 -08:00
Marcos Slomp
dacb3dbae6 support for toggling EnableFlags after the singleton kernel session has started 2026-01-15 11:20:06 -08:00
Bartosz Taudul
eeacbac8bc Workaround issues with LM Studio.
LM Studio will prefix the assistant's content with '\n\n'. While this is
not a problem when proper text follows (the markdown parser will ignore
this), the empty check does fail.
2026-01-15 17:59:00 +01:00
Kejin
1cad2903a1 fix a nullptr crash on android devices 2026-01-15 21:54:24 +08:00
Bartosz Taudul
fc63779b18 Reduce nested divs in retrieved webpages. 2026-01-15 02:37:47 +01:00
Bartosz Taudul
3817db0dc2 Fix newline removal in retrieved webpages. 2026-01-15 02:33:45 +01:00
Bartosz Taudul
fa8a57af86 Include search excerpt in wikipedia search results.
This directly references the search keywords in articles that may seem
unrelated based on their title or description alone.
2026-01-15 02:25:03 +01:00
Bartosz Taudul
01d1850b0f Return 10 results in wikipedia search. 2026-01-15 02:22:08 +01:00
Bartosz Taudul
c153f598b6 Request prompt caching. 2026-01-14 18:48:28 +01:00
Bartosz Taudul
23e752a03b Rework LLM summary error display in callstack window. 2026-01-14 02:50:09 +01:00
Bartosz Taudul
828d32521d Return proper error response from TracyLlmApi::SendMessage(). 2026-01-14 02:49:38 +01:00
Bartosz Taudul
227c7133c3 Add animated waiting dots in place of ellipsis in call stack window. 2026-01-14 02:25:00 +01:00
Bartosz Taudul
b19d9622b3 Add small version of DrawWaitingDots().
The normal one is fit for lines with full size buttons, entry fields, etc.
2026-01-14 02:24:02 +01:00
Bartosz Taudul
5b568d7bce Add in-line waiting dots drawer. 2026-01-14 02:17:56 +01:00
Bartosz Taudul
a991b4fd50 Cosmetics. 2026-01-14 02:14:25 +01:00
Bartosz Taudul
24ea5118e0 Rename DrawWaitingDots() to DrawWaitingDotsCentered(). 2026-01-14 02:12:00 +01:00
Bartosz Taudul
38b73254e9 Add emoji font. 2026-01-14 01:51:32 +01:00
Bartosz Taudul
3547009d1c Don't lock user manual window size. 2026-01-14 01:23:39 +01:00
Bartosz Taudul
ce74512b92 Update manual. 2026-01-14 00:58:07 +01:00
Bartosz Taudul
bc33767aab Update NEWS. 2026-01-14 00:21:37 +01:00
Bartosz Taudul
040b4d0e33 Merge pull request #1256 from siliceum/test/add-lua-test
Add lua to test/test.cpp
2026-01-13 15:21:35 +01:00
Bartosz Taudul
43c0fe9b61 Merge pull request #1255 from siliceum/fix/lua-callstack-depth
Don't try to send callstacks of depth 0 (would trigger assert in `tracy::Callstack`)
2026-01-13 15:19:11 +01:00
Bartosz Taudul
1fa1a4f5e7 Merge pull request #1254 from siliceum/fix/constexpr-string
Use string_view as constexpr std::string requires recent compilers
2026-01-13 15:18:12 +01:00
Clément Grégoire
9acc186ceb Don't try to send callstacks of depth 0 (would trigger assert in tracy::Callstack) 2026-01-13 11:28:38 +01:00
Clément Grégoire
9b135b53b4 Add lua to test/test.cpp 2026-01-13 11:25:44 +01:00
Clément Grégoire
5b79a9a825 Use string_view as constexpr std::string requires recent compilers
This was not building with visual studio Version 17.14.13 (August 2025)
2026-01-13 10:57:18 +01:00
Bartosz Taudul
76e0ab135b Keep window redrawing while waiting for message reply. 2026-01-11 22:32:25 +01:00
Bartosz Taudul
ed8fc7690f Implement automatic callstack annotation. 2026-01-11 20:54:10 +01:00
Bartosz Taudul
0b9dcc0fbe Add callstack annotations option. 2026-01-11 20:50:37 +01:00
Bartosz Taudul
b53e10b25e Fake a progress indicator. 2026-01-11 20:42:13 +01:00
Bartosz Taudul
3008cb8ad7 Add LLM summaries for callstacks. 2026-01-11 20:07:09 +01:00
Bartosz Taudul
1918667bbd Use proper types for RangeSlim init. 2026-01-11 19:37:38 +01:00
Bartosz Taudul
6f06a25669 Change messages icon to a single-way conversation. 2026-01-11 19:11:20 +01:00
Bartosz Taudul
3ae9db27de Change chat icon to a two-way conversation. 2026-01-11 19:10:58 +01:00
Bartosz Taudul
2ef21b93c5 More compact call stack window controls. 2026-01-11 19:06:01 +01:00
Bartosz Taudul
2bf0a3c7f9 Implement fast message queries. 2026-01-11 18:56:19 +01:00
Bartosz Taudul
9b5cbf835d Implement separate-channel non-streamed chat completion requests. 2026-01-11 18:54:11 +01:00
Bartosz Taudul
761cb1041b Add fast model selection to the UI. 2026-01-11 17:58:22 +01:00
Bartosz Taudul
caba47a66b Don't copy the string to print if no replacements are needed. 2026-01-11 16:52:35 +01:00
Bartosz Taudul
bf61589f3d Separate wrapped text printer from text fixup. 2026-01-11 16:20:06 +01:00
Bartosz Taudul
b26fefd325 Smaller header font sizes. 2026-01-10 15:22:29 +01:00
Bartosz Taudul
a04b0e515a Undo newline when the word position is already at the start of the line. 2026-01-10 15:10:49 +01:00
Bartosz Taudul
ec2ac9f227 Fix table rendering. 2026-01-10 01:14:03 +01:00
Bartosz Taudul
7268cd8c32 Include external jump destination names in LLM attachment. 2026-01-10 00:32:40 +01:00
Bartosz Taudul
c0acafea63 Assume paths containing hidden files are external.
A typical use case would be $(HOME)/.cache/cpm/somelib/file.h.

Special care is needed to avoid filtering out dot-dot path elements: /../
While these have been normalized for some time now on the client-side, old
traces might still contain the dot-dot elements.
2026-01-09 03:05:04 +01:00
Bartosz Taudul
aeadeace0f Check for both versions of Program Files in external paths. 2026-01-09 01:06:32 +01:00
Bartosz Taudul
d4c88dc7c4 Allow filtering out external functions in sampling statistics view. 2026-01-09 01:05:17 +01:00
Bartosz Taudul
560f8f935d Add ability to attach entry call stacks to LLM. 2026-01-08 22:35:03 +01:00
Bartosz Taudul
723bdc71dc Make GetCallstackJson available via View. 2026-01-08 22:34:45 +01:00
Bartosz Taudul
d9200351ef Allow case-insensitive code search. 2026-01-08 21:29:26 +01:00
Bartosz Taudul
d1a4746076 Add ParamOptBool(). 2026-01-08 21:19:08 +01:00
Bartosz Taudul
517366bec9 Use templates for GetParam() implementation. 2026-01-08 21:18:47 +01:00
Bartosz Taudul
c1ffbe8e0d Check if mouse is over the window before acting on mouse click. 2026-01-08 20:50:26 +01:00
Bartosz Taudul
825ab7f411 Implement search in code. 2026-01-08 20:48:19 +01:00
Bartosz Taudul
e4ff8d34be Move IsFrameExternal from View to TracyUtility.hpp. 2026-01-08 20:28:16 +01:00
Bartosz Taudul
a5e5e8a435 Workaround emscripten scroll issues.
Obviously not the correct fix, but whatever.
2026-01-07 23:29:35 +01:00
Bartosz Taudul
1413bb4b4d Merge pull request #1250 from YaLTeR/fix-scrolling
Fix scrolling speed for touchpads and high-res wheels on Wayland
2026-01-07 23:16:19 +01:00
Bartosz Taudul
e37d58c60c Better printing of tool calls. 2026-01-07 17:47:52 +01:00
Bartosz Taudul
2903fcabe4 Change default source_file context to 50 lines. 2026-01-07 17:03:42 +01:00
Bartosz Taudul
26c5999a6e Add callstack inspection workflow. 2026-01-07 17:02:24 +01:00
Bartosz Taudul
9774fdd017 System prompt reword. 2026-01-07 17:02:12 +01:00
Bartosz Taudul
14f0ed1cba Add hard limit on context usage.
Big MoE models + big context size = slow prompt processing. Limit tool
reply size to a reasonable amount.
2026-01-07 16:31:48 +01:00
Bartosz Taudul
f00694fae0 Add optional context parameter to source_file calls. 2026-01-07 16:24:34 +01:00
Bartosz Taudul
3c82b63046 Allow optional parameters with a default value. 2026-01-07 16:24:10 +01:00
Bartosz Taudul
82d47db47d Give LLM profiling instructions. 2026-01-07 16:13:00 +01:00
Ivan Molodetskikh
203f6cc508 timeline: Use fractional vertical scroll amount in calculation
Before this commit, vertical scroll was always discrete. At least on
Wayland, this caused extremely fast scrolling on touchpads (that send
lots of small axis events) and on mice with high-resolution wheels (that
also send lots of small axis events). After this commit, all of this
scrolling works correctly, at a speed matching regular wheels.
2026-01-05 19:46:37 +03:00
Ivan Molodetskikh
218265ad37 wayland: Adjust scroll scaling
Regular mice send a value of 15 for one wheel tick, not 8.

This currently doesn't change anything about vertical scrolling since
it's handled discretely, but that will change in the next commit.
2026-01-05 19:44:42 +03:00
Bartosz Taudul
189a4fc203 Glue together adjacent user messages.
In most cases this is not needed. However, some models, like Gemma3 or
Devstral require that user and assistant messages alternate.

The only case where this can happen in Tracy is when an attachment is added:

[
  {
    "role": "user",
    "content": "<attachment>\n..."
  },
  {
    "role": "user",
    "content": "Tell me something about..."
  }
]

It is trivial to glue these messages together. This is only done when sending
the data in the REST request, as the chat rendering logic expects these to be
separate and it would be too much work unnecessary work to do it "proper".
2026-01-05 13:45:50 +01:00
Bartosz Taudul
711771bc27 Replace narrow no-break space with no-break space in markdown text.
Nemotron 3 Nano outputs these spaces in the text. The currently used font
(or is it ImGui?) is not able to render this, and draws replacement character
instead.
2026-01-05 13:35:51 +01:00
Bartosz Taudul
1851743c9d Include offset data in assembly attachments. 2026-01-04 23:16:17 +01:00
Bartosz Taudul
405778acf3 Add button for attaching complete assembly to LLM. 2026-01-04 23:10:44 +01:00
Bartosz Taudul
4d7670bac5 Extract LLM assembly range attaching to a separate function. 2026-01-04 23:04:16 +01:00
Bartosz Taudul
51cee7f07d Inject sampled execution cost into assembly attachments. 2026-01-04 22:53:59 +01:00
Bartosz Taudul
14bdad425f No need for nesting source information. 2026-01-04 22:18:15 +01:00
Bartosz Taudul
29f304554d Explicitly say the frame and subframe numbers for each frame. 2026-01-04 21:56:19 +01:00
Bartosz Taudul
b79f3232b6 Properly update system prompt on first message. 2026-01-04 15:29:05 +01:00
Bartosz Taudul
3f84749b05 Implement system prompt updates without clearing chat. 2026-01-04 15:28:49 +01:00
Bartosz Taudul
d146714185 Merge pull request #1249 from siliceum/fix/lua-message
Fix `TracyLua.hpp` compilation
2026-01-04 01:28:11 +01:00
Clément Grégoire
e5d251a0be Fix TracyLua.hpp build 2026-01-03 22:19:49 +01:00
Bartosz Taudul
9d5b380ea9 Implement markdown tables. 2026-01-03 21:22:38 +01:00
Bartosz Taudul
6f5fb3044a Add separation between multiple assistant responses. 2026-01-02 12:40:22 +01:00
Bartosz Taudul
b6f03ef75d Change assistant render order to reasoning -> content -> tool calls.
Previously reasoning and tool calls were rendered first, followed by
content. The tool call response was then rendered in the second reasoning
section. This made the tool call and response disjoint and, with the
current reasoning hiding logic, not visible at the same time.
2026-01-02 12:25:25 +01:00
Bartosz Taudul
b7a51d265c Update system prompt. 2026-01-02 03:05:01 +01:00
Bartosz Taudul
6323f1642d Refresh system prompt immediately before sending first message. 2026-01-01 17:36:46 +01:00
Bartosz Taudul
58dbde7b2f Move system prompt update to a separate function. 2026-01-01 17:33:23 +01:00
Bartosz Taudul
c2431d5c17 Bump copyright year. 2026-01-01 02:12:05 +01:00
Bartosz Taudul
63a8b4cfb4 Use proper UTF ellipsis. 2025-12-31 18:28:57 +01:00
Bartosz Taudul
34faaeb314 Display short snippet of thinking process. 2025-12-31 18:22:13 +01:00
Bartosz Taudul
523d2fb8bf Hide LLM thinking regions by default. 2025-12-31 17:47:12 +01:00
Bartosz Taudul
c01d5d5dd2 Don't create assistant entries with empty content. 2025-12-31 17:38:25 +01:00
Bartosz Taudul
09aa695048 Tool response labels now have unique ids in them. 2025-12-31 17:10:04 +01:00
Bartosz Taudul
3d9b228177 Allow disabling rendering of thinking regions. 2025-12-31 17:08:35 +01:00
Bartosz Taudul
96961f696b Unify internet icon with the welcome window. 2025-12-31 16:51:05 +01:00
Bartosz Taudul
52179c4428 Hide LLM temperature setting in advanced options. 2025-12-31 15:58:58 +01:00
Bartosz Taudul
8520c79749 Set proper width of LLM input text fields. 2025-12-31 15:57:30 +01:00
Bartosz Taudul
50e6497390 Enable horizontal scroll bars in markdown code segments. 2025-12-31 15:35:59 +01:00
Bartosz Taudul
b17002a9c0 Update markdown manual. 2025-12-31 15:28:05 +01:00
Bartosz Taudul
d9e977ed42 Fix spacing when think scope is not the first item in reply. 2025-12-31 15:26:37 +01:00
Bartosz Taudul
217906b63b Drop Ollama. 2025-12-31 15:20:28 +01:00
Bartosz Taudul
b4ff3b1c83 Do not pass AltGr to ImGui.
AltGr (right alt) is used to enter characters, at least with the Polish
keymap. ImGui uses alt to switch between some of the controls. Keep the
interaction on the (left) Alt key, and leave AltGr to do composition.
2025-12-31 14:00:01 +01:00
Bartosz Taudul
ad09ae8790 Use variables to inject data into system prompt. 2025-12-31 13:54:44 +01:00
Bartosz Taudul
5bc2e4b95c Implement full user name retrieval on win32. 2025-12-30 15:17:08 +01:00
Bartosz Taudul
9016911a04 Fix clash with winapi define crap. 2025-12-30 14:49:23 +01:00
Bartosz Taudul
4661233904 Add missing include for UNLEN definition. 2025-12-30 14:48:17 +01:00
Bartosz Taudul
f6ba6cbd4e Fix typo. 2025-12-30 14:48:11 +01:00
Bartosz Taudul
20b9d002dc Check for empty full name. 2025-12-30 14:23:37 +01:00
Bartosz Taudul
94c1614416 Store full user name in trace info. 2025-12-30 14:19:40 +01:00
Bartosz Taudul
e1b426efe6 Pass full user name to LLM. 2025-12-30 14:17:10 +01:00
Bartosz Taudul
299b641173 Implement getting full user name. 2025-12-30 14:16:53 +01:00
Bartosz Taudul
6933780aed Provide current user name to the LLM. 2025-12-30 13:52:33 +01:00
Bartosz Taudul
da85325686 Move user name retrieval to a common API. 2025-12-30 13:41:19 +01:00
Bartosz Taudul
6a26472278 Reformulate current time statement. 2025-12-30 13:26:23 +01:00
Bartosz Taudul
47806d00c8 Don't mention tool use. 2025-12-30 13:22:31 +01:00
Bartosz Taudul
fc35fa6a1d Give instructions to use multiple tools. 2025-12-30 01:50:31 +01:00
Bartosz Taudul
e889fa17f3 Bump usearch to 2.22.0. 2025-12-29 20:46:48 +01:00
Bartosz Taudul
c996c67390 Take the thinking and tool use context into account in LLM chat rendering. 2025-12-29 20:43:28 +01:00
Bartosz Taudul
ac5dabbb94 Drop user debug role. 2025-12-29 20:43:28 +01:00
Bartosz Taudul
cd9585d713 Less verbose system prompt. 2025-12-29 20:43:28 +01:00
Bartosz Taudul
237e90fe64 Adapt context management to tool role usage. 2025-12-29 20:43:27 +01:00
Bartosz Taudul
7a43036e6e Process tool calls table and respond with tool role. 2025-12-29 20:43:27 +01:00
Bartosz Taudul
26cf9591e7 Remove tool and thinking instructions from the system prompt. 2025-12-29 20:43:27 +01:00
Bartosz Taudul
167779392c Include reasoning in context removal calculation.
The calculations here are so-so at best. The only reliable source of context
usage are the server responses.
2025-12-29 20:43:27 +01:00
Bartosz Taudul
fe567e5b42 Add support for streaming reasoning and tool call responses. 2025-12-29 20:43:27 +01:00
Bartosz Taudul
edffd4af81 Check for content being available when deleting user message. 2025-12-29 20:43:27 +01:00
Bartosz Taudul
f4f3c63755 Move time information to system prompt.
This also changes the context of the information a bit. Previously it was
the current time, now it is the time when the conversation started.
2025-12-29 20:43:27 +01:00
Bartosz Taudul
0a983cb24c Check for "content" in error and attachment messages. 2025-12-29 20:43:27 +01:00
Bartosz Taudul
dedc50e848 Support adding messages completely defined by json. 2025-12-29 20:43:26 +01:00
Bartosz Taudul
c9443db053 Provide LLM tools using a standard API. 2025-12-29 20:43:26 +01:00
Bartosz Taudul
e7288604ea Including ranges is not necessary. 2025-12-29 20:43:26 +01:00
Bartosz Taudul
79ee17d2f6 Inject current time into each user message.
This is not removed later on, mainly to enable caching of previous replies
(changing any earlier message would require processing everything that's
later), but also to give the LLM a sense of passing time.
2025-12-29 20:43:26 +01:00
Bartosz Taudul
9183aef645 Do not display system prompt injected into user messages. 2025-12-29 20:43:26 +01:00
Bartosz Taudul
0246cec0a7 System reminder is no longer in use. 2025-12-29 20:43:26 +01:00
Bartosz Taudul
d385328a16 Remove prefill of assistant messages.
Does not work with models implementing reasoning in a standarized way.
2025-12-29 20:43:26 +01:00
Bartosz Taudul
1708a88445 Remove AssistantDebug LLM role. 2025-12-29 20:43:25 +01:00
Bartosz Taudul
e2a86c1756 Merge pull request #1246 from slomp/slomp/logstring-fix
fix for TRACY_FIBERS
2025-12-29 20:37:59 +01:00
Marcos Slomp
12fa5aeb5e fix for TRACY_FIBERS 2025-12-29 11:23:08 -08:00
Bartosz Taudul
6f9504c50a Redo message filtering UI. 2025-12-28 16:56:09 +01:00
Bartosz Taudul
2a9ab49d13 Use constexpr for tables. 2025-12-28 16:26:19 +01:00
Bartosz Taudul
f649943e93 Fix text formatting. 2025-12-28 16:03:44 +01:00
Bartosz Taudul
f43b86e3b3 Merge pull request #1180 from siliceum/feature/logging
Support source/severity for messages
2025-12-28 15:17:03 +01:00
Clément Grégoire
5ef64841cc Remove MessageMetadata type and replace by uint8_t everywhere 2025-12-28 15:04:18 +01:00
Clément Grégoire
2df7c53c26 Keep tracy::Profiler::Message in the stack frames that need to be ignored
This may still appear in saved traces.
2025-12-28 15:04:18 +01:00
Clément Grégoire
4cceab5ad8 Remove Profiler::Messsage since it's not part of the public API
This also replaces `___tracy_emit_message*` by `___tracy_emit_logString`.
The `TracyCMessage*` defines no long include the `;`, which may be a breaking change even though we did already require semi-colon since 0.9.0. See #493 and #592
2025-12-28 15:04:05 +01:00
Clément Grégoire
88c926d723 TracyMessage* Macros now use tracy::Profiler::LogString 2025-12-28 15:01:00 +01:00
Clément Grégoire
1a4cdef4b6 Add TracyLog to the test example 2025-12-28 15:01:00 +01:00
Clément Grégoire
f17bd3f444 TracyDebug now uses TracyInternalMessage by default unless TRACY_VERBOSE or TRACY_NO_INTERNAL_MESSAGE is defined 2025-12-28 15:00:59 +01:00
Clément Grégoire
13261b9bdc ETWErrorAction now uses message source and severity 2025-12-28 14:50:41 +01:00
Clément Grégoire
b2a7bb64ff Add tooltip for message source filters 2025-12-28 14:50:41 +01:00
Clément Grégoire
3e99b0e7c2 Add severity name tooltip 2025-12-28 14:50:41 +01:00
Clément Grégoire
a0016be7ff Allow filtering Messages by source and severity 2025-12-28 14:50:41 +01:00
Clément Grégoire
35a05aea62 Optimize message filtering a bit
Instead of decompressing and checking visibility of the thread all the time, cache the previous result.
2025-12-28 14:50:41 +01:00
Clément Grégoire
615db1a78c Refactor message filtering
This now uses a single path for all cases (filter/threads changed, new message).
Note this no longer discriminates against `m_messageFilter.IsActive()` to skip the message filter. `ImGui::PassFilter already` early outs, and if performance is a concern we might as well start by caching the result of `VisibleMsgThread` which always does a hashmap lookup.
2025-12-28 14:50:41 +01:00
Clément Grégoire
1e61dc88de Add source and severity to the server's MessageData + bump minor version for serialization
Note this does not change `sizeof(MessageData)` as there were 5 bytes left due to alignment. (now 3)
2025-12-28 14:50:38 +01:00
Clément Grégoire
f650b69591 tracy_force_inline for message metadata conversion 2025-12-28 14:44:40 +01:00
Clément Grégoire
f981330f66 Replace all messages text addr by TaggedUserlandAddress and send metadata over the network
There are two changes to the protocol:

- `QueueMessageLiteral*` were changed and what used to be addresses are now addresses+metadata
- Other messages now send `QueueMessage*Metadata` with added metadata.

This will later be used to store and transmit message sources, level, etc.
2025-12-28 14:44:40 +01:00
Clément Grégoire
9c57b229ea Introduce tracy::TaggedUserlandAddress to pack metadata with pointers 2025-12-28 14:42:40 +01:00
Bartosz Taudul
a602127edd Merge pull request #1242 from wvbbreu/cupti-driverapi-memtrace
Add CUDA Driver API memory operations to Tracy CUPTI profiling
2025-12-25 13:16:37 +01:00
Wiebe van Breukelen
66b23bb19a Add CUDA Driver API memory operations to Tracy CUPTI profiling
Extended Tracy's CUPTI callback registration to track CUDA Driver API
memory operations that were previously missing.
Registration of these events allow users to trace applications that directly
call the Driver API.
2025-12-24 12:05:51 +01:00
Bartosz Taudul
1ad248892d Fix time range limits button id overlap. 2025-12-23 14:03:54 +01:00
Bartosz Taudul
b63f605ec1 Merge pull request #1239 from slomp/slomp/macos-arm64-tsc
Apple Silicon / macOS: use ARM64 CNTVCT_EL0 instruction in GetTime()
2025-12-23 12:31:15 +01:00
Marcos Slomp
2d3fa2141e removing parentheses from define 2025-12-22 12:22:26 -08:00
Marcos Slomp
f55bd056a9 switch to using ARM64's CNTVCT_EL0 instruction instead of std::chrono::high_resolution_clock on macOS 2025-12-22 11:43:51 -08:00
Bartosz Taudul
6cd7751479 Merge pull request #1236 from siliceum/fix/frame-image-race-condition
Fix frame image race condition + refactor
2025-12-18 16:36:41 +01:00
Bartosz Taudul
9ced780715 Merge pull request #1235 from alexandergunnarson/master
A few minor Windows-specific fixes
2025-12-18 16:34:18 +01:00
Clément Grégoire
0eb9f4acb6 Fix frame image race condition + refactor
- In the connection state, retrieve the FrameImage while owning the data lock.
- Use actual image data pointer as caching key instead of the address of ImageCache which may change during executation (unstable).
- Fixes scale Messages image tooltip scale.
- Free the connection image
2025-12-18 15:44:58 +01:00
Alex Gunnarson
921d426488 Add conditional compilation option for MSVC 2025-12-17 15:26:58 -07:00
Alex Gunnarson
90bc94f237 Use builtins before MSVC intrinsics 2025-12-17 15:24:04 -07:00
Alex Gunnarson
dffa18378b Update IMAGEHLP_LINE to IMAGEHLP_LINE64
OfflineSymbolResolverDbgHelper.cpp uses IMAGEHLP_LINE but
SymGetLineFromAddr64 expects IMAGEHLP_LINE64. On 64-bit Windows these are typedef'd to the same thing, but on 32-bit they're different.
2025-12-17 15:19:00 -07:00
Bartosz Taudul
8b2019830a Merge pull request #1234 from siliceum/fix/etw-vsync
VSyncDPC events do not have the Keyword::DxgKrnlPresent bit set, so using it as MatchAllKeyword excluded it
2025-12-17 18:07:42 +01:00
Bartosz Taudul
2c19b82d72 Merge pull request #1233 from slomp/slomp/etw-happiness
Ensure all ETW StackWalk requests are satisfied
2025-12-17 18:07:26 +01:00
Clément Grégoire
d59e6cdfad VSyncDPC events do not have the Keyword::DxgKrnlPresent bit set, so using it as MatchAllKeyword excluded it 2025-12-17 17:45:52 +01:00
Marcos Slomp
4a6c75d8f8 ensure all stackwalk requests are satisfied 2025-12-17 08:03:34 -08:00
Bartosz Taudul
3ac8242d72 Merge pull request #1227 from WangFengtu1996/master
fixbug build cuda demo error
2025-12-17 16:43:27 +01:00
Fengtu Wang
4745db1553 Fix include statement for Tracy.hpp 2025-12-17 09:47:19 +08:00
Bartosz Taudul
3258599899 Merge pull request #1229 from slomp/slomp/etw-error-check-patch
ETW initialization: more explicit error check
2025-12-17 00:26:00 +01:00
Marcos Slomp
db745611c4 more explicit error check 2025-12-16 13:38:42 -08:00
Bartosz Taudul
1977beafe6 Merge pull request #1228 from siliceum/fix/test-memory-free
Fix unknown allocation message in debug due to alloc name litteral not pointing to the same location
2025-12-16 20:19:19 +01:00
Clément Grégoire
16558f2915 Fix unknown allocation message in debug due to alloc name litteral not pointing to the same location 2025-12-16 19:49:08 +01:00
Bartosz Taudul
7976e6ab0b Merge pull request #1213 from slomp/slomp/etw-refactor
Refactoring ETW kernel session
2025-12-16 18:59:56 +01:00
Marcos Slomp
2403438bd9 error flow control for VSync tracing 2025-12-16 09:11:11 -08:00
Marcos Slomp
bb3b5b6a4f reuse StopSession 2025-12-16 09:10:19 -08:00
Fengtu Wang
d2ffc9b9c6 fixbug build cuda demo error
1. fix bug build error can not find head file `#include <tracy/Tracy.hpp>`
2.  when not enable TRACY_ENABLE macro, build error  can not find  `tracy::CUDACtx` type
2025-12-16 18:32:10 +08:00
Marcos Slomp
a0092a793a abandoning the private kernel session for now 2025-12-15 16:21:42 -08:00
Marcos Slomp
c0ac36918a adding interfaces for singleton kernel logger session, and regular user sessions 2025-12-15 16:20:57 -08:00
Marcos Slomp
22d2b7407f emit ETW errors in english 2025-12-15 16:19:45 -08:00
Bartosz Taudul
0e3b3c57fc Merge pull request #1223 from siliceum/fix/fix-example-alloc-tracking
Test: Fix unknown allocation message in debug due to arena name litteral not pointing to the same location
2025-12-12 16:55:31 +01:00
Clément Grégoire
9c66d27777 Test: Fix unknown allocation message in debug due to arena name litteral not pointing to the same location 2025-12-12 16:40:14 +01:00
Bartosz Taudul
a7c6b7f02a Merge pull request #1221 from martymichal/wip/martymichal/fix-atomic-thread-init
public/client: Correctly initialize atomic thread reference
2025-12-12 12:21:34 +01:00
Bartosz Taudul
f1efafe825 Do not show external frames in DrawCallstackCalls(). 2025-12-12 01:23:36 +01:00
Bartosz Taudul
4fe1e00696 IsFrameExternal() can be const. 2025-12-12 01:23:19 +01:00
Bartosz Taudul
49ab593247 Change DrawCallstackCalls() limit logic. 2025-12-12 01:16:14 +01:00
Bartosz Taudul
05cceee0df Release 0.13.1. 2025-12-11 23:46:02 +01:00
Marcos Slomp
cc7790af04 add check to determine if provider has already been enabled by other sessions 2025-12-10 13:50:28 -08:00
Marcos Slomp
aaa695611b code formatting 2025-12-10 13:42:43 -08:00
Marcos Slomp
1be738ba10 expanding Tracy macros 2025-12-08 11:30:03 -08:00
Marcos Slomp
86a6b9b671 add admin check (and don't log it if it fails). 2025-12-08 08:40:26 -08:00
Ondřej Míchal
d79b6d040e public/client: Correctly initialize atomic thread reference
Atomic variables need to be initialize with direct-initialization
instead of copy-initialization lest the compilation fails complaining
about missing constructor for the atomic type.
2025-12-08 15:06:26 +02:00
Marcos Slomp
04c32562a0 adressing review comments 2025-12-07 15:51:07 -08:00
Bartosz Taudul
16bac5f807 Merge pull request #1220 from Lgt2x/imgui-x11
Link imgui against X11 libs
2025-12-06 01:23:47 +01:00
Louis Gombert
92ca07bb31 Link imgui against X11 libs
Imgui-docking >=v1.92.3 GLFW back-end requires linking against x11 libraries. This solves link failures when building tracy with the LEGACY option turned on.
2025-12-05 23:49:16 +01:00
Marcos Slomp
d363ddde2a missing events 2025-12-05 12:46:27 -08:00
Marcos Slomp
7b5de9e2b9 relocating ETW events (structs), and adding checks and comments 2025-12-05 12:03:57 -08:00
Marcos Slomp
16724b39c5 handle ProcessTrace pending (draining/flushing) condition 2025-12-05 09:49:11 -08:00
Bartosz Taudul
10500ed1f0 Merge pull request #1218 from mtreglia-gpsw/libcurl-fixed-version
Required lib-curl version to 8.17.0 in vendor.cmake pkg-config
2025-12-05 11:14:24 +01:00
Marco Treglia
951fc1b071 required pkg-config lib-curl v7.87.0 in the profiler
Resolving compiling issue when building with previous version of lib-curl.

If locally is present an older version of lib-curl the profiler build fails with:

```
   29 |     curl_easy_setopt( curl, CURLOPT_CA_CACHE_TIMEOUT, 604800L );
      |                             ^~~~~~~~~~~~~~~~~~~~~~~~
      |                             CURLOPT_DNS_CACHE_TIMEOUT
include/curl/curl.h:3109:68: note: expanded from macro 'curl_easy_setopt'
 3109 | #define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param)
      |                                                                    ^
include/curl/curl.h:1398:11: note: 'CURLOPT_DNS_CACHE_TIMEOUT' declared here
 1398 |   CURLOPT(CURLOPT_DNS_CACHE_TIMEOUT, CURLOPTTYPE_LONG, 92),
      |           ^
tracy/profiler/src/profiler/TracyLlmApi.cpp:144:46: error: use of undeclared identifier 'CURL_WRITEFUNC_ERROR'; did you mean 'CURLE_WRITE_ERROR'?
  144 |             if( !v.callback( json ) ) return CURL_WRITEFUNC_ERROR;
      |                                              ^~~~~~~~~~~~~~~~~~~~
      |                                              CURLE_WRITE_ERROR
include/curl/curl.h:524:3: note: 'CURLE_WRITE_ERROR' declared here
  524 |   CURLE_WRITE_ERROR,             /* 23 */
      |   ^
2 errors generated.
```

Both CURLOPT_CA_CACHE_TIMEOUT and CURL_WRITEFUNC_ERROR were added in
https://curl.se/ch/7.87.0.html

Now checking the version will avoid such issues:

-- Checking for module 'libcurl>=7.87.0'
--   Package dependency requirement 'libcurl >= 7.87.0' could not be satisfied.
Package 'libcurl' has version '7.84.0', required version is '>= 7.87.0'
-- CPM: Adding package libcurl@ (curl-8_17_0 to ...)
2025-12-05 10:51:29 +01:00
Marcos Slomp
9bb2be27cf details 2025-12-03 14:55:08 -08:00
Marcos Slomp
f0b8658346 splitting event consumer 2025-12-03 14:55:08 -08:00
Marcos Slomp
f6f9ec49d8 comments about the choice of default arguments 2025-12-03 14:55:08 -08:00
Marcos Slomp
bca011966d code formatting 2025-12-03 14:55:08 -08:00
Marcos Slomp
e5ca27966e ASCII 2025-12-03 14:55:08 -08:00
Marcos Slomp
d1f63dbca8 notify that events have been lost 2025-12-03 14:55:08 -08:00
Marcos Slomp
95658d532e isolating error actions 2025-12-03 14:55:08 -08:00
Marcos Slomp
f6965c62a9 reminder 2025-12-03 14:55:07 -08:00
Marcos Slomp
0270177a85 typo 2025-12-03 14:55:07 -08:00
Marcos Slomp
16e2f9f3bb Using ASCII version of the ETW API 2025-12-03 14:55:07 -08:00
Marcos Slomp
0adb0dbc57 refactoring ETW kernel session 2025-12-03 14:55:07 -08:00
Bartosz Taudul
886a0abec9 Merge pull request #1215 from slomp/slomp/worker-thread-race
Fixed race condition around `s_sysTraceThread`
2025-12-03 22:43:42 +01:00
Marcos Slomp
7fa30d08b5 clarification 2025-12-03 12:41:44 -08:00
Marcos Slomp
874d65b036 code formatting 2025-12-03 10:15:19 -08:00
Marcos Slomp
c44beaac28 fixed race condition around s_sysTraceThread 2025-12-02 16:19:20 -08:00
Bartosz Taudul
52bfac4243 Merge pull request #1214 from tmcdonell/feat/ignore-memory-faults
feat: Add build option to ignore memory free faults
2025-12-02 17:32:06 +01:00
Trevor L. McDonell
d1b0406801 Add option to ignore memory free faults
This replaces the IsApple flag, which was previously only used for this purpose.
2025-12-02 16:16:50 +01:00
Bartosz Taudul
29e8bbbbb2 Add user manual viewer. 2025-12-01 00:29:42 +01:00
Bartosz Taudul
6489874327 Extract links from manual section titles. 2025-11-30 22:05:20 +01:00
Bartosz Taudul
8c8cb8899f Store manual chunk level. 2025-11-30 21:54:19 +01:00
Bartosz Taudul
eec5444d84 Fix invalid chapter names for unnumbered manual sections. 2025-11-30 02:39:16 +01:00
Bartosz Taudul
154712bc81 Keep user manual chunks in a separate object.
This makes the user manual available outside of the LLM context.

The code is also more readable, as splitting the manual into sections and
splitting section content into chunks fit for embeddings is now separated.
A bug has been fixed, where the above splits were mixed up for the last
manual section, producing invalid data.

The unembedded manual contents are no longer held in the memory. The only
use case for this was to calculate the manual contents hash. The hash is
now precalculated and cached.
2025-11-29 20:16:00 +01:00
Bartosz Taudul
b74cac005d Retrieve manual chunk only once. 2025-11-29 19:56:07 +01:00
Bartosz Taudul
9aa78b224c Bump imgui to 1.92.5-docking. 2025-11-29 17:40:43 +01:00
Bartosz Taudul
3ddb7f6fd3 Merge pull request #1209 from ruifig/truncated_mean
Added the --truncated_mean parameter to csvexport
2025-11-26 21:03:08 +01:00
Rui Figueira
f6a6947987 Added the --truncated_mean paramter to csvexport 2025-11-26 16:11:35 +00:00
Bartosz Taudul
2acf93ac68 Merge pull request #1208 from foxtran/fix/Apple-15
Fix build for AppleClang 15
2025-11-26 15:14:21 +01:00
Igor S. Gerasimov
ade4182214 Tracy can not be compiled for too old target 2025-11-26 14:14:08 +01:00
Igor S. Gerasimov
de3cca3b97 Construct full type: std::vector<tracy::TracyLlmTools::ManualChunk>::emplace_back<std::string> is not available 2025-11-26 13:34:17 +01:00
Igor S. Gerasimov
e612c2674d Use std::string instead of std::format: Apple Clang 15 does not support it 2025-11-26 13:32:02 +01:00
Bartosz Taudul
be23d9354a Handle Lost_Event in Vsync callback on Windows. 2025-11-22 15:39:52 +01:00
Bartosz Taudul
a11c3d4236 Merge pull request #1199 from deralmas/fix-error-suppression-for-real
Fix error suppression macro
2025-11-15 22:27:41 +01:00
Dery Almas
e1110d6c58 Fix error suppression macro
My previous fix triggered another issue: apparently at least GCC expects
the `_Pragma` operator to be placed in its own statement (after a
semicolon). The current macro simply dumped the expression and the
_Pragma together, triggering an error. Putting a semicolon after `Expr`
fixes the issue (actually double-checked after a `git clean -fdx`),
although slightly changing the API (the semicolon after the wrapped
macros is now optional).
2025-11-15 21:38:08 +01:00
Bartosz Taudul
36d3f1e0ab Merge pull request #1198 from deralmas/fix-error-suppression
Fix shadow error suppression on GCC
2025-11-15 20:25:36 +01:00
Dery Almas
458d9ee89e Fix shadow error suppression on GCC
It looks like the actual macro defined by GCC is `__GNUC__`.

From my testing, `__GNU__` does not seem to be defined neither on my
musl machine nor a Fedora Linux VM. I have no idea if it's a typo or set
by specific libraries, but testing for `__GNUC__` actually suppresses
shadowing errors on my end.
2025-11-15 20:07:11 +01:00
Bartosz Taudul
f79033efd0 Bump curl to 8.17.0. 2025-11-14 17:07:32 +01:00
Bartosz Taudul
a257ccc3d0 Bump usearch to 2.21.3. 2025-11-14 17:05:56 +01:00
Bartosz Taudul
a1ab2fe91e Bump ppqsort to 1.0.6. 2025-11-14 17:00:29 +01:00
Bartosz Taudul
879ddf881c Bump imgui to 1.92.4-docking. 2025-11-14 16:59:14 +01:00
Bartosz Taudul
226fa7eee5 Bump freetype to 2.14.1. 2025-11-14 16:53:41 +01:00
Bartosz Taudul
75e3073b2a Bump capstone to 6.0.0-Alpha5. 2025-11-14 16:51:58 +01:00
Bartosz Taudul
5f4cccaa00 Use proper API to read /proc/mounts. 2025-11-13 19:40:28 +01:00
Bartosz Taudul
d70c7fb4c3 Merge pull request #1197 from nagisa/fix-debuginfod-signature
fix: GetDebugInfoDescriptor signature
2025-11-13 18:31:01 +01:00
Simonas Kazlauskas
10b5f0d878 fix: GetDebugInfoDescriptor signature 2025-11-13 19:19:52 +02:00
Bartosz Taudul
89f68babd2 Android user name may be longer than _POSIX_LOGIN_NAME_MAX. 2025-11-13 12:28:57 +01:00
Bartosz Taudul
0a64c7217f Merge pull request #1194 from ZeWaka/zewaka/fix-cpuid-parsing
fix CPUID parsing in TraceInfo
2025-11-13 12:24:52 +01:00
ZeWaka
e38ab2260d fix CPUID parsing in TraceInfo
the extended model was 4 bytes too low, as well as the extended family

the extended family was also not properly masked and the reserved space bled into it

fixes #1193
2025-11-13 01:15:45 -08:00
Bartosz Taudul
e6b9ea4609 Release 0.13.0. 2025-11-11 16:31:54 +01:00
Bartosz Taudul
0cc8e29eb1 Fix copy pasta. 2025-11-06 12:29:25 +01:00
Bartosz Taudul
9a27779d56 TRACY_CALLSTACK is not boolean. 2025-11-03 16:31:16 +01:00
Bartosz Taudul
d413e2bb51 Merge pull request #1186 from KovalevDima/denerate-pc-for-tracy
Generate pkgconf file for tracy downstream users
2025-11-02 18:43:00 +01:00
KovalevDima
da5547691a Generate pkgconf file for tracy 2025-11-02 20:08:03 +03:00
Bartosz Taudul
d7e1923a68 Fix nullptr deref. 2025-10-27 22:03:58 +01:00
Bartosz Taudul
b762dc2a82 Retrieve tracefs mount path. 2025-10-25 21:06:37 +02:00
Bartosz Taudul
3eda01d55f Merge pull request #1181 from mmcgill/1150-defer-gpu-ctx-events-in-c-serial-api
Defer GPU context events in serial C API
2025-10-25 16:42:59 +02:00
Matt McGill
491445343f Defer GPU context events in serial C API
Without this, the profiler crashes due to an assert
violation when connecting to a client built with
TRACY_ON_DEMAND that uses these C API calls.
2025-10-24 18:52:36 -04:00
Bartosz Taudul
6e3acecf54 Proper rounding for window size with fractional scaling.
Co-authored-by: Ivan Molodetskikh <yalterz@gmail.com>
2025-10-24 22:09:38 +02:00
Bartosz Taudul
7b8d868bbd Merge pull request #1120 from siliceum/refactor/unify-module-caches
Unify module caches
2025-10-24 15:44:50 +02:00
Clément Grégoire
8ccc76c66b Use CopyStringFast in FormatImageName 2025-10-24 13:10:23 +02:00
Clément Grégoire
fe516e3596 IsKernelAddress helper 2025-10-24 13:10:23 +02:00
Clément Grégoire
2bdefc2aa3 Move drivers and modules caching to their own functions 2025-10-24 13:10:23 +02:00
Clément Grégoire
903cde50d9 Replace windows caches with ImageCache
- Introduce both s_imageCache and s_krnlCache on all platforms, even if unused (will be reused later to unify platforms handling)
- This means that what userland images that used to be unsorted are now sorted
2025-10-24 13:10:23 +02:00
Clément Grégoire
e1e9fb680d Rename TRACY_USE_IMAGE_CACHE to TRACY_HAS_DL_ITERATE_PHDR_TO_REFRESH_IMAGE_CACHE
Windows is already using a cache, and the only platforms that won't have one for now are those without dl_iterate_phdr.
2025-10-24 13:10:23 +02:00
Clément Grégoire
3b5b32d307 Replace hardcoded string duplication by CopyStringFast
This can be CopyStringFast since we allocated the cache on the same thread.
2025-10-24 13:10:22 +02:00
Clément Grégoire
32f94a05cb Support adding new entries and keeping the image cache sorted
Image cache will remain potentially unsorted until first access or `Sort` is called explicitely.
2025-10-24 12:54:35 +02:00
Clément Grégoire
0b814a2532 Split ImageCache to seperate platform specific so that it can be used on other platforms 2025-10-24 12:50:27 +02:00
Clément Grégoire
aa68c31780 Add path to ImageEntry in prevision of replacing KernelDriver use + add DestroyImageEntry for ImageEntry cleanup 2025-10-24 12:50:26 +02:00
Bartosz Taudul
32cc0e5121 Take scale into account when creating window. 2025-10-23 19:30:26 +02:00
Bartosz Taudul
7428defab6 Don't attach wayland surface before acking configure. 2025-10-21 22:55:19 +02:00
Bartosz Taudul
30267de474 Make sure symbols thread has time to enter into disconnected condition. 2025-10-21 20:42:44 +02:00
Bartosz Taudul
22dc5b1ca7 Merge pull request #1176 from redthing1/pr/fix/macos-dock-icon
fix window icon/dock integration with objc on macos
2025-10-17 11:30:32 +02:00
redthing1
2625468615 remove (void) unused markers 2025-10-16 20:22:17 -07:00
redthing1
9580ad46c3 fix window icon/dock integration with objc on macos 2025-10-16 14:00:18 -07:00
Clément Grégoire
385f72f9dc Rename ImageCache::Contains to ContainsImage
The name was a bit misleading as it could be mistaken to mean "The cache contains the address" and not as "has an image with this start address". ie: that it could be mistaken to do GetImageForAddress( startAddress ) != nullptr.
2025-10-11 14:13:33 +02:00
Clément Grégoire
12026dae5b Make ImageEntry m_startAddress/m_endAddress uint64_t as it will later be used in server, and thus not pointing to current process memory 2025-10-11 14:10:18 +02:00
Clément Grégoire
9665f7ac42 Move ImageEntry to header in prevision of sharing it with other CPP files in the future 2025-10-11 13:52:03 +02:00
Bartosz Taudul
027bc04279 Merge pull request #1168 from siliceum/fix/unintialized-pending-counts
Fix uninitialized Worker::m_pending* loaded traces.
2025-10-08 12:50:49 +02:00
Clément Grégoire
255f465a8f Fix uninitialized Worker::m_pending* loaded traces.
This was causing issues in the Infos -> Trace Statistics window as `GetCallstackFrameCount` uses `m_pendingCallstackFrames`. Just in case, init those all those variables where declared instead of constructor.
2025-10-08 07:47:51 +02:00
Bartosz Taudul
b6191ceddb Merge pull request #1160 from Voultapher/suppress-variable-shadowing-warnings
Suppress variable shadowing warnings
2025-10-07 19:23:41 +02:00
Lukas Bergdoll
5002c045e2 Make variable shadowing warning suppression optional 2025-10-03 11:57:18 +02:00
Bartosz Taudul
863bcc4635 Merge pull request #1161 from siliceum/doc/gpu-zone-and-ondemand
Document a classic mistake with Tracy's C GPU Zones API and `TRACY_ON_DEMAND`
2025-09-30 17:36:09 +02:00
Clément Grégoire
f5b3711163 Document a classic mistake with Tracy's C GPU Zones API and TRACY_ON_DEMAND 2025-09-30 15:08:42 +02:00
Lukas Bergdoll
abd7c4f317 Suppress variable shadowing warnings
This disables the warnings for MSVC, GCC and Clang in the ZoneScopedXX
macros.

The warnings produced are both a false positive since they didn't find a
bug *and* they don't happen in user written code, so the user couldn't
even do much about it. The previous workaround of using ZoneNamedXXX is
a poor solution since the Zone(Text|Name|etc.) macros all rely on the
`___tracy_scoped_zone` name.
2025-09-29 18:58:22 +02:00
Bartosz Taudul
0a5aa506b6 Update markdown manual. 2025-09-16 22:34:16 +02:00
Bartosz Taudul
a52a2db95d Merge pull request #1148 from siliceum/bugfix/cropper-display-issues
Fix#1147: Cropper now displays properly when docking windows
2025-09-11 18:44:36 +02:00
Bartosz Taudul
f998e3e2a9 Merge pull request #1151 from dpelle/make-ZoneNameF-less-error-prone
Make ZoneNameF() less error-prone by checking format against args
2025-09-11 12:30:03 +02:00
Bartosz Taudul
5cf408fc10 Cosmetics. 2025-09-11 00:57:22 +02:00
Bartosz Taudul
dcc46d2a72 Merge pull request #1149 from anderswk-ioi/master
Fix crash due to freeing elements of m_serialDequeue twice.
2025-09-11 00:56:50 +02:00
Dominique Pelle
5f36f3d2ec Make ZoneNameF() less error-prone by checking format against args
`ZoneNameF(fmt, ...)` was error-prone: if the format is inconsistent
with arguments, the code compiled fine without errors or warnings.
Use gcc/clang `__attribute__((format(printf, fmt_idx, arg_idx)))`
function attribute, so that `ZoneNameF(fmt, ...)` can now check
at compilation time the consistency between the format and the
arguments.

See https://gcc.gnu.org/onlinedocs/gcc-3.1/gcc/Function-Attributes.html
2025-09-10 20:26:57 +02:00
Anders Wang Kristensen
355a11f47f Missing initialization of dequeueStatus 2025-09-10 14:43:28 +02:00
Anders Wang Kristensen
f21f8d6ad2 Fix crash due to freeing elements of m_serialDequeue twice.
In Profiler::DequeueSerial if AppendData fails part way through m_serialDequeue then the elements could be freed again in Profiler::ClearSerial, which leads to memory corruption in rpmalloc.
2025-09-10 12:56:47 +02:00
Clément Grégoire
4be2e88292 Rework the way the cropper computes its sizes and position
- No long assumes timelines are on the left of the window
- Derive circle size from cropper width
2025-09-09 16:15:36 +02:00
Clément Grégoire
d61e4aee6c Fix cropper line position and draw order
No longer using the `ForegroundDrawList` by simply moving draw after zones.
2025-09-09 16:13:04 +02:00
Clément Grégoire
2396733f89 Fix timeline cropper triggered on hover of other windows 2025-09-09 14:29:50 +02:00
Bartosz Taudul
6e214cab0a Merge pull request #1146 from whouishere/fix-non-glibc-stat64
Fix usage of stat64 on non-glibc Linux
2025-09-05 16:50:15 +02:00
whouishere
a755cfab78 Fix usage of stat64 on non-glibc Linux 2025-09-05 10:22:02 -03:00
Bartosz Taudul
981717f3ef Workaround libwayland regression.
ddd348da7e
2025-08-25 17:08:21 +02:00
Bartosz Taudul
67ba5b7727 Fix possible crash. 2025-08-23 21:22:32 +02:00
Bartosz Taudul
69836f3166 Merge pull request #1108 from siliceum/feature/thread-cropping
Allow to limit zone depth
2025-08-22 18:12:14 +02:00
Bartosz Taudul
47d0654bc9 Merge pull request #1140 from mcourteaux/config-ghostzones
Configuration of defaults.
2025-08-22 18:07:32 +02:00
Martijn Courteaux
62e062ee82 Fix highlight on the asteriks label. 2025-08-22 16:08:23 +02:00
Martijn Courteaux
fbcd3c1ae2 Make markers subtle, and only clear when you hover the save-defaults button. 2025-08-22 13:05:21 +02:00
Clément Grégoire
a0ab47efad Fix lambda indent 2025-08-22 10:54:44 +02:00
Martijn Courteaux
ae523c9bbf Explain that you can also reset the values by deleting the config file. 2025-08-21 21:15:36 +02:00
Martijn Courteaux
278251f483 I always forget the manual. 2025-08-21 18:03:06 +02:00
Martijn Courteaux
039ea797fc Improve wording. 2025-08-21 17:58:00 +02:00
Martijn Courteaux
8e72e2bb78 Default markers * to indicate which options are saved in the defaults. 2025-08-20 16:26:21 +02:00
Martijn Courteaux
ba178ce3d3 Add more Timeline options to the defaults. 2025-08-20 15:46:24 +02:00
Martijn Courteaux
577e7a3074 feat(config): Button to save ViewData options to the defaults in TracyConfig. 2025-08-20 15:32:04 +02:00
Martijn Courteaux
ebc31f25e3 feat(config): Add default value for ghostZones. 2025-08-20 14:46:03 +02:00
Bartosz Taudul
88a6378fff Merge pull request #1137 from mjopenglsdl/fix-on-demand
Add connection check when TRACY_ON_DEMAND for EnterFiber and LeaveFiber
2025-08-15 17:21:38 +02:00
Minjie
c545b34f68 Add connection check when TRACY_ON_DEMAND for EnterFiber and LeaveFiber 2025-08-15 22:36:45 +08:00
Bartosz Taudul
650541f280 Merge pull request #1136 from moritz-h/python-docs
Update Python docs
2025-08-14 19:39:01 +02:00
Moritz Heinemann
18e75668a9 Update markdown manual. 2025-08-14 19:36:04 +02:00
Moritz Heinemann
a8e60df334 Update Python docs 2025-08-14 19:28:38 +02:00
Bartosz Taudul
8bea64a55c Merge pull request #1134 from moritz-h/python-package
Refactor Python bindings build
2025-08-13 16:24:46 +02:00
Clément Grégoire
ba5a4b7ad1 Limit cropper display zone to window and only take margin into account when active, to avoid flickering when hovering 2025-08-12 18:07:24 +02:00
Clément Grégoire
11e3295275 Implement margin for text only. Unify text drawing for zone (als fixing missing clamp for the missing frame case) 2025-08-12 18:07:22 +02:00
Moritz Heinemann
0b57a37ebb Refactor python build system 2025-08-12 18:03:28 +02:00
Bartosz Taudul
0721561c54 Merge pull request #1124 from AnyOldName3/config-specific-lib-dir
Use config-specific lib directory so files don't overwrite each other
2025-08-06 17:30:03 +02:00
Bartosz Taudul
680f12463d Merge pull request #1130 from PewPewCrit/libbacktrace-macosSequoia-fix
Support for new DWARF sections used in macOS Sequoia
2025-08-04 13:25:01 +02:00
PewPewCrit
11c9e3fa35 libbacktrace: recognize new Mach-O DWARF sections
Reference: libbacktrace@d48f84034ce3e53e501d10593710d025cb1121db
2025-08-04 14:17:18 +03:00
Bartosz Taudul
c168b308c7 Merge pull request #1129 from alariq/docs-fix-1128
manual upate: OpenCL macro name fix
2025-08-04 11:25:07 +02:00
sebi
5ee82874c6 manual: OpenCL macro name fix 2025-08-04 10:17:30 +03:00
AnyOldName3
0da827ba34 Don't use separate directory for Release library 2025-08-03 14:46:13 +01:00
Bartosz Taudul
8e388d6d4e Merge pull request #1126 from slomp/slomp/sampling-toggle
Option to manually control sampling profiling
2025-08-02 16:12:34 +02:00
Marcos Slomp
5864350912 removed duplicated extern "C" 2025-08-02 06:48:00 -07:00
Marcos Slomp
9b84b527a6 adding manual control over sampling profiling 2025-08-01 15:24:30 -07:00
Bartosz Taudul
1393278afd Merge pull request #1125 from slomp/slomp/external-names-win32
Speeding up ExternalName queries (on Windows)
2025-08-01 22:40:14 +02:00
Marcos Slomp
b4b5f46d7b speeding up ExternalName queries 2025-08-01 12:53:56 -07:00
Bartosz Taudul
3bff910a27 Merge pull request #1121 from siliceum/feature/faster-module-caching-windows
Add faster module caching fallback by using GetModuleHandleExA
2025-08-01 20:44:19 +02:00
Bartosz Taudul
93f88c20e3 Merge pull request #1116 from siliceum/bugfix/clipboard-button
Fix clipboard button and add code preview in Zone Info
2025-08-01 20:30:38 +02:00
AnyOldName3
e4fcc1fdea Use config-specific lib dir so files don't overwrite each other 2025-08-01 00:23:47 +01:00
Gabriel Bon
1f6531f46d Add faster module caching fallback by using GetModuleHandleExA 2025-07-31 15:06:15 +02:00
Bartosz Taudul
be7b116a65 Merge pull request #1118 from siliceum/refactor/libbacktrace-integration
Refactor libbacktrace usage with TRACY_USE_LIBBACKTRACE
2025-07-31 12:28:38 +02:00
Clément Grégoire
8c06fec09e Refactor libbacktrace usage with TRACY_USE_LIBBACKTRACE 2025-07-31 10:41:37 +02:00
Clément Grégoire
effb5fbed5 Allow to chhange clipboard button font + center-align based on previous font 2025-07-31 00:20:56 +02:00
Bartosz Taudul
23be6a0789 Split too long line. 2025-07-30 23:40:01 +02:00
Bartosz Taudul
9bb5f8ec64 Merge pull request #1117 from siliceum/bugfix/displaysamplesevenwithoutzones
If we have samples in view and they are displayed, timeline should be displayed even without zones
2025-07-30 23:35:54 +02:00
Bartosz Taudul
0a9f3acb53 Merge pull request #1113 from siliceum/refine-clang-format
Refine .clang-format
2025-07-30 20:39:50 +02:00
Clément Grégoire
3751dc88c3 If we have samples in view and they are displayed, timeline should be displayed even without zones 2025-07-30 17:17:40 +02:00
Antoine Mura
301298d6f7 Fix clipboard button and add code preview in Zone Info 2025-07-30 16:07:56 +02:00
Bartosz Taudul
bd3660ed9f Merge pull request #1115 from akoylasar/master
Add p99 and p99.9 stats
2025-07-30 13:08:16 +02:00
Fouad Valadbeigi
9e754e61bc Add p99 and p99.9 stats 2025-07-30 02:27:20 +02:00
Clément Grégoire
a4d73cf0b3 Refine .clang-format 2025-07-27 21:18:57 +02:00
Bartosz Taudul
9d3c02686f Merge pull request #1096 from siliceum/feature/condition-variable-main-thread
Add lock struct with condition variable to main thread
2025-07-27 12:16:48 +02:00
Clément Grégoire
5bf53c1eb7 Fix formatting issues 2025-07-27 11:11:21 +02:00
Antoine Mura
80126ed1e0 Add lock struct with condition variable to main thread 2025-07-27 11:05:45 +02:00
Clément Grégoire
d1bb306dae Fix last cropper handle click 2025-07-23 15:33:44 +02:00
Clément Grégoire
c6e1bd40cd Auto-hide cropper when not actively limiting zones in view or mouse isn't hovering it 2025-07-23 15:33:20 +02:00
Bartosz Taudul
6f3a023df8 Update markdown manual. 2025-07-23 00:57:26 +02:00
Clément Grégoire
6f0f26ebcc View::DrawThread now properly accounts for the additional margin caused by cropper 2025-07-22 22:07:53 +02:00
Clément Grégoire
9c3629ab28 Revert margin modifications 2025-07-22 22:02:47 +02:00
Clément Grégoire
479b714b4b Add zone depth limit documentation 2025-07-22 20:51:06 +02:00
Bartosz Taudul
840a74172e Update manual. 2025-07-22 20:40:58 +02:00
Bartosz Taudul
3c1c444a15 Unbreak loading traces from previous versions. 2025-07-22 20:18:55 +02:00
Clément Grégoire
ed569b20c2 Update colors to be more discrete 2025-07-22 20:04:40 +02:00
Clément Grégoire
ed6a6d1e92 Fix cropper positions and sizes. Display hint when cropped. Allow depth to be lower than limit. 2025-07-22 20:02:08 +02:00
Antoine Mura
f32d4e4b44 Adjust aligment 2025-07-22 16:37:53 +02:00
Bartosz Taudul
c03fdaec1e Merge pull request #1097 from erieaton-amd/rocprofv3-2
Collect dispatches and counter values with Rocprofv3
2025-07-22 13:33:15 +02:00
Antoine Mura
d18f08fb9e Add Thread Timeline Cropping 2025-07-22 09:22:38 +02:00
Eric Eaton
1639598d62 Update documentation
This provides some instructions and tips for the manual. Also:
* Made the calibration feature a CMake option
* Cleaned up some minor code issues
* Fixed an issue with the calibration
* Incremented patch number
2025-07-21 15:30:42 -07:00
Bartosz Taudul
dd4db35b05 Merge pull request #1106 from nyorain/master
Allow to access wrapped Lockable/SharedLockable object
2025-07-20 18:44:33 +02:00
nyorain
02295cbfeb Allow to access wrapped Lockable object 2025-07-20 18:26:22 +02:00
Bartosz Taudul
8512a1c925 Merge pull request #1099 from pkraif/master
Add GDK platform support
2025-07-19 14:07:50 +02:00
Bartosz Taudul
1949fd765c Merge pull request #1104 from siliceum/bugfix/embed-dependency
Fix embed dependency
2025-07-18 20:07:42 +02:00
Clément Grégoire
3f5d07ebd7 Fix embed dependency
add_custom_command DEPENDS can only see the output of other commands or targets names, not the targets installation through ExternalProject_Add.
Add the `embed` target (created by `ExternalProject_Add`) as a dependency for commands using the utility
2025-07-18 15:23:18 +02:00
Patrik Kraif
a642b84add Add missing TracyWinFamily header include 2025-07-18 10:10:02 +02:00
Bartosz Taudul
2f17e33851 Prevent duplicate callstack frame queries.
Callstack frames will now have nullptr as the value in the callstackFrameMap
map, as a way to signal that a query for given key is already pending.
Duplicate queries should no longer happen.

@slomp provided alternative implementation, which produced the following
results:

Queries made: 195,778
Duplicate queries skipped: 9,518,910

Co-authored-by: Marcos Slomp <slomp@adobe.com>
2025-07-18 01:16:46 +02:00
Bartosz Taudul
c704f909be Move duplication check into QueryCallstackFrame() to make things clear. 2025-07-18 01:15:16 +02:00
Bartosz Taudul
c4a6cf3456 Use contains() to check if map contains element. 2025-07-18 00:45:26 +02:00
Bartosz Taudul
f578d14553 Extract callstack frame query to a separate function. 2025-07-18 00:33:09 +02:00
Bartosz Taudul
38ff7a6697 Make sure count is right. 2025-07-18 00:24:23 +02:00
Bartosz Taudul
320eb67581 Assume callstackFrameMap can store null ptrs. 2025-07-18 00:23:43 +02:00
Bartosz Taudul
ea661d0765 Cosmetics. 2025-07-18 00:19:09 +02:00
Eric Eaton
9caa91f06f Move the annotations data to the GPU context 2025-07-16 16:02:54 -07:00
Patrik Kraif
dacd0fc63f Fix header guard to match the new file name 2025-07-16 12:55:22 +02:00
Patrik Kraif
4a3713cca8 Add support for GDK 2025-07-16 12:51:16 +02:00
Bartosz Taudul
382b41bcce Add example llama-swap configuration to the manual. 2025-07-15 14:32:49 +02:00
Bartosz Taudul
d9a1655f9a Add information about CPU dies to topology section in the manual. 2025-07-15 14:04:21 +02:00
Eric Eaton
21a34c5a38 Fix windows build error 2025-07-14 12:58:47 -07:00
Bartosz Taudul
825e60e1d5 Workaround json parsing problems.
The true issue is probably related to bad threading, but it needs to be
properly found.
2025-07-13 19:09:43 +02:00
Bartosz Taudul
24b43e9e0a Update manual. 2025-07-13 19:09:37 +02:00
Bartosz Taudul
0772f1f952 Add predefined queries for callstacks. 2025-07-13 19:09:17 +02:00
Bartosz Taudul
b44822899e Add wrapper for sending LLM queries to TracyView. 2025-07-13 18:52:20 +02:00
Bartosz Taudul
39c121ce20 Make AddMessage and QueueSendMessage public in TracyLlm. 2025-07-13 18:52:03 +02:00
Bartosz Taudul
64b61fee03 Extract function for getting callstack data as json. 2025-07-13 18:40:42 +02:00
Bartosz Taudul
adefaff0cc RasterizerDensity is obsolete now. 2025-07-13 12:49:23 +02:00
Bartosz Taudul
c7c20730cf Fix Worker name conflict. 2025-07-13 01:27:56 +02:00
Bartosz Taudul
3d00f3eda1 Disable LLM on emscripten. 2025-07-13 01:00:08 +02:00
Bartosz Taudul
d1e3d1abb5 Proper support for markdown header font sizes (including style changes). 2025-07-13 00:25:14 +02:00
Bartosz Taudul
9ee6af33a4 Format achievements intro message with markdown. 2025-07-12 23:54:49 +02:00
Bartosz Taudul
70d6d7e756 Fully externalize markdown printer. 2025-07-12 23:42:21 +02:00
Bartosz Taudul
75cfc67972 Add robot icon to default assist view. 2025-07-12 23:28:12 +02:00
Bartosz Taudul
3d183e2da1 Markdown renderer is not strictly an LLM functionality. 2025-07-12 23:26:55 +02:00
Bartosz Taudul
b12253e706 Update CPU data window column labels in the manual. 2025-07-12 20:28:08 +02:00
Bartosz Taudul
00bc533d4d Improve code block style. 2025-07-12 20:08:26 +02:00
Bartosz Taudul
f098102898 Parse source code blocks in markdown. 2025-07-12 20:04:58 +02:00
Bartosz Taudul
5833f0d734 Add SourceContents::Parse() with length argument. 2025-07-12 20:01:27 +02:00
Bartosz Taudul
d4094f45cc Replace all deprecated ImGui functionality. 2025-07-12 19:50:37 +02:00
Bartosz Taudul
78c284cd8f Remove font glyph ranges. 2025-07-12 18:42:08 +02:00
Bartosz Taudul
fdeb33c566 Bump usearch, curl. 2025-07-12 18:27:43 +02:00
Bartosz Taudul
89f246dc07 Bump emscripten SDK to 4.0.10. 2025-07-12 18:20:28 +02:00
Bartosz Taudul
b58388316a Fix emscripten build. 2025-07-12 18:19:56 +02:00
Bartosz Taudul
e77240a47d Workaround broken md4c CMake configuration. 2025-07-12 18:09:31 +02:00
Bartosz Taudul
4a25079996 Disable demo window in release build.
Workarounds ImGui issue 8796.
2025-07-12 17:43:53 +02:00
Bartosz Taudul
bd0591c4d5 Bump ImGui to 1.92.1-docking. 2025-07-12 17:08:13 +02:00
Bartosz Taudul
1dd4c2d670 Update ImGui to 1.92.0-docking. 2025-07-12 14:36:47 +02:00
Bartosz Taudul
d2d50d2cea Fix flame graph limit range button position. 2025-07-12 14:31:15 +02:00
Bartosz Taudul
d2db62ebc3 Change how icons are converted in markdown manual. 2025-07-12 14:25:29 +02:00
Bartosz Taudul
249673660e Remove mouse button images from markdown manual. 2025-07-12 13:41:05 +02:00
Bartosz Taudul
f6f2fa0a0a Fix font awesome icons in markdown manual. 2025-07-12 13:34:22 +02:00
Bartosz Taudul
1e1d9d9a84 Fix \menu, this time properly. 2025-07-12 12:35:37 +02:00
Bartosz Taudul
6058e6ede0 Hackfix section names in markdown manual. 2025-07-12 12:23:48 +02:00
Bartosz Taudul
31815fd45d Remove junk from links in markdown manual. 2025-07-12 11:58:19 +02:00
Bartosz Taudul
ee2ef5c455 Increase number of user manual search results. 2025-07-12 11:50:32 +02:00
Bartosz Taudul
0da4c7e320 Explicit search parameters. 2025-07-12 11:50:32 +02:00
Bartosz Taudul
87c1200c80 Add shell script for latex to markdown conversion. 2025-07-12 11:50:32 +02:00
Bartosz Taudul
c08364779a Update markdown manual. 2025-07-12 11:50:32 +02:00
Bartosz Taudul
55cf0139fd Don't crash on assert when a tool call is missing a parameter. 2025-07-12 11:50:31 +02:00
Bartosz Taudul
818d238f50 Update system prompt to use English names for UI elements. 2025-07-12 11:50:31 +02:00
Bartosz Taudul
d5b36ea7d0 Do not block UI thread when waiting for tokenization.
Erasing chat contens or regenerating assistant reply can still block.
2025-07-12 11:50:31 +02:00
Bartosz Taudul
c9cca586cc Add tokenization job. 2025-07-12 11:50:31 +02:00
Bartosz Taudul
37da8f923b Better handling of responding and stop states. 2025-07-12 11:50:31 +02:00
Bartosz Taudul
50d68f6bae Make current job visible. 2025-07-12 11:50:31 +02:00
Bartosz Taudul
a3b06851d8 The queue should be fifo. 2025-07-12 11:50:31 +02:00
Bartosz Taudul
7809e39cac Wrap adding LLM tasks in helper functions. 2025-07-12 11:50:31 +02:00
Bartosz Taudul
c518de7837 Handle empty think section, repeated think close tags. 2025-07-12 11:50:30 +02:00
Bartosz Taudul
d0c4e9bc3a Handle multiple tool calls by erroring out. 2025-07-12 11:50:30 +02:00
Bartosz Taudul
22281d04ab Update system prompt. 2025-07-12 11:50:30 +02:00
Bartosz Taudul
7ffd8310e6 Improve code tokenization estimation. 2025-07-12 11:50:30 +02:00
Bartosz Taudul
6c05079e7b Disable LLM settings when the model is responding. 2025-07-12 11:50:30 +02:00
Bartosz Taudul
4e8fb7870b Decrease context usage when removing chat content. 2025-07-12 11:50:30 +02:00
Bartosz Taudul
b54c4f7aa9 Get exact token counts when adding or removing messages. 2025-07-12 11:50:30 +02:00
Bartosz Taudul
b36b6a0aa2 Implement llama-swap tokenization request. 2025-07-12 11:50:30 +02:00
Bartosz Taudul
4969be344e Use exact tokens count when available in server response.
Note that this is not really exacy, as it includes system prompt reminder
and possibly other input data that is dynamically injected.
2025-07-12 11:50:29 +02:00
Bartosz Taudul
047fa3b98f Remove readability.js support.
The current method of web retrieval works well enough.
2025-07-12 11:50:29 +02:00
Bartosz Taudul
154c055fcb Update manual. 2025-07-12 11:50:29 +02:00
Bartosz Taudul
2e77045ff7 Rearrange LLM provider presets. 2025-07-12 11:50:29 +02:00
Bartosz Taudul
567cd562e4 Fix rendering complex markdown headers. 2025-07-12 11:50:29 +02:00
Bartosz Taudul
b84f1407d4 Ask for donations. 2025-07-12 11:50:29 +02:00
Bartosz Taudul
dee495cefc Add embedding prefixes required by the nomic-embed-text model. 2025-07-12 11:50:29 +02:00
Bartosz Taudul
c893954da7 Add missing switch case break. 2025-07-12 11:50:29 +02:00
Bartosz Taudul
7252c6b41e Add spacing before markdown headers. 2025-07-12 11:50:29 +02:00
Bartosz Taudul
0b9ea6f650 Refine system prompt. 2025-07-12 11:50:28 +02:00
Bartosz Taudul
fcfbd9810a Add md extension to system prompt files, to get coloring in editor. 2025-07-12 11:50:28 +02:00
Bartosz Taudul
55dc632b10 Handle HTTP errors. 2025-07-12 11:50:28 +02:00
Bartosz Taudul
20182e88cd Sort models list. 2025-07-12 11:50:28 +02:00
Bartosz Taudul
2f1cb512e6 Implement copying chat responses to the clipboard. 2025-07-12 11:50:28 +02:00
Bartosz Taudul
abef0d76b1 Update manual. 2025-07-12 11:50:28 +02:00
Bartosz Taudul
f9be40ae7c Update wording. 2025-07-12 11:50:28 +02:00
Bartosz Taudul
4f01a43920 Reload InputText buffer.
https://github.com/ocornut/imgui/issues/8709#issuecomment-2993482040
2025-07-12 11:50:28 +02:00
Bartosz Taudul
7a0a0a9749 Add option to regenerate LLM reply. 2025-07-12 11:50:27 +02:00
Bartosz Taudul
998ec7941f Clearly indicate that stop operation is in progress. 2025-07-12 11:50:27 +02:00
Bartosz Taudul
7ab657a0d5 Refine system prompt. 2025-07-12 11:50:27 +02:00
Bartosz Taudul
fc840c1d47 Implement attaching assembly loops to LLM chat. 2025-07-12 11:50:27 +02:00
Bartosz Taudul
39d624b969 Reinit connection on error. 2025-07-12 11:50:27 +02:00
Bartosz Taudul
21ddd99d55 Properly handle error output. 2025-07-12 11:50:27 +02:00
Bartosz Taudul
b51ed462f7 Handle response failure. 2025-07-12 11:50:27 +02:00
Bartosz Taudul
ca02df8ad5 Ignore spaces after <think> and <tool> tags. 2025-07-12 11:50:27 +02:00
Bartosz Taudul
91cfc2e5b8 Move jump range calculation to a separate function. 2025-07-12 11:50:26 +02:00
Bartosz Taudul
76fd44ea8a Add function for attaching data to LLM chat. 2025-07-12 11:50:26 +02:00
Bartosz Taudul
9b0bb7cfda Refine system prompt. 2025-07-12 11:50:26 +02:00
Bartosz Taudul
dabfa36913 Display attachment type. 2025-07-12 11:50:26 +02:00
Bartosz Taudul
5d653551b9 Add icon for each single attachment / error. 2025-07-12 11:50:26 +02:00
Bartosz Taudul
96a13f2a45 Move markdown logic to a separate file. 2025-07-12 11:50:26 +02:00
Bartosz Taudul
6419a01849 Refine wording. 2025-07-12 11:50:26 +02:00
Bartosz Taudul
1aa27c81ac Remove call stack text from system prompt. 2025-07-12 11:50:26 +02:00
Bartosz Taudul
f3c066cc69 More explicit local / network tool split. 2025-07-12 11:50:25 +02:00
Bartosz Taudul
b4692740aa Add source_file tool. 2025-07-12 11:50:25 +02:00
Bartosz Taudul
b2122e7d41 Move SplitLines to TracyUtility.cpp. 2025-07-12 11:50:25 +02:00
Bartosz Taudul
0b8f7344e6 Don't create intermediate string. 2025-07-12 11:50:25 +02:00
Bartosz Taudul
712fd3b58a Update system prompt. 2025-07-12 11:50:25 +02:00
Bartosz Taudul
5d7695cbce Allow attaching call stacks for the AI chat. 2025-07-12 11:50:25 +02:00
Bartosz Taudul
a09f1b2d15 Implement attachments in chat. 2025-07-12 11:50:25 +02:00
Bartosz Taudul
1e508f0b44 Implement removing chat messages. 2025-07-12 11:50:25 +02:00
Bartosz Taudul
8b2de04cd9 Chat message removal UI. 2025-07-12 11:50:25 +02:00
Bartosz Taudul
764348be79 Trim section title and newlines from manual sections. 2025-07-12 11:50:24 +02:00
Bartosz Taudul
80a10a9095 Better context delivery for manual sections. 2025-07-12 11:50:24 +02:00
Bartosz Taudul
ed1f64d001 Disable send button when there's no input. 2025-07-12 11:50:24 +02:00
Bartosz Taudul
1183364812 Add warning. 2025-07-12 11:50:24 +02:00
Bartosz Taudul
d67d37de8e Request verbose user manual search queries. 2025-07-12 11:50:24 +02:00
Bartosz Taudul
25c85ad853 No images (at least for now). 2025-07-12 11:50:24 +02:00
Bartosz Taudul
1f87cd3b17 Update tool use examples. 2025-07-12 11:50:24 +02:00
Bartosz Taudul
ebc25665bd Update markdown manual. 2025-07-12 11:50:24 +02:00
Bartosz Taudul
7ce42a7df8 Bump usearch to 2.17.11. 2025-07-12 11:50:23 +02:00
Bartosz Taudul
67d1c8b8b8 Small batch size. 2025-07-12 11:50:23 +02:00
Bartosz Taudul
7e0476a641 Fail when embeddings were not calculated. 2025-07-12 11:50:23 +02:00
Bartosz Taudul
2578a0c04a URL encode already handles spaces. 2025-07-12 11:50:23 +02:00
Bartosz Taudul
9c831471a3 Refine system prompt. 2025-07-12 11:50:23 +02:00
Bartosz Taudul
017e050f09 Reword user manual query description. 2025-07-12 11:50:23 +02:00
Bartosz Taudul
845933040d Perform tool calls with json. 2025-07-12 11:50:23 +02:00
Bartosz Taudul
1b24f60ac1 Group lines with no empty line separator between them together. 2025-07-12 11:50:23 +02:00
Bartosz Taudul
3ecac21db9 Filter out manual lines with no usable content. 2025-07-12 11:50:22 +02:00
Bartosz Taudul
c9d70b7f67 Remove ollama-specific image support. 2025-07-12 11:50:22 +02:00
Bartosz Taudul
c443f4fc64 Relax newline requirements around <think> and <tool> tags. 2025-07-12 11:50:22 +02:00
Bartosz Taudul
67419ee931 Don't force newline in injected <think> tag.
Fixes qwen3 models.
2025-07-12 11:50:22 +02:00
Bartosz Taudul
555966e1b1 Handle no embeddings response. 2025-07-12 11:50:22 +02:00
Bartosz Taudul
3504f485dd Add support for google search API. 2025-07-12 11:50:22 +02:00
Bartosz Taudul
43d94a3cc3 Crash fix. 2025-07-12 11:50:22 +02:00
Bartosz Taudul
6255b4c67c Move current time back to system prompt. 2025-07-12 11:50:22 +02:00
Bartosz Taudul
f04dcc7c42 Don't display model quantization when it's not known. 2025-07-12 11:50:22 +02:00
Bartosz Taudul
14cc545efd Get context size with llama-swap. 2025-07-12 11:50:21 +02:00
Bartosz Taudul
e2ba66cf04 Detect llama-swap, match embedding models by name. 2025-07-12 11:50:21 +02:00
Bartosz Taudul
c35a75f86c Fix crash when embedding model is no longer available after provider switch. 2025-07-12 11:50:21 +02:00
Bartosz Taudul
b9595add71 Do not repeatedly probe for LLM provider type. 2025-07-12 11:50:21 +02:00
Bartosz Taudul
a84e63d573 Remove cortex from list of predefined LLM servers. 2025-07-12 11:50:21 +02:00
Bartosz Taudul
08fd4aa182 Automatically load embeddings when already calculated. 2025-07-12 11:50:21 +02:00
Bartosz Taudul
e8b6cdb72b Rework embeddings handling.
Send embedding requests in batches. This shaves off ~4% of run time.

Save ready-to-use database instead of intermediate data that need to be
processed.
2025-07-12 11:50:21 +02:00
Bartosz Taudul
8259cd6aff Don't waste time calculating embeddings that will be ignored. 2025-07-12 11:50:21 +02:00
Bartosz Taudul
c641787ed1 Bump usearch to 2.17.9. 2025-07-12 11:50:20 +02:00
Bartosz Taudul
0db765a684 Indent list items text. 2025-07-12 11:50:20 +02:00
Bartosz Taudul
75c1735695 Fix word wrap when the first continued word requires line break. 2025-07-12 11:50:20 +02:00
Bartosz Taudul
ddc3d8884f Fix font ranges. 2025-07-12 11:50:20 +02:00
Bartosz Taudul
9e593ce61c Support hand pointer mouse cursor on Wayland. 2025-07-12 11:50:20 +02:00
Bartosz Taudul
5778c5ef9f Fix code block clashes. 2025-07-12 11:50:20 +02:00
Bartosz Taudul
fde94e10d4 Implement printing markdown. 2025-07-12 11:50:20 +02:00
Bartosz Taudul
5a6b51c245 Track hover status in PrintTextWrapped. 2025-07-12 11:50:20 +02:00
Bartosz Taudul
64ec3f6e3f Add spacing after an expanded think section. 2025-07-12 11:50:19 +02:00
Bartosz Taudul
b521064875 Add spacing between chat turns. 2025-07-12 11:50:19 +02:00
Bartosz Taudul
de9c90673e Do not copy strings. 2025-07-12 11:50:19 +02:00
Bartosz Taudul
295b597835 Load all characters from fonts.
It's not that much more. The majority of the font texture is font awesome.
The size of the font texture (2K x 4K) stays the same with this change.
2025-07-12 11:50:19 +02:00
Bartosz Taudul
5ccd05d2a5 Rework chat rendering. 2025-07-12 11:50:19 +02:00
Bartosz Taudul
33e55c32f7 Remove current time from system prompt.
It makes little sense to provide it, when it's already in the system
reminder.
2025-07-12 11:50:19 +02:00
Bartosz Taudul
735ef3b9b8 Use LLM tools through a pointer. 2025-07-12 11:50:19 +02:00
Bartosz Taudul
2ffae6c626 Don't repeat text. 2025-07-12 11:50:19 +02:00
Bartosz Taudul
ceb635d297 Rearrange order of predefined API providers. 2025-07-12 11:50:19 +02:00
Bartosz Taudul
cffc7abff7 Unify API urls. 2025-07-12 11:50:18 +02:00
Bartosz Taudul
31cd82f78d When managing context don't stop after first removal if quota is not met. 2025-07-12 11:50:18 +02:00
Bartosz Taudul
30c2f45c2c Disable tool calls in debug replies. 2025-07-12 11:50:18 +02:00
Bartosz Taudul
e0820587a5 Add md4c. 2025-07-12 11:50:18 +02:00
Bartosz Taudul
9c648232a8 Disable LLM integration on emscripten. 2025-07-12 11:50:18 +02:00
Bartosz Taudul
ec205fa854 Move embed utility to a separate project.
This has to be separate to build a host executable during cross-compilation
(e.g. on emscripten builds).
2025-07-12 11:50:18 +02:00
Bartosz Taudul
111f68052f No LLM libs on emscripten. 2025-07-12 11:50:18 +02:00
Bartosz Taudul
84d829454c Require translating tool output to user's language. 2025-07-12 11:50:18 +02:00
Bartosz Taudul
3d3fb0591d Add LLM debug mode. 2025-07-12 11:50:17 +02:00
Bartosz Taudul
e693a1923e Delta content may be null.
Compatibility with llama-server.
2025-07-12 11:50:17 +02:00
Bartosz Taudul
7cae20d572 Implement key repeat in BackendWayland. 2025-07-12 11:50:17 +02:00
Bartosz Taudul
8c697479c2 Cache calculated embeddings. 2025-07-12 11:50:17 +02:00
Bartosz Taudul
27a17eb4ff Calculate manual chunks in TracyLlmTools constructor. 2025-07-12 11:50:17 +02:00
Bartosz Taudul
f6f602da32 Add cache dir support. 2025-07-12 11:50:17 +02:00
Bartosz Taudul
5f9491264b Rename Tracy AI to Tracy Assist. 2025-07-12 11:50:17 +02:00
Bartosz Taudul
90334f8db2 Remove <think> usage from reminder, as it's now forced. 2025-07-12 11:50:17 +02:00
Bartosz Taudul
0fff110338 Improve system reminder mechanism.
Previously the reminder was prepended to each user message and each one did
persist in the chat history. This change injects the system reminder into
the assistant output, without storing it in the history.

The change also adds an initial <think> tag to each of the assistant replies
to force the thinking process.
2025-07-12 11:50:16 +02:00
Bartosz Taudul
fc095be081 Limit user manual search results to fit in context. 2025-07-12 11:50:16 +02:00
Bartosz Taudul
72ed1e2691 Remove non-existing function. 2025-07-12 11:50:16 +02:00
Bartosz Taudul
e6bbfbdcf0 Fix locks. 2025-07-12 11:50:16 +02:00
Bartosz Taudul
de4ea095e6 Fix typo. 2025-07-12 11:50:16 +02:00
Bartosz Taudul
b00d4e36a8 Fix glfw backend. 2025-07-12 11:50:16 +02:00
Bartosz Taudul
e9db22b175 Make the user manual queries verbose. 2025-07-12 11:50:16 +02:00
Bartosz Taudul
cadfa3f9fb Change user manual embeddings chunking strategy.
The source is now the markdown text, not latex. Each embedding is now
a single paragraph from the manual. The search now returns whole sections
from the manual matching the query.
2025-07-12 11:50:16 +02:00
Bartosz Taudul
2e598ee548 Add tracy manual converted to markdown.
The following command was used:

pandoc --wrap=none --reference-location=block --number-sections -s tracy.tex -o tracy.md

This should be a part of the build process, but that would require pandoc,
which is not something users may have installed.
2025-07-12 11:50:15 +02:00
Bartosz Taudul
35775c0ad9 Another place where line may not have contents. 2025-07-12 11:50:15 +02:00
Bartosz Taudul
c758ca9b87 Store chunk data as pointer + length. 2025-07-12 11:50:15 +02:00
Bartosz Taudul
a20c06b041 Line content may be null. 2025-07-12 11:50:15 +02:00
Bartosz Taudul
59eb0fc2b5 Detect embedding failure early on. 2025-07-12 11:50:15 +02:00
Bartosz Taudul
b4689fe88f Check for HTTP return codes in FetchWebPage(). 2025-07-12 11:50:15 +02:00
Bartosz Taudul
70ede04ede Allow setting user agent for tools. 2025-07-12 11:50:15 +02:00
Bartosz Taudul
d5b3de6b3a Fix aliasing of button names in options. 2025-07-12 11:50:15 +02:00
Bartosz Taudul
fb0d4f0d82 Make config accessible to all code without extern hacks. 2025-07-12 11:50:15 +02:00
Bartosz Taudul
736a2d3ba2 Indicate forgotten tool outputs in the chat window. 2025-07-12 11:50:14 +02:00
Bartosz Taudul
168ae92b8b Forget old tool replies when available context size runs out. 2025-07-12 11:50:14 +02:00
Bartosz Taudul
7a729e20f3 Do not copy messages to be sent.
Sending the message blocks user input, so chat contents will not change.
2025-07-12 11:50:14 +02:00
Bartosz Taudul
cfc78192da Use common functionality to add messages to chat. 2025-07-12 11:50:14 +02:00
Bartosz Taudul
c035e68770 Don't fail on invalid UTF-8. 2025-07-12 11:50:14 +02:00
Bartosz Taudul
f76c2ab427 Remove empty html tags. 2025-07-12 11:50:14 +02:00
Bartosz Taudul
f3be60e191 Refine tool use. 2025-07-12 11:50:14 +02:00
Bartosz Taudul
9738591d96 GetCurrentTime() can be const. 2025-07-12 11:50:14 +02:00
Bartosz Taudul
f3aceef051 More html cleanup. 2025-07-12 11:50:13 +02:00
Bartosz Taudul
f2ec04be3c Color-code context size meter. 2025-07-12 11:50:13 +02:00
Bartosz Taudul
d52e0e9a19 Cleanup html. 2025-07-12 11:50:13 +02:00
Bartosz Taudul
bbf551e7d3 Ignore tidy errors. 2025-07-12 11:50:13 +02:00
Bartosz Taudul
d1c67a93c6 Make readability.js optional. 2025-07-12 11:50:13 +02:00
Bartosz Taudul
aa6d6c586e Another approach at getting web pages. 2025-07-12 11:50:13 +02:00
Bartosz Taudul
cead66cc3d Disable printing tidy warnings and errors. 2025-07-12 11:50:13 +02:00
Bartosz Taudul
d9f7772e9a Move parsing HTML to a separate function. 2025-07-12 11:50:13 +02:00
Bartosz Taudul
0a4c1c9a77 Make webpage caching optional. 2025-07-12 11:50:12 +02:00
Bartosz Taudul
b659d79ac1 Add progress bar to user manual embeddings processing. 2025-07-12 11:50:12 +02:00
Bartosz Taudul
1c9ef33e8c Add system prompt reinforcement. 2025-07-12 11:50:12 +02:00
Bartosz Taudul
a00d8c3fd5 Remove obsolete tools.json. 2025-07-12 11:50:12 +02:00
Bartosz Taudul
bddd705861 Do system prompt tag injection properly. 2025-07-12 11:50:12 +02:00
Bartosz Taudul
9d825e794b Refine system prompt. 2025-07-12 11:50:12 +02:00
Bartosz Taudul
bf9e4f6254 Update system prompt. 2025-07-12 11:50:12 +02:00
Bartosz Taudul
c5422e0264 Add user_manual tool. 2025-07-12 11:50:12 +02:00
Bartosz Taudul
0520d12b24 Reserve memory for embeddings. 2025-07-12 11:50:11 +02:00
Bartosz Taudul
96e03b079e Embeddings calls may need to be done on a separate connection.
The completion reply may be unfinished when the embeddings call is executed.
2025-07-12 11:50:11 +02:00
Bartosz Taudul
75e9e589b8 Make SetupCurl() work with any curl context. 2025-07-12 11:50:11 +02:00
Bartosz Taudul
f1d1e00659 Model may be unloaded after completion (by embeddings call). 2025-07-12 11:50:11 +02:00
Bartosz Taudul
da54eec537 Disable another stupid check. 2025-07-12 11:50:11 +02:00
Bartosz Taudul
338e029621 Fill in manual vector database. 2025-07-12 11:50:11 +02:00
Bartosz Taudul
e54f4d6a15 Add vector database. 2025-07-12 11:50:11 +02:00
Bartosz Taudul
e3db1eb7ee Probe embeddings vector length. 2025-07-12 11:50:11 +02:00
Bartosz Taudul
746f28e3c9 Add UI for building manual embeddings. 2025-07-12 11:50:10 +02:00
Bartosz Taudul
b4fe4c460c Calculation of manual embeddings. 2025-07-12 11:50:10 +02:00
Bartosz Taudul
89d65b52d9 Add API for getting embeddings vector. 2025-07-12 11:50:10 +02:00
Bartosz Taudul
932af50d3e Set headers for GET. 2025-07-12 11:50:10 +02:00
Bartosz Taudul
4301573d95 Embed manual contents. 2025-07-12 11:50:10 +02:00
Bartosz Taudul
85086c461b Separate selection of LLM and embeddings model. 2025-07-12 11:50:10 +02:00
Bartosz Taudul
ffe0047f8c Detect embeddings-capable models. 2025-07-12 11:50:10 +02:00
Bartosz Taudul
95d2aa9a22 Set content type in POST request. 2025-07-12 11:50:10 +02:00
Bartosz Taudul
931bc97787 Trimming tool response now properly handles UTF-8.
This is important to have, as otherwise json parser will fail.
2025-07-12 11:50:10 +02:00
Bartosz Taudul
a1b67e4299 Retrieve the model context size for use in UI and tools. 2025-07-12 11:50:09 +02:00
Bartosz Taudul
b33110e53e Retrieve context size for LM Studio models. 2025-07-12 11:50:09 +02:00
Bartosz Taudul
1d4bdfc8c3 Handle stop streaming requests in a more valid way. 2025-07-12 11:50:09 +02:00
Bartosz Taudul
fba21c1854 Filter out LM Studio embedding models. 2025-07-12 11:50:09 +02:00
Bartosz Taudul
fc9d787cf9 Move curl context setup to a separate function. 2025-07-12 11:50:09 +02:00
Bartosz Taudul
602a675bf4 Remove ugly advice about downloading LLM models. 2025-07-12 11:50:09 +02:00
Bartosz Taudul
3a27bcb8a9 Add system prompt tag.
This helps shut up gemma3 in LM Studio. Ollama doesn't need this.
2025-07-12 11:50:09 +02:00
Bartosz Taudul
aea3ad4730 Fix chat completions stop flow. 2025-07-12 11:50:09 +02:00
Bartosz Taudul
5f8c38a268 Include tool output in context size calculation. 2025-07-12 11:50:08 +02:00
Bartosz Taudul
782dc7de8d Direct the LLM to inform the user about enabling network access. 2025-07-12 11:50:08 +02:00
Bartosz Taudul
16eaf114a6 Don't duplicate network check code. 2025-07-12 11:50:08 +02:00
Bartosz Taudul
203e5e2b13 Add preset endpoint addresses for various LLM providers. 2025-07-12 11:50:08 +02:00
Bartosz Taudul
b398a4641a Switch from Ollama API to OpenAI API commonly used by all LLM providers. 2025-07-12 11:50:08 +02:00
Bartosz Taudul
b05bbc7f53 Enable CURLOPT_NOSIGNAL. 2025-07-12 11:50:08 +02:00
Bartosz Taudul
580423225e Get nlohmann json via CPM. 2025-07-12 11:50:08 +02:00
Bartosz Taudul
eae3c7ef80 Remove LLM config from global settings (leave just LLM checkbox). 2025-07-12 11:50:08 +02:00
Bartosz Taudul
a4418bf50b Move libcurl init to TracyLlm.cpp. 2025-07-12 11:50:07 +02:00
Bartosz Taudul
0f78084f8f Add dictionary support. 2025-07-12 11:50:07 +02:00
Bartosz Taudul
6d8d461f2b Extract calculation of max tool output size. 2025-07-12 11:50:07 +02:00
Bartosz Taudul
98e9383c89 Print language specifier in code blocks. 2025-07-12 11:50:07 +02:00
Bartosz Taudul
ea956f4cb2 Bullet points in markdown are '*' or '-'. 2025-07-12 11:50:07 +02:00
Bartosz Taudul
c0e89f992d Extend big font characters range. 2025-07-12 11:50:07 +02:00
Bartosz Taudul
43463abdfe Add bold, italic and bold+italic font. 2025-07-12 11:50:07 +02:00
Bartosz Taudul
2f9436577e Use global font structure. 2025-07-12 11:50:07 +02:00
Bartosz Taudul
183847821e Ignore annoying clang-tidy rules. 2025-07-12 11:50:06 +02:00
Bartosz Taudul
654243eeea Use embed utility to provide fonts. Replace Droid Sans with Roboto. 2025-07-12 11:50:06 +02:00
Bartosz Taudul
78a80b64fa Remove explicit spacing hacks.
The new text wrapped functionality works in a way that already does this.
2025-07-12 11:50:06 +02:00
Bartosz Taudul
64c0d645ee Render inline code fragments with fixed width font. 2025-07-12 11:50:06 +02:00
Bartosz Taudul
d5f732e768 Add ImGui::SameLine() capable wrapped text printing function.
Adapted from imgui_markdown.
2025-07-12 11:50:06 +02:00
Bartosz Taudul
bc7f365793 Use proper curl library name. 2025-07-12 11:50:06 +02:00
Bartosz Taudul
e4a9c9be3c Fix bad code in ollama-hpp. 2025-07-12 11:50:06 +02:00
Bartosz Taudul
bc126833e2 Fix operator std::string in ollama-hpp. 2025-07-12 11:50:06 +02:00
Bartosz Taudul
928ad3dd72 Add libcurl include dir to TracyLibcurl interface. 2025-07-12 11:50:05 +02:00
Bartosz Taudul
9bce0bda02 Disable libpsl when building curl. 2025-07-12 11:50:05 +02:00
Bartosz Taudul
ebe50c9981 Move implementation of all LLM tools to a separate file. 2025-07-12 11:50:05 +02:00
Bartosz Taudul
4af390719c Forward declare ImFont. 2025-07-12 11:50:05 +02:00
Bartosz Taudul
a68cd2543d Handle ollama with no models available. 2025-07-12 11:50:05 +02:00
Bartosz Taudul
915e4ab77e Less strict tool use requirements. 2025-07-12 11:50:05 +02:00
Bartosz Taudul
101c7c40f7 Provide current time and date in the system prompt. 2025-07-12 11:50:05 +02:00
Bartosz Taudul
f68253a085 Allow disabling network access for the LLM. 2025-07-12 11:50:05 +02:00
Bartosz Taudul
b574e28b79 Refine system prompt. 2025-07-12 11:50:05 +02:00
Bartosz Taudul
aa925a81f7 Fix multiple think tags in one reply. 2025-07-12 11:50:04 +02:00
Bartosz Taudul
518587779f Add an option to enable sanitizers. 2025-07-12 11:50:04 +02:00
Bartosz Taudul
9755f165f1 Prefer wikipedia as source of information. 2025-07-12 11:50:04 +02:00
Bartosz Taudul
92288bc710 Implement web search. 2025-07-12 11:50:04 +02:00
Bartosz Taudul
1e5f5215d4 Spoof user agent seen in the wild.
The state of modern web sadly discourages being honest.
2025-07-12 11:50:04 +02:00
Bartosz Taudul
c0ffd99c91 Allow setting custom temperature value. 2025-07-12 11:50:04 +02:00
Bartosz Taudul
229e810697 Don't set keep_alive value.
The default is 5 minutes anyway.
2025-07-12 11:50:04 +02:00
Bartosz Taudul
f4e340b573 Add note about context size estimation. 2025-07-12 11:50:04 +02:00
Bartosz Taudul
d0acd37b54 Calculate system prompt context size estimate. 2025-07-12 11:50:03 +02:00
Bartosz Taudul
290198704b Rewrite the tools description to json. 2025-07-12 11:50:03 +02:00
Bartosz Taudul
522395d37e Add a send message button. 2025-07-12 11:50:03 +02:00
Bartosz Taudul
72de3ecaa7 Add web cache. 2025-07-12 11:50:03 +02:00
Bartosz Taudul
82b976b1ee Adjust user messages color. 2025-07-12 11:50:03 +02:00
Bartosz Taudul
97048cf692 Improve wikipedia search by providing a summary of the page. 2025-07-12 11:50:03 +02:00
Bartosz Taudul
a6c77d73a4 Enable wikipedia in other languages. 2025-07-12 11:50:03 +02:00
Bartosz Taudul
5bbe81a029 Don't retrieve the full image, thumbnail is enough.
Too much context pollution for too little gain.
2025-07-12 11:50:03 +02:00
Bartosz Taudul
1f9639dfe3 Reword tool knowledge rules. 2025-07-12 11:50:02 +02:00
Bartosz Taudul
14fc45a1e2 Specify user agent. 2025-07-12 11:50:02 +02:00
Bartosz Taudul
a7cc678960 Display appropriate icon when tool reply contains an image. 2025-07-12 11:50:02 +02:00
Bartosz Taudul
46c000fd66 Fix scrolling. 2025-07-12 11:50:02 +02:00
Bartosz Taudul
41f9b75372 Add Latin Extended A/B to fixed width font. 2025-07-12 11:50:02 +02:00
Bartosz Taudul
a35e996f4f Release lock when handling tool calls. 2025-07-12 11:50:02 +02:00
Bartosz Taudul
0ba0590dbc Don't use the "tool" role. 2025-07-12 11:50:02 +02:00
Bartosz Taudul
68b73811c4 Retrieve images from wikipedia. 2025-07-12 11:50:02 +02:00
Bartosz Taudul
13eca84926 Use the user language. 2025-07-12 11:50:01 +02:00
Bartosz Taudul
80f678c28a Replace spaces in wikipedia page queries with underscores. 2025-07-12 11:50:01 +02:00
Bartosz Taudul
e293f87a8a Adapt the wikipedia page cut-off to the available context size. 2025-07-12 11:50:01 +02:00
Bartosz Taudul
31afd9dbca Url encode wikipedia search queries. 2025-07-12 11:50:01 +02:00
Bartosz Taudul
4f49635c42 Further system prompt refinement. 2025-07-12 11:50:01 +02:00
Bartosz Taudul
b2f3e6b681 The models like to group separate wikipedia query terms.
Some search examples:
1. Tracy Profiler
2. "Tracy Profiler" "C++"
3. "Tracy Profiler"
2025-07-12 11:50:01 +02:00
Bartosz Taudul
40fed7dd6f Update system prompt with new rules. 2025-07-12 11:50:01 +02:00
Bartosz Taudul
8a6a6d8132 Merge wikipedia query terms with '+' in code, not in LLM. 2025-07-12 11:50:01 +02:00
Bartosz Taudul
116881ae81 Remove stray \r characters from the LLM responses. 2025-07-12 11:50:01 +02:00
Bartosz Taudul
50886ac16e Wikipedia search + article retrieval. 2025-07-12 11:50:00 +02:00
Bartosz Taudul
b0a36cb8e8 Use correct parameter for setting context size. 2025-07-12 11:50:00 +02:00
Bartosz Taudul
a8dd0ca232 Add Latin Extended A/B to font. 2025-07-12 11:50:00 +02:00
Bartosz Taudul
b54e36df29 Display context usage. 2025-07-12 11:50:00 +02:00
Bartosz Taudul
e60e30ddf1 Don't persist tree node open state between chats. 2025-07-12 11:50:00 +02:00
Bartosz Taudul
b163d97e65 Fix setting context size. 2025-07-12 11:50:00 +02:00
Bartosz Taudul
f65302984e Remove html2md, remove access to web for LLM. 2025-07-12 11:50:00 +02:00
Bartosz Taudul
8b100ff11d Use custom tool handling.
The ollama tool_calls do not preserve the context of why the tool was
called. The feature as it is right now doesn't seem to be designed for
the LLM to make queries, but rather to act as an agent that is supposed
to call some functions that will directly provide their output to the
user.

Instead, let's encode the tool calling protocol in the system prompt.
2025-07-12 11:50:00 +02:00
Bartosz Taudul
0d3e183540 Display tool responses in chat. 2025-07-12 11:49:59 +02:00
Bartosz Taudul
05f7019f30 Chat will have system prompt. 2025-07-12 11:49:59 +02:00
Bartosz Taudul
2e61fbac78 Expand system prompt. 2025-07-12 11:49:59 +02:00
Bartosz Taudul
4ad9e05814 Convert html to markdown. 2025-07-12 11:49:59 +02:00
Bartosz Taudul
f5ea5ffce1 Display tool call arguments. 2025-07-12 11:49:59 +02:00
Bartosz Taudul
dc8c106454 Implement fetching web pages. 2025-07-12 11:49:59 +02:00
Bartosz Taudul
3a60926f65 Link with libcurl. 2025-07-12 11:49:59 +02:00
Bartosz Taudul
9202ce277d Respond to tool calls. 2025-07-12 11:49:59 +02:00
Bartosz Taudul
b4763c7500 Pass messages to SendMessage() as const ref, not rvalue. 2025-07-12 11:49:58 +02:00
Bartosz Taudul
78257553c7 Allow disabling tools use. 2025-07-12 11:49:58 +02:00
Bartosz Taudul
4c46cc4deb Push available tools list to ollama. 2025-07-12 11:49:58 +02:00
Bartosz Taudul
7eedbe130e Prepare ollama request in an explicit way. 2025-07-12 11:49:58 +02:00
Bartosz Taudul
3414773f18 Keep system prompt unembedded. 2025-07-12 11:49:58 +02:00
Bartosz Taudul
c8dbe33a3c Move LLM system prompt to an external file. 2025-07-12 11:49:58 +02:00
Bartosz Taudul
cc0aa73527 Add embed utilities. 2025-07-12 11:49:58 +02:00
Bartosz Taudul
8006ae9e30 Build embed tool. 2025-07-12 11:49:58 +02:00
Bartosz Taudul
8fd1530c8f Rework context size handling.
The user now specifies max context size to be used for all models.
2025-07-12 11:49:57 +02:00
Bartosz Taudul
74b6e481bb Add spacing between chat messages. 2025-07-12 11:49:57 +02:00
Bartosz Taudul
10decca063 Fix chat input focus. 2025-07-12 11:49:57 +02:00
Bartosz Taudul
b901544fb4 Draw ellipsis when waiting for ollama reply (loading model, parsing prompt, etc.) 2025-07-12 11:49:57 +02:00
Bartosz Taudul
1590d3196b Don't wait for streaming to end when exiting. 2025-07-12 11:49:57 +02:00
Bartosz Taudul
dedc9259c1 Add basic system prompt. 2025-07-12 11:49:57 +02:00
Bartosz Taudul
e8578668d4 Add support for basic markdown features. 2025-07-12 11:49:57 +02:00
Bartosz Taudul
2bf627061e Add support for printing code blocks. 2025-07-12 11:49:57 +02:00
Bartosz Taudul
b982515774 Use string references instead of copies. 2025-07-12 11:49:56 +02:00
Bartosz Taudul
60230c2d7e Split chat responses into lines for easier parsing. 2025-07-12 11:49:56 +02:00
Bartosz Taudul
cfd3260ea0 Count chat lines. 2025-07-12 11:49:56 +02:00
Bartosz Taudul
3a60a67c95 Explicitly check for assistant role. 2025-07-12 11:49:56 +02:00
Bartosz Taudul
2ad2fa0b4a Get role string only once. 2025-07-12 11:49:56 +02:00
Bartosz Taudul
1ebe85d24f Always show scroll bar in chat window. 2025-07-12 11:49:56 +02:00
Bartosz Taudul
ef230b08f3 Don't display the "thinking" unless asked for. 2025-07-12 11:49:56 +02:00
Bartosz Taudul
b90e0fa467 Adjust colors. 2025-07-12 11:49:56 +02:00
Bartosz Taudul
18a220d4db Support displaying ollama error messages. 2025-07-12 11:49:56 +02:00
Bartosz Taudul
22d139bff7 Allow changing context size. 2025-07-12 11:49:55 +02:00
Bartosz Taudul
c36386ac81 Scroll to bottom when chat is updating. 2025-07-12 11:49:55 +02:00
Bartosz Taudul
8edbdc8081 Add icons to help differentiate user from bot answers. 2025-07-12 11:49:55 +02:00
Bartosz Taudul
d499458c69 Working chat. 2025-07-12 11:49:55 +02:00
Bartosz Taudul
a25b189692 Put a date on the Weizenbaum quote. 2025-07-12 11:49:55 +02:00
Bartosz Taudul
dc325dae89 Focus chat entry field when LLM UI is opened. 2025-07-12 11:49:55 +02:00
Bartosz Taudul
58125770b1 Use ollama::messages instead of vector of strings to hold chat messages.
The implementation is similar, but this way is needed for the ollama-hpp
API.
2025-07-12 11:49:55 +02:00
Bartosz Taudul
c1998bd9f3 Basic chat input and rendering. 2025-07-12 11:49:55 +02:00
Bartosz Taudul
2ea7a183f1 Add chat UI elements. 2025-07-12 11:49:54 +02:00
Bartosz Taudul
4250fa51c2 Add model selection to LLM UI. 2025-07-12 11:49:54 +02:00
Bartosz Taudul
571189c9da Use the intended icon for setting default ollama url. 2025-07-12 11:49:54 +02:00
Bartosz Taudul
42010dc457 Handle no connection / busy cases in LLM UI. 2025-07-12 11:49:54 +02:00
Bartosz Taudul
ab76bafdf7 Use three dots to indicate background tasks instead of one pulsing dot. 2025-07-12 11:49:54 +02:00
Bartosz Taudul
3a4786d2be httplib may throw on invalid protocol. 2025-07-12 11:49:54 +02:00
Bartosz Taudul
4c7338ec1e Load LLM models in a thread. 2025-07-12 11:49:54 +02:00
Bartosz Taudul
fd291f225e Properly set state when reseting ollama URL to default. 2025-07-12 11:49:54 +02:00
Bartosz Taudul
6ce5c345a5 Don't fail when there are no models downloaded. 2025-07-12 11:49:54 +02:00
Bartosz Taudul
d50f05c00b Rework loading LLM models. 2025-07-12 11:49:53 +02:00
Bartosz Taudul
e4e23eabb6 Hook up LLM window. 2025-07-12 11:49:53 +02:00
Bartosz Taudul
e8c2d498d3 Remove redundant m_valid variable. 2025-07-12 11:49:53 +02:00
Bartosz Taudul
02b2882261 Display context size in model selection dropdown. 2025-07-12 11:49:53 +02:00
Bartosz Taudul
cf892505e1 Setup model, get context size. 2025-07-12 11:49:53 +02:00
Bartosz Taudul
0f31d6ac1a List LLM models in global settings. 2025-07-12 11:49:53 +02:00
Bartosz Taudul
08c877c4ef Add interface for listing LLM models. 2025-07-12 11:49:53 +02:00
Bartosz Taudul
cb212567ed Store selected LLM model. 2025-07-12 11:49:53 +02:00
Bartosz Taudul
d72898087f Allow creating TracyLlm when LLM is disabled. 2025-07-12 11:49:52 +02:00
Bartosz Taudul
6b0589f5eb Add configuration UI for LLM. 2025-07-12 11:49:52 +02:00
Bartosz Taudul
85a82fbb70 Implement checking for connection validity and API version in TracyLlm. 2025-07-12 11:49:52 +02:00
Bartosz Taudul
584ad9ffde Add LLM configuration. 2025-07-12 11:49:52 +02:00
Bartosz Taudul
a3e3f9a98f Add basic integration with ollama-hpp. 2025-07-12 11:49:49 +02:00
Bartosz Taudul
8fa40e87d1 Merge pull request #1016 from 6yry6e/systrace-hang-fix
Fix: Hang on shutdown with enabled system tracing
2025-07-12 11:49:05 +02:00
Eric Eaton
0c77bfcbed Use tracy data structures 2025-07-11 17:18:17 -07:00
Eric Eaton
114f6ef096 Supply the correct thread ID for annotations 2025-07-11 17:18:17 -07:00
Eric Eaton
3324b46dca Make rocprof optional 2025-07-11 17:18:16 -07:00
Eric Eaton
d4a35c5ab1 Change rocprof context name 2025-07-11 17:18:07 -07:00
Eric Eaton
3fce5c1280 Use a map to record counter values
This removes the limitation of 10 counters.
2025-07-11 17:17:05 -07:00
Eric Eaton
6a5e4d8a60 Use assert intead of a condition 2025-07-11 17:17:05 -07:00
Eric Eaton
1494fe5671 Apply code style 2025-07-11 17:17:05 -07:00
Eric Eaton
7fc5b6c977 Increase protocol version 2025-07-11 17:17:03 -07:00
Eric Eaton
9413436ba1 Search backward for the correct zone
Needed to make tracing more intense applications work.
2025-07-11 17:16:00 -07:00
Eric Eaton
d1f9df8058 Get counter names from environment variable
Allows user to customize the collected information with environment
variable TRACY_ROCPROF_COUNTERS.
2025-07-11 17:16:00 -07:00
Eric Eaton
e9e0404930 Add support for multiple counters 2025-07-11 17:16:00 -07:00
Eric Eaton
a754db16f8 Show counter name in GUI 2025-07-11 17:16:00 -07:00
Eric Eaton
2e49bdf4cb Add counter value collection 2025-07-11 17:16:00 -07:00
Eric Eaton
86de39704f Add calibration thread
Synchronizes the GPU timeline periodically. This is needed to counter
network time updates that cause drift in the GPU and CPU timeline.

Signed-off-by: Eric Eaton <erieaton@amd.com>
2025-07-11 17:16:00 -07:00
Eric Eaton
495321fc10 Record dispatch enqueue times 2025-07-11 17:16:00 -07:00
Eric Eaton
98047ffbe2 Delay initialization
Delay initialization until tracy is started. Removed some debug prints.
2025-07-11 17:16:00 -07:00
Eric Eaton
1517756d54 Add buffer copy tracing 2025-07-11 17:16:00 -07:00
Eric Eaton
00648836a2 Add rocprof dispatch tracing 2025-07-11 17:16:00 -07:00
Bartosz Taudul
880c600506 Remove queue delay calibration.
This value is not used for anything, it was just a number displayed in
the UI without much meaning to anyone.

Operations on the queue during early init may not work correctly, stopping
some programs from running past the calibration loop.
2025-07-11 23:23:31 +02:00
Bartosz Taudul
33713086b4 Disable stupid function size warnings. 2025-07-11 23:18:37 +02:00
Bartosz Taudul
91c17abcc7 Merge pull request #1092 from wannacu/master
Fix profiler compilation for older wayland version
2025-07-07 11:53:11 +02:00
wannacu
034b18a933 Fix profiler compilation for older wayland version 2025-07-07 11:54:14 +08:00
Bartosz Taudul
abbc35793e Merge pull request #1091 from siliceum/bugfix/ignorebuildfiles
Update gitignore with ToyPathTracer windows output
2025-07-04 15:47:25 +02:00
Bartosz Taudul
6578a11a1c Merge pull request #1090 from siliceum/bugfix/test-on-windows
Bugfix/test on windows
2025-07-04 15:47:02 +02:00
Clément Grégoire
9971280082 Update gitignore with ToyPathTracer windows output 2025-07-04 14:56:32 +02:00
Clément Grégoire
a3be5cca2c Set tracy-test exe as startup project 2025-07-04 14:54:13 +02:00
Clément Grégoire
84f3bd10e8 Make test app compile on windows SIGUSR1 does not exist on windows 2025-07-04 12:56:09 +02:00
Bartosz Taudul
1d4b9c77ce Merge pull request #1088 from jcl1234/master
Fix FiberEnter start time always being processed as 0
2025-07-02 13:55:27 +02:00
jcl1234
791904a37f Fix FiberEnter start time always being processed as 0 2025-07-01 22:38:10 -05:00
Bartosz Taudul
7388a47658 Fix LockMark source location name. 2025-06-28 00:04:07 +02:00
Bartosz Taudul
7f6efe3bd4 Merge pull request #1065 from maxime-modulopi/vulkan-collect-host
Add support for host query reset when collecting Vulkan traces
2025-06-26 14:51:51 +02:00
Maxime Duriez
656ff1ba16 Added TracyVkCollectHost to manual 2025-06-26 12:54:10 +02:00
Bartosz Taudul
c556831ddc Release 0.12.2. 2025-06-25 23:55:40 +02:00
Bartosz Taudul
8a8e16a559 Merge pull request #1083 from siliceum/bugfix/clear-button-find-zone
Fix Clear button behavior in Find Zone
2025-06-23 14:30:49 +02:00
Bartosz Taudul
be89f228ee Merge pull request #1081 from boguscoder/boguscoder-lua
Make TracyLua buildable with TRACY_NO_CALLSTACK
2025-06-21 00:12:12 +02:00
Oleg Bogdanov
4f9107fac5 Make TracyLua buildable with TRACY_NO_CALLSTACK
See discussion https://github.com/wolfpld/tracy/issues/1080
2025-06-20 12:45:54 -07:00
Antoine Mura
17ab46c539 Fix Clear Button in Find Zone 2025-06-20 11:05:02 +02:00
Bartosz Taudul
8caf4f0d60 Merge pull request #1078 from mcourteaux/master
Fix MinGW build.
2025-06-19 21:07:12 +02:00
Martijn Courteaux
8b1576170d Disable Windows __try1 __except1 mechanic to be cross compilable from Linux. 2025-06-19 17:11:28 +02:00
mncat77
1d6fda26ea Fix MinGW build 2025-06-19 17:11:28 +02:00
Bartosz Taudul
581e9cb28e Merge pull request #1076 from boguscoder/regex_fix
relax regex match in symbolication substitution
2025-06-19 11:34:06 +02:00
Oleg Bogdanov
84cbf46cc5 relax regex match in symbolication substitution
See discussion https://github.com/wolfpld/tracy/issues/1075
2025-06-18 18:50:05 -07:00
Bartosz Taudul
250daeabe7 Merge pull request #1074 from boguscoder/master
Fixing typo in log statement of symbolication
2025-06-18 23:16:48 +02:00
Oleg Bogdanov
1fa69045a3 Fixing typo in log statement of symbolication 2025-06-18 14:10:15 -07:00
Bartosz Taudul
1a872faae6 Update can't be built without NO_STATISTICS. 2025-06-18 20:00:34 +02:00
Bartosz Taudul
f1119d88b9 Merge pull request #1072 from neobrain/profiler_include_dirs
Add include directories for pkg-config dependencies in the profiler build
2025-06-17 18:40:40 +02:00
Tony Wasserka
22e580d4c0 Add include directories for pkg-config dependencies in the profiler build 2025-06-17 17:39:57 +02:00
Bartosz Taudul
764624d3d1 Merge pull request #1070 from rmarker/flameLimit
Add limit range for flame graph.
2025-06-15 17:03:04 +02:00
rmarker
e1b325741e Add limit range for flame graph.
Allow restricting the flame graph to a specific time range.
Similar to the existing range limits for other tools, such as for
statistics.
2025-06-15 17:41:27 +09:30
Bartosz Taudul
b69813f077 Fix CMake stupidity with Ninja vs Unix Makefiles generators. 2025-06-14 12:07:43 +02:00
Bartosz Taudul
d181e80c29 Fix builds out of git repository. 2025-06-14 11:56:17 +02:00
Maxime Duriez
6abd2505bd Added support for host query reset when collecting Vulkan traces 2025-06-07 21:06:39 +02:00
Timur Popov
46a5cc4fa5 Stop filling queues with systrace data on exit 2025-03-29 01:12:28 +02:00
336 changed files with 261942 additions and 227041 deletions

View File

@@ -1,18 +1,35 @@
# 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
BasedOnStyle: Microsoft
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
AllowShortLoopsOnASingleLine: true
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBraces: Allman
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
# AllowShortEnumsOnASingleLine: true # Broken for some reason, even in last versions of clang-format... So don't use it or it may change formating in the future.
AllowShortLambdasOnASingleLine: All
BreakConstructorInitializers: BeforeComma
BreakStringLiterals: false
ColumnLimit: 120
SpaceAfterTemplateKeyword: false
AlwaysBreakTemplateDeclarations: Yes
# Allman seems to break lambda formatting for some reason with `ColumnLimit: 0`. See https://github.com/llvm/llvm-project/issues/50275
# Even though it is supposed to have been fixed, issue still remains in 20.1.8. (and is very much present in 18.x which is the one shipped by VS2022 and VSCord clangd as of 2025-07-27)
# Things work fine with `BasedOnStyle: Microsoft` so use that instead
#BreakBeforeBraces: Allman
ColumnLimit: 0
# We'd like to use LeftWithLastLine but it's only available in >=19.x
#AlignEscapedNewlines: LeftWithLastLine
AlignEscapedNewlines: Left
FixNamespaceComments: false
IndentPPDirectives: AfterHash
IndentAccessModifiers: false
AccessModifierOffset: -4
LambdaBodyIndentation: OuterScope
PPIndentWidth: 2
IndentWidth: 4
PointerAlignment: Left
SpaceBeforeParens: Never
SpacesInParentheses: true
TabWidth: 4
AlignTrailingComments:
Kind: Leave

View File

@@ -20,18 +20,23 @@ Checks:
-google-readability-namespace-comments,
-misc-confusable-identifiers,
-misc-no-recursion,
-misc-use-anonymous-namespace,
-misc-use-internal-linkage,
-modernize-avoid-c-arrays,
-modernize-deprecated-headers,
-modernize-use-default-member-init,
-modernize-use-designated-initializers,
-modernize-use-trailing-return-type,
-performance-no-int-to-ptr,
-readability-braces-around-statements,
-readability-else-after-return,
-readability-function-cognitive-complexity,
-readability-function-size,
-readability-identifier-length,
-readability-implicit-bool-conversion,
-readability-isolate-declaration,
-readability-magic-numbers,
-readability-math-missing-parentheses,
-readability-qualified-auto,
-readability-uppercase-literal-suffix
'

35
.github/actions/test-tracy/action.yml vendored Normal file
View File

@@ -0,0 +1,35 @@
name: 'Test Tracy'
description: 'Build the Tracy test application with various cmake flag combinations'
inputs:
extra_cmake_flags:
description: 'Additional cmake flags appended to each configure command (e.g. cross-compilation flags)'
required: false
default: ''
runs:
using: 'composite'
steps:
- name: Test application
shell: bash
run: |
# test compilation with different flags
# we clean the build folder to reset cached variables between runs
cmake -B tests/tracy/build -S tests/tracy -DCMAKE_BUILD_TYPE=Release ${{ inputs.extra_cmake_flags }}
cmake --build tests/tracy/build --parallel
cmake -E rm -rf tests/tracy/build
# same with TRACY_ON_DEMAND
cmake -B tests/tracy/build -S tests/tracy -DCMAKE_BUILD_TYPE=Release -DTRACY_ON_DEMAND=ON ${{ inputs.extra_cmake_flags }}
cmake --build tests/tracy/build --parallel
cmake -E rm -rf tests/tracy/build
# same with TRACY_DELAYED_INIT and TRACY_MANUAL_LIFETIME
cmake -B tests/tracy/build -S tests/tracy -DCMAKE_BUILD_TYPE=Release -DTRACY_DELAYED_INIT=ON -DTRACY_MANUAL_LIFETIME=ON ${{ inputs.extra_cmake_flags }}
cmake --build tests/tracy/build --parallel
cmake -E rm -rf tests/tracy/build
# same with TRACY_DEMANGLE
cmake -B tests/tracy/build -S tests/tracy -DCMAKE_BUILD_TYPE=Release -DTRACY_DEMANGLE=ON ${{ inputs.extra_cmake_flags }}
cmake --build tests/tracy/build --parallel
cmake -E rm -rf tests/tracy/build

View File

@@ -5,24 +5,31 @@ on:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
env:
CPM_SOURCE_CACHE: ${{ github.workspace }}/cpm-cache
jobs:
build:
build-emscripten:
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
run: pacman -Syu --noconfirm && pacman -S --noconfirm --needed cmake git unzip python ninja zstd nodejs
- name: Setup emscripten
uses: mymindstorm/setup-emsdk@v14
uses: emscripten-core/setup-emsdk@v16
with:
version: 3.1.67
version: 5.0.7
- name: Trust git repo
run: git config --global --add safe.directory '*'
- uses: actions/checkout@v4
- name: Cache CPM packages
uses: actions/cache@v4
with:
path: ${{ env.CPM_SOURCE_CACHE }}
key: ${{ runner.os }}-cpm-${{ hashFiles('**/vendor.cmake', '**/CMakeLists.txt') }}
restore-keys: ${{ runner.os }}-cpm-
- 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
@@ -48,7 +55,7 @@ jobs:
path: bin
deploy:
runs-on: ubuntu-latest
needs: build
needs: build-emscripten
if: github.ref == 'refs/heads/master'
steps:
- uses: actions/download-artifact@v4

View File

@@ -5,9 +5,11 @@ on:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
workflow_call:
jobs:
build:
build-manual:
runs-on: ubuntu-latest

View File

@@ -5,64 +5,68 @@ on:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
env:
CPM_SOURCE_CACHE: ${{ github.workspace }}/cpm-cache
jobs:
build:
build-linux:
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
run: pacman -Syu --noconfirm && pacman -S --noconfirm --needed freetype2 debuginfod wayland dbus libxkbcommon libglvnd meson cmake git wayland-protocols nodejs lua
- name: Trust git repo
run: git config --global --add safe.directory '*'
- uses: actions/checkout@v4
- name: Cache CPM packages
uses: actions/cache@v4
with:
path: ${{ env.CPM_SOURCE_CACHE }}
key: ${{ runner.os }}-cpm-${{ hashFiles('**/vendor.cmake', '**/CMakeLists.txt') }}
restore-keys: ${{ runner.os }}-cpm-
- name: Profiler GUI
run: |
cmake -B profiler/build -S profiler -DCMAKE_BUILD_TYPE=Release -DGIT_REV=${{ github.sha }}
cmake --build profiler/build --parallel
if [ "${ACT:-}" != "true" ] && [ "${FORGEJO_ACTIONS:-}" != "true" ]; then
cmake --build profiler/build
else
cmake --build profiler/build --parallel 2
fi
- name: Update utility
run: |
cmake -B update/build -S update -DCMAKE_BUILD_TYPE=Release
cmake -B update/build -S update -DCMAKE_BUILD_TYPE=Release -DGIT_REV=${{ github.sha }}
cmake --build update/build --parallel
- name: Capture utility
run: |
cmake -B capture/build -S capture -DCMAKE_BUILD_TYPE=Release
cmake -B capture/build -S capture -DCMAKE_BUILD_TYPE=Release -DGIT_REV=${{ github.sha }}
cmake --build capture/build --parallel
- name: Csvexport utility
run: |
cmake -B csvexport/build -S csvexport -DCMAKE_BUILD_TYPE=Release
cmake -B csvexport/build -S csvexport -DCMAKE_BUILD_TYPE=Release -DGIT_REV=${{ github.sha }}
cmake --build csvexport/build --parallel
- name: Import utilities
run: |
cmake -B import/build -S import -DCMAKE_BUILD_TYPE=Release
cmake -B import/build -S import -DCMAKE_BUILD_TYPE=Release -DGIT_REV=${{ github.sha }}
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
- name: Merge utility
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
cmake -B merge/build -S merge -DCMAKE_BUILD_TYPE=Release -DGIT_REV=${{ github.sha }}
cmake --build merge/build --parallel
- name: Library (cmake)
run: |
cmake -B build -DCMAKE_BUILD_TYPE=Release -DTRACY_ENABLE=ON
cmake --build build
cmake --install build
env:
CMAKE_INSTALL_PREFIX: ${{ github.workspace }}/bin
- name: Library (meson)
run: |
meson setup -Dprefix=$GITHUB_WORKSPACE/bin/lib -Dtracy_enable=true build-meson
meson compile -C build-meson
- name: Test application
uses: ./.github/actions/test-tracy
- name: Find Artifacts
id: find_artifacts
run: |
@@ -73,6 +77,7 @@ jobs:
cp csvexport/build/tracy-csvexport bin
cp import/build/tracy-import-chrome bin
cp import/build/tracy-import-fuchsia bin
cp merge/build/tracy-merge bin
strip bin/tracy-*
- uses: actions/upload-artifact@v4
with:

69
.github/workflows/macos.yml vendored Normal file
View File

@@ -0,0 +1,69 @@
name: macos
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
env:
CPM_SOURCE_CACHE: ${{ github.workspace }}/cpm-cache
jobs:
build-macos:
runs-on: macos-15
steps:
- uses: actions/checkout@v4
- name: Cache CPM packages
uses: actions/cache@v4
with:
path: ${{ env.CPM_SOURCE_CACHE }}
key: ${{ runner.os }}-cpm-${{ hashFiles('**/vendor.cmake', '**/CMakeLists.txt') }}
restore-keys: ${{ runner.os }}-cpm-
- name: Install dependencies
run: brew install pkg-config glfw meson
- name: Trust git repo
run: git config --global --add safe.directory '*'
- name: Build profiler
run: |
cmake -B profiler/build -S profiler -DCMAKE_BUILD_TYPE=Release -DGIT_REV=${{ github.sha }}
cmake --build profiler/build --parallel 2 --config Release
- name: Build update
run: |
cmake -B update/build -S update -DCMAKE_BUILD_TYPE=Release -DGIT_REV=${{ github.sha }}
cmake --build update/build --parallel --config Release
- name: Build capture
run: |
cmake -B capture/build -S capture -DCMAKE_BUILD_TYPE=Release -DGIT_REV=${{ github.sha }}
cmake --build capture/build --parallel --config Release
- name: Build csvexport
run: |
cmake -B csvexport/build -S csvexport -DCMAKE_BUILD_TYPE=Release -DGIT_REV=${{ github.sha }}
cmake --build csvexport/build --parallel --config Release
- name: Build import
run: |
cmake -B import/build -S import -DCMAKE_BUILD_TYPE=Release -DGIT_REV=${{ github.sha }}
cmake --build import/build --parallel --config Release
- name: Build merge
run: |
cmake -B merge/build -S merge -DCMAKE_BUILD_TYPE=Release -DGIT_REV=${{ github.sha }}
cmake --build merge/build --parallel --config Release
- name: Build library
run: meson setup -Dprefix=$GITHUB_WORKSPACE/bin/lib -Dtracy_enable=true build && meson compile -C build && meson install -C build
- name: Test application
uses: ./.github/actions/test-tracy
- name: Package 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
cp merge/build/tracy-merge bin
- uses: actions/upload-artifact@v4
with:
name: macos
path: bin

61
.github/workflows/mingw.yml vendored Normal file
View File

@@ -0,0 +1,61 @@
name: build-mingw
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
env:
CPM_SOURCE_CACHE: ${{ github.workspace }}/cpm-cache
jobs:
build-mingw:
runs-on: ubuntu-latest
container: archlinux:base-devel
steps:
- name: Install dependencies
run: |
pacman -Syu --noconfirm
pacman -S --noconfirm --needed mingw-w64-gcc cmake git nodejs meson
- name: Trust git repo
run: git config --global --add safe.directory '*'
- uses: actions/checkout@v4
- name: Cache CPM packages
uses: actions/cache@v4
with:
path: ${{ env.CPM_SOURCE_CACHE }}
key: ${{ runner.os }}-cpm-${{ hashFiles('**/vendor.cmake', '**/CMakeLists.txt') }}
restore-keys: ${{ runner.os }}-cpm-
- name: Build TracyClient
run: |
cmake -B build -DCMAKE_BUILD_TYPE=Release -DTRACY_ENABLE=ON \
-DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc \
-DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++
cmake --build build
- name: Library (meson)
run: |
cat > mingw-cross.txt << 'EOF'
[binaries]
c = '/usr/bin/x86_64-w64-mingw32-gcc'
cpp = '/usr/bin/x86_64-w64-mingw32-g++'
ar = '/usr/bin/x86_64-w64-mingw32-ar'
strip = '/usr/bin/x86_64-w64-mingw32-strip'
[host_machine]
system = 'windows'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'
EOF
meson setup build-meson --cross-file mingw-cross.txt -Ddefault_library=static -Dtracy_enable=true
meson compile -C build-meson
- name: Test application
uses: ./.github/actions/test-tracy
with:
extra_cmake_flags: >-
-DCMAKE_SYSTEM_NAME=Windows
-DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc
-DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++

29
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,29 @@
name: release
on:
release:
types: [published]
jobs:
release-build-windows:
uses: ./.github/workflows/windows.yml
release-build-manual:
uses: ./.github/workflows/latex.yml
attach-to-release:
needs: [release-build-windows, release-build-manual]
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
- name: Create versioned zip
run: |
VERSION="${{ github.event.release.tag_name }}"
VERSION_NO_V="${VERSION#v}"
cd windows
zip -r ../windows-$VERSION_NO_V.zip .
- uses: softprops/action-gh-release@v2
with:
files: |
windows-*.zip
manual/tracy.pdf

View File

@@ -1,74 +1,61 @@
name: build
name: windows
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
workflow_call:
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
build-windows:
runs-on: windows-latest
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
- name: Cache CPM packages
uses: actions/cache@v4
with:
path: ${{ env.CPM_SOURCE_CACHE }}
key: ${{ runner.os }}-cpm-${{ hashFiles('**/vendor.cmake', '**/CMakeLists.txt') }}
restore-keys: ${{ runner.os }}-cpm-
- uses: microsoft/setup-msbuild@v2
- 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
- run: pip install meson ninja
- name: Trust git repo
run: git config --global --add safe.directory '*'
- name: Profiler GUI
- name: Build profiler
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
cmake --build profiler/build --parallel 2 --config Release
- name: Build update
run: |
cmake -B update/build -S update -DCMAKE_BUILD_TYPE=Release
cmake -B update/build -S update -DCMAKE_BUILD_TYPE=Release -DGIT_REV=${{ github.sha }}
cmake --build update/build --parallel --config Release
- name: Capture utility
- name: Build capture
run: |
cmake -B capture/build -S capture -DCMAKE_BUILD_TYPE=Release
cmake -B capture/build -S capture -DCMAKE_BUILD_TYPE=Release -DGIT_REV=${{ github.sha }}
cmake --build capture/build --parallel --config Release
- name: Csvexport utility
- name: Build csvexport
run: |
cmake -B csvexport/build -S csvexport -DCMAKE_BUILD_TYPE=Release
cmake -B csvexport/build -S csvexport -DCMAKE_BUILD_TYPE=Release -DGIT_REV=${{ github.sha }}
cmake --build csvexport/build --parallel --config Release
- name: Import utilities
- name: Build import
run: |
cmake -B import/build -S import -DCMAKE_BUILD_TYPE=Release
cmake -B import/build -S import -DCMAKE_BUILD_TYPE=Release -DGIT_REV=${{ github.sha }}
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
- name: Build merge
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
cmake -B merge/build -S merge -DCMAKE_BUILD_TYPE=Release -DGIT_REV=${{ github.sha }}
cmake --build merge/build --parallel --config Release
- name: Test application
uses: ./.github/actions/test-tracy
- name: Package artifacts
run: |
mkdir bin
copy profiler\build\Release\tracy-profiler.exe bin
@@ -77,7 +64,8 @@ jobs:
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
copy merge\build\Release\tracy-merge.exe bin
- uses: actions/upload-artifact@v4
with:
name: ${{ matrix.os }}
name: windows
path: bin

5
.gitignore vendored
View File

@@ -30,7 +30,12 @@ profiler/build/win32/Tracy.aps
extra/vswhere.exe
extra/tracy-build
.cache
.uv-cache/
.venv/
compile_commands.json
profiler/build/wasm/Tracy-release.*
profiler/build/wasm/Tracy-debug.*
profiler/build/wasm/embed.tracy
examples/ToyPathTracer/Windows/TestCpu
examples/ToyPathTracer/Windows/x64
*.user

View File

@@ -1,12 +1,12 @@
{
"cmake.configureOnOpen": true,
"cmake.sourceDirectory": [
"${workspaceFolder}/profiler",
"${workspaceFolder}/capture",
"${workspaceFolder}/csvexport",
"${workspaceFolder}/import",
"${workspaceFolder}/merge",
"${workspaceFolder}/update",
"${workspaceFolder}/test",
"${workspaceFolder}/tests/tracy",
"${workspaceFolder}",
],
"cmake.buildDirectory": "${sourceDirectory}/build",

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.10)
cmake_minimum_required(VERSION 3.13)
# Run version helper script
include(cmake/version.cmake)
@@ -33,6 +33,7 @@ else()
endif()
find_package(Threads REQUIRED)
find_package(rocprofiler-sdk PATHS "/opt/rocm/lib/cmake")
set(TRACY_PUBLIC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/public)
@@ -56,6 +57,10 @@ target_link_libraries(
Threads::Threads
${CMAKE_DL_LIBS}
)
if(rocprofiler-sdk_FOUND)
target_compile_definitions(TracyClient PUBLIC TRACY_ROCPROF)
target_link_libraries(TracyClient PUBLIC rocprofiler-sdk::rocprofiler-sdk)
endif()
if(TRACY_Fortran)
add_library(TracyClientF90 ${TRACY_VISIBILITY} "${TRACY_PUBLIC_DIR}/TracyClient.F90")
@@ -73,7 +78,8 @@ endif()
# Public dependency on some libraries required when using Mingw
if(WIN32 AND ${CMAKE_CXX_COMPILER_ID} MATCHES "GNU|Clang")
target_link_libraries(TracyClient PUBLIC ws2_32 dbghelp)
target_link_libraries(TracyClient PUBLIC ws2_32 dbghelp secur32)
target_compile_definitions(TracyClient PUBLIC WINVER=0x0A00 _WIN32_WINNT=0x0A00)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
@@ -100,53 +106,58 @@ if(TRACY_Fortran)
add_library(Tracy::TracyClient_Fortran ALIAS TracyClientF90)
endif()
macro(set_option option help value)
option(${option} ${help} ${value})
if(${option})
message(STATUS "${option}: ON")
target_compile_definitions(TracyClient PUBLIC ${option})
else()
message(STATUS "${option}: OFF")
endif()
endmacro()
include(cmake/options.cmake)
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_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)
set_option(TRACY_NO_BROADCAST "Disable client discovery by broadcast to local network" OFF)
set_option(TRACY_ONLY_IPV4 "Tracy will only accept connections on IPv4 addresses (disable IPv6)" OFF)
set_option(TRACY_NO_CODE_TRANSFER "Disable collection of source code" OFF)
set_option(TRACY_NO_CONTEXT_SWITCH "Disable capture of context switches" OFF)
set_option(TRACY_NO_EXIT "Client executable does not exit until all profile data is sent to server" OFF)
set_option(TRACY_NO_SAMPLING "Disable call stack sampling" OFF)
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)
set_option(TRACY_ENABLE "Enable profiling" OFF TracyClient)
set_option(TRACY_ON_DEMAND "On-demand profiling" OFF TracyClient)
set_option_value(TRACY_CALLSTACK "Override the callstack collection depth for tracy zones" "" TracyClient)
set_option_value_as_string(TRACY_PLATFORM_HEADER "Path to a header providing TRACY_HAS_CUSTOM_* hooks for an unsupported platform" "" TracyClient)
set_option(TRACY_NO_CALLSTACK "Disable all callstack related functionality" OFF TracyClient)
set_option(TRACY_NO_CALLSTACK_INLINES "Disables the inline functions in callstacks" OFF TracyClient)
set_option(TRACY_ONLY_LOCALHOST "Only listen on the localhost interface" OFF TracyClient)
set_option(TRACY_NO_BROADCAST "Disable client discovery by broadcast to local network" OFF TracyClient)
set_option(TRACY_ONLY_IPV4 "Tracy will only accept connections on IPv4 addresses (disable IPv6)" OFF TracyClient)
set_option(TRACY_NO_CODE_TRANSFER "Disable collection of source code" OFF TracyClient)
set_option(TRACY_NO_CONTEXT_SWITCH "Disable capture of context switches" OFF TracyClient)
set_option(TRACY_NO_EXIT "Client executable does not exit until all profile data is sent to server" OFF TracyClient)
set_option(TRACY_NO_SAMPLING "Disable call stack sampling" OFF TracyClient)
set_option(TRACY_NO_VERIFY "Disable zone validation for C API" OFF TracyClient)
set_option(TRACY_NO_VSYNC_CAPTURE "Disable capture of hardware Vsync events" OFF TracyClient)
set_option(TRACY_NO_FRAME_IMAGE "Disable the frame image support and its thread" OFF TracyClient)
set_option(TRACY_NO_SYSTEM_TRACING "Disable systrace sampling" OFF TracyClient)
set_option(TRACY_PATCHABLE_NOPSLEDS "Enable nopsleds for efficient patching by system-level tools (e.g. rr)" OFF TracyClient)
set_option(TRACY_DELAYED_INIT "Enable delayed initialization of the library (init on first call)" OFF TracyClient)
set_option(TRACY_MANUAL_LIFETIME "Enable the manual lifetime management of the profile" OFF TracyClient)
set_option(TRACY_FIBERS "Enable fibers support" OFF TracyClient)
set_option(TRACY_NO_CRASH_HANDLER "Disable crash handling" OFF TracyClient)
set_option(TRACY_TIMER_FALLBACK "Use lower resolution timers" OFF TracyClient)
set_option(TRACY_DISALLOW_HW_TIMER "Disallow hardware timer (may be useful on VMs). Requires TRACY_TIMER_FALLBACK=ON" OFF TracyClient)
set_option(TRACY_LIBUNWIND_BACKTRACE "Use libunwind backtracing where supported" OFF TracyClient)
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 TracyClient)
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 TracyClient)
set_option(TRACY_DEBUGINFOD "Enable debuginfod support" OFF TracyClient)
set_option(TRACY_IGNORE_MEMORY_FAULTS "Ignore instrumentation errors from memory free events that do not have a matching allocation" OFF TracyClient)
set_option(TRACY_OPENGL_AUTO_CALIBRATION "Periodically recalibrate OpenGL GPU/CPU clock drift (forces a CPU/GPU sync each time)" OFF TracyClient)
# advanced
set_option(TRACY_VERBOSE "[advanced] Verbose output from the profiler" OFF)
set_option(TRACY_VERBOSE "[advanced] Verbose output from the profiler" OFF TracyClient)
mark_as_advanced(TRACY_VERBOSE)
set_option(TRACY_DEMANGLE "[advanced] Don't use default demangling function - You'll need to provide your own" OFF)
set_option(TRACY_NO_INTERNAL_MESSAGE "[advanced] Prevent the profiler from logging messages" OFF TracyClient)
mark_as_advanced(TRACY_NO_INTERNAL_MESSAGE)
set_option(TRACY_DEMANGLE "[advanced] Don't use default demangling function - You'll need to provide your own" OFF TracyClient)
mark_as_advanced(TRACY_DEMANGLE)
if(rocprofiler-sdk_FOUND)
set_option(TRACY_ROCPROF_CALIBRATION "[advanced] Use continuous calibration of the Rocprof GPU time." OFF TracyClient)
mark_as_advanced(TRACY_ROCPROF_CALIBRATION)
endif()
# 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(TRACY_DISALLOW_HW_TIMER AND NOT TRACY_TIMER_FALLBACK)
message(FATAL_ERROR "TRACY_DISALLOW_HW_TIMER can not be activated with disabled TRACY_TIMER_FALLBACK")
endif()
if(NOT TRACY_STATIC)
target_compile_definitions(TracyClient PRIVATE TRACY_EXPORTS)
@@ -186,6 +197,7 @@ set(client_includes
${TRACY_PUBLIC_DIR}/client/TracyDxt1.hpp
${TRACY_PUBLIC_DIR}/client/TracyFastVector.hpp
${TRACY_PUBLIC_DIR}/client/TracyLock.hpp
${TRACY_PUBLIC_DIR}/client/TracyMangle.hpp
${TRACY_PUBLIC_DIR}/client/TracyProfiler.hpp
${TRACY_PUBLIC_DIR}/client/TracyRingBuffer.hpp
${TRACY_PUBLIC_DIR}/client/TracyScoped.hpp
@@ -209,21 +221,22 @@ set(common_includes
${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/TracyTaggedUserlandAddress.hpp
${TRACY_PUBLIC_DIR}/common/TracyWinFamily.hpp
${TRACY_PUBLIC_DIR}/common/TracyYield.hpp)
install(TARGETS TracyClient
EXPORT TracyConfig
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}/$<IF:$<CONFIG:Release>,,$<CONFIG>>
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/$<IF:$<CONFIG:Release>,,$<CONFIG>>
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/$<IF:$<CONFIG:Release>,,$<CONFIG>>
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}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}/$<IF:$<CONFIG:Release>,,$<CONFIG>>
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/$<IF:$<CONFIG:Release>,,$<CONFIG>>
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/$<IF:$<CONFIG:Release>,,$<CONFIG>>
COMPONENT lib)
endif()
# Export targets to build tree root
@@ -271,3 +284,7 @@ if(TRACY_CLIENT_PYTHON)
add_subdirectory(python)
endif()
if(PROJECT_IS_TOP_LEVEL)
set(CMAKE_COLOR_DIAGNOSTICS ON)
endif()

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-2026, Bartosz Taudul <wolf@nereid.pl>
All rights reserved.
Redistribution and use in source and binary forms, with or without

278
NEWS
View File

@@ -2,6 +2,284 @@ 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 (2026-xx-xx)
--------------------
- API break: removed "secure" variants of memory alloc and free macros. The
secure code path is now always enabled. Migrate by removing "Secure" from
the macros you use, e.g. TracySecureAlloc(...) -> TracyAlloc(...).
- Added tracy-capture-daemon for automated multi-client trace capture.
- Added tracy-merge utility for combining multiple trace files into one.
- Added support for Windows on ARM64 with MSVC.
- Added support for WebGPU.
- Trace-specific settings storage has been completely overhauled. It is now
possible to make the settings sidecar file public, saved next to the trace
file.
- External frames are now omitted in the single-line call stack list visible
in messages list, or in memory allocation info window.
- External frames are now hidden by default in various contexts where they
were previously enabled:
- Flame graph window.
- Call stack window.
- Statistics window (sampling mode).
- External frames are now dimmed out in call stacks in various parts of UI.
- Single-line call stacks now have ellipsis at the end, if there are frames
remaining.
- System tracing on Windows has been refactored to be more robust.
- Tracing on Arm macOS will now have more precise timer readings.
- Extended CUDA support to track some previously missing memory operations.
- Added support for setting message's source and severity, through the
TracyLogString macro.
- The "zone trace" list in zone information window has been removed. It was
never convenient to use properly. It was replaced by "parent zones" list,
which is basically a less convoluted equivalent.
- Added inline call stack list to the zone information window.
- The "call stack" button for opening the call stack in a separate window
is still there.
- Call stacks are now also displayed in zone tooltips (single-line).
- Implemented heuristic reconstruction of zone call stacks for zones that
were captured without call stacks.
- Requires sampling to be enabled, and at least one sample in the zone
extent.
- Since this is a heuristic, the result can be wrong.
- The reconstructed call stack can be displayed in the zone tooltip and in
the inline call stack view in zone information window.
- Reconstructed call stacks are indicated with the "magic wand" icon.
- Various LLM integration improvements.
- The protocol has been updated to use model templates. As a result, tools
are now specified in a common way and the reasoning is performed in a
separate content stream.
- Several new tools were added, which in concert enable the assistant to
answer very general questions, such as "how to optimize this program?".
- Smaller models are now viable to use. Models as small as 4B parameters do
now work really well. You can run such models on virtually all hardware.
- Added horizontal scroll bars to code segments.
- LLM thinking regions are now hidden by default.
- The assistant may notify the user about its current findings, then
resume thinking, after which it may give a more complete answer. In
such cases, the initial part of the reply will be faded out.
- Sampled execution costs are now included in assembly attachments.
- Source code retrieval now has an optional line context parameter.
- Added ability to search the code for keywords.
- Calls in assembly attachments are now annotated with function names.
- Wikipedia search will now return 10 results, not only the top one.
- Brave search engine is now available as an alternative web search option.
- Added emoji font.
- Maximum tool reply size has been tweaked to better work with larger
contexts.
- Tool reply size limit is now configurable in LLM settings.
- Tool reply eviction logic for context management has been adjusted to
better work with larger contexts. Additional logic was added to prefer
eviction of old responses.
- Certain LLM actions want to run in a fast mode, with reasoning disabled.
In most scenarios the default chat model will have to do here. If you
have the memory to spare, you can optionally load two models at once,
setting the "fast" model to a smaller and much quicker one.
- Chat topic description is now provided, based on the first user question.
- Each assistant reply is now labeled with used model and reply time.
- Follow-up questions can be automatically suggested.
- Expanded LLM attachments.
- You can now attach complete symbol assembly.
- Entry call stacks can be now attached (previously it was only regular
call stacks).
- Crash call stack attachments are now annotated with crash info.
- Source code can be attached (also with execution costs in symbol view).
- Zone histogram data can be attached for analysis.
- Markdown renderer improvements.
- Tables are now properly rendered.
- Tasklist rendering has been implemented.
- Strikethrough is now supported.
- Clickable links are now underlined.
- Tweaked high-resolution scroll handling on Wayland.
- Touchpad gestures on the timeline now either scroll or zoom, but not both
simultaneously.
- Full user name is now stored in trace info.
- External functions can be filtered out in the sampling statistics view.
- Tweaked external paths heuristics.
- Check for both 64-bit and 32-bit versions of Program Files directory.
- Hidden unix files and directories are now also considered external. For
example: $(HOME)/.cache/cpm/somelib/file.h.
- Call stack window can now provide LLM summaries.
- These summaries can be performed automatically. Enable in LLM settings.
- The capture utility is now displaying query backlog, just like the profiler
GUI.
- Lua source locations that are script code will now have newlines removed.
This is a capture-time change, so previously captured broken Lua source
locations won't be fixed.
- Call stack window will now display notification if viewing a crash call
stack.
- Removal of Tracy crash handler stack from the reported crash call stack
should now work again on Linux.
- In disassembly line view, source file names are now displayed instead of
"unknown", in case the source line number is not known.
- Trace host info is now properly formatted.
- It is now possible to sort the order of threads on the timeline ("visible
threads" in trace settings).
- Added clipboard support to emscripten backend.
- Added TRACY_DISALLOW_HW_TIMER define for virtualized environments and WSL2,
which may not have reliable access to hardware timer registers. Falls back
to standard library timer with reduced resolution.
- Fixed DPI scaling on macOS.
- Thread names are no longer truncated to 15 characters on Apple.
- Executable path is now inspected when looking for PDB files on Windows.
- Added ___tracy_get_time() C API as an equivalent for Profiler::GetTime().
- D3D12 instrumentation improvements.
- CUDA instrumentation improvements.
- Properly set API visibility attributes on MSVC + clang.
- Fixed regression in data sorting algorithm that could cause broken (going
back in time) plots. A retroactive fix is included for previously broken
traces.
- All tools provided by the project now report the version number and git sha
revision on the command line help output.
- Microarchitectural data has been updated to include the latest uops.info
measurements.
- Added validation check for SymSrv.dll on Windows.
- Various CMake options are now available to control optional build settings:
- NO_LTO disables link-time optimization.
- NO_MOLD_LINKER disables use of the mold linker.
- NO_CCACHE disables use of ccache (compiler cache).
- The Tracy library now has TRACY_ENABLED unset by default in the CMake and
Meson default configurations. This now matches what the documentation was
always saying. Some build setups may need updating.
- Adjust to max sampling rate on Linux.
- Further improvements to tracefs mount path discovery robustness.
- Macro mismatch detection between Tracy configuration and client code.
- Tracy client build settings change the ABI of the library.
- Mismatched versions will break at linking.
- As a reminder, Tracy *always* required using the same set of compilation
options for the entire program.
- Message windows will now properly show full message in a tooltip for
multi-line messages.
- Greatly improved the in-profiler user manual.
- There is now chapter tree and the manual contents are displayed section
by section.
- Links to chapters are now properly working.
- The "bclogo" blocks are now correctly processed and displayed as proper
admonitions.
- The font awesome icons now show as in the rest of the UI.
- Footnotes are now rendered as proper footnotes.
- Tables are now rendered as intended.
- LaTeX math is now converted to readable form.
- Added a button to download the full PDF manual to the user manual window.
- Call stack window will now show the thread viewed call stack originates
from (if possible).
- "Visible threads" checkboxes in messages, flame graph and wait stacks
windows are now displayed in multiple columns, and the maximum number of
visible rows is limited, with fallback to scrollable view.
- Improved child call distribution list in the symbol view window.
- The visible area can be now resized horizontally.
- The list is now displayed as a table with resizable columns, etc.
- Child calls time percentage is now shown as a percentage of calls (as
it was before), and also as a percentage of total symbol time.
- Child calls time is now also displayed as a percentage.
- Prototype implementation of system tracing on Apple devices.
- Local (inline) call stack printouts were added to tooltips in statistics
window, in sampling mode.
- Ironed out some code corners to make integration of closed gaming console
platforms easier. Added support for custom platform headers.
- Bottom and top sample trees (in wait stacks, or in entry call stacks)
now display aggregation counts if "group by function name" is enabled.
- HW sample view in symbol view are now disabled by default.
- The profiler can no longer be built with the statistics disabled.
- Fixed NVCC builds.
- Fixed possible lockups in Vulkan timer calibration loop.
- The flame graph view now supports zooming in and panning with the mouse.
- General application crash information polish in the profiler UI.
- The achievements system has been converted to use markdown renderer.
- Offline symbol resolution with the update utility now supports custom
addr2line-compatible tools via -a and -A command line parameters.
Additionally, it is now possible to reset all call stack frame symbols to
unresolved with the -R parameter.
- Periodic recalibration of the clock drift in OpenGL contexts can be enabled
with the TRACY_OPENGL_AUTO_CALIBRATION compilation define. Note that this
requires a full CPU/GPU sync on each calibration event. These events will
not fire more often than once every second.
- Added missing C API for shared locks.
- Implemented semi-unique, nonsense random name generator.
- Can be used to set a trace description.
- Will be used to provide default description for newly added annotations.
- Polished look and feel of annotation regions on the timeline.
v0.13.1 (2025-12-11)
--------------------
- Fixed parsing of extended model and family of x86 CPUID.
- Fixed memory corruption when a "long" user name was used on Android.
- Fixed wrong function signature when TRACY_DEBUGINFOD was enabled.
- Mount list is now read using proper API instead of processing /proc/mounts.
- Fixed shadow warning supression not being enabled on gcc.
- Silently ignore lost ETW Vsync events instead of asserting.
- Worked around few cases where old macOS machines do not support C++20
properly. Thanks Tim Apple!
- Added truncated mean parameter to csvexport.
- Added experimental viewer for the user manual.
- Memory free faults can be now ignored with the TRACY_IGNORE_MEMORY_FAULTS
option.
- Fixed race condition during profiler shutdown.
v0.13.0 (2025-11-11)
--------------------
- Added optional LLM integration.
- Can be completely disabled in options.
- Requires you to provide a local LLM service.
- Can be used to retrieve information from the user manual.
- Can answer queries about application call stacks, assembly code, other
general questions.
- Will refer to network resources to obtain information.
- The required setup is detailed in the user manual.
- Added support for Microsoft Game Development Kit (GDK).
- Added support for ROCm / Rocprof.
- Default values for certain settings can be now saved in the options
window.
- The display height of any timeline thread can be limited with a thread
cropper widget at the left border of the screen.
- System tracing is now stopped when the profiled program wants to exit.
- System tracing can be now enabled and disabled by the profile program.
- Added support for host query reset when collecting Vulkan traces.
- The find zone statistics now also show P99 and P99.9.
- Timeline for a thread will no longer hide if there are no zones to show,
but samples are visible.
- Fixed problems with Wayland integration.
- Proper order of operations is now ensured during initialization.
- The window size calculations for fractional scaling are now done
correctly.
- The Linux tracefs mount path is now properly detected, instead of relying
on a hardcoded value.
- Fixed LockMark macro expansion.
- Fixed invalid reported fiber enter time.
- Properly handle fiber enter and leave events in the on demand mode.
- Removed calibration of queue delay time. It served no real purpose.
- Various improvements have been made to speed up symbol and executable
image queries.
- Exposed internal mutex variable in Lockable and SharedLockable.
- Fixed problems with Linux systems that do not use glibc.
- Fixed edge case that could corrupt rpmalloc state in the profiled
application.
- Extended ZoneNameF macro with compiler checks for proper printf args.
- Warnings about variable redefinition by nested zone macros are now
supressed by default. The old behavior can be restored by adding the
TRACY_ALLOW_SHADOW_WARNING define during compilation of your program.
- Fixed window icon and dock integration on macOS.
- Fixed edge case with symbols thread not behaving as expected when on
demand mode was used and a rapid reconnection was made.
- Properly defer GPU context events in serial C API.
v0.12.2 (2025-06-25)
--------------------
- Fixed builds made out of git checkout directory.
- Added range limits for flame graph.
- Fixed wayland include paths for distros that use non-standard package
layouts.
- Workarounded MinGW build problems. Safe symbol retrieval is not available
on this platform.
- Fixed Lua bindings when TRACY_NO_CALLSTACK is defined.
v0.12.1 (2025-06-07)
--------------------

View File

@@ -4,7 +4,7 @@
### 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, CUDA.), 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++, 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 graphics/compute APIs: OpenGL, Vulkan, Direct3D 11/12, Metal, OpenCL, CUDA, WebGPU.), 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

View File

@@ -1,7 +1,6 @@
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)
set(NO_STATISTICS ON)
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/version.cmake)
@@ -16,13 +15,22 @@ project(
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/config.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/vendor.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/server.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/GitRef.cmake)
set(PROGRAM_FILES
src/capture.cpp
src/CaptureOutput.cpp
)
add_executable(${PROJECT_NAME} ${PROGRAM_FILES} ${COMMON_FILES} ${SERVER_FILES})
add_git_ref(${PROJECT_NAME})
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})
install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})
add_executable(tracy-capture-daemon src/capturedaemon.cpp src/CaptureOutput.cpp ${COMMON_FILES} ${SERVER_FILES})
add_git_ref(tracy-capture-daemon)
target_link_libraries(tracy-capture-daemon PRIVATE TracyServer TracyGetOpt)
install(TARGETS tracy-capture-daemon DESTINATION ${CMAKE_INSTALL_BINDIR})

View File

@@ -0,0 +1,202 @@
#ifdef _WIN32
# include <io.h>
# include <windows.h>
#else
# include <unistd.h>
#endif
#include <atomic>
#include <chrono>
#include <cstdarg>
#include <cstdio>
#include <cstring>
#include <inttypes.h>
#include <thread>
#include "CaptureOutput.hpp"
#include "../../public/common/TracyProtocol.hpp"
#include "../../public/common/TracyStackFrames.hpp"
#include "../../server/TracyMemory.hpp"
#include "../../server/TracyPrint.hpp"
#include "../../server/TracyWorker.hpp"
static bool s_isTerminal = false;
void InitTerminalDetection()
{
#ifdef _WIN32
s_isTerminal = _isatty( fileno( stdout ) );
#else
s_isTerminal = isatty( fileno( stdout ) );
#endif
}
bool IsTerminal()
{
return s_isTerminal;
}
void AnsiPrintf( const char* ansiEscape, const char* format, ... )
{
if( IsTerminal() )
{
char buf[256];
va_list args;
va_start( args, format );
vsnprintf( buf, sizeof buf, format, args );
va_end( args );
printf( "%s%s" ANSI_RESET, ansiEscape, buf );
}
else
{
va_list args;
va_start( args, format );
vfprintf( stdout, format, args );
va_end( args );
}
}
int WaitForConnection( tracy::Worker& worker )
{
while( !worker.HasData() )
{
const auto handshake = worker.GetHandshakeStatus();
if( handshake == tracy::HandshakeProtocolMismatch )
{
printf( "\nThe client you are trying to connect to uses incompatible protocol version.\nMake sure you are using the same Tracy version on both client and server.\n" );
return 1;
}
if( handshake == tracy::HandshakeNotAvailable )
{
printf( "\nThe client you are trying to connect to is no longer able to sent profiling data,\nbecause another server was already connected to it.\nYou can do the following:\n\n 1. Restart the client application.\n 2. Rebuild the client application with on-demand mode enabled.\n" );
return 2;
}
if( handshake == tracy::HandshakeDropped )
{
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 ) );
}
return 0;
}
void PrintWorkerFailure( tracy::Worker& worker )
{
const auto& failure = worker.GetFailureType();
if( failure == tracy::Worker::Failure::None ) return;
AnsiPrintf( ANSI_RED ANSI_BOLD, "\nInstrumentation failure: %s", tracy::Worker::GetFailureString( failure ) );
auto& fd = worker.GetFailureData();
if( !fd.message.empty() )
{
printf( "\nContext: %s", fd.message.c_str() );
}
if( fd.callstack != 0 )
{
AnsiPrintf( ANSI_BOLD, "\nFailure callstack:\n" );
auto& cs = worker.GetCallstack( fd.callstack );
int fidx = 0;
for( auto& entry : cs )
{
auto frameData = worker.GetCallstackFrame( entry );
if( !frameData )
{
printf( "%3i. %p\n", fidx++, (void*)worker.GetCanonicalPointer( entry ) );
}
else
{
const auto fsz = frameData->size;
for( uint8_t f = 0; f < fsz; f++ )
{
const auto& frame = frameData->data[f];
auto txt = worker.GetString( frame.name );
if( fidx == 0 && f != fsz - 1 )
{
auto test = tracy::s_tracyStackFrames;
bool match = false;
do
{
if( strcmp( txt, *test ) == 0 )
{
match = true;
break;
}
}
while( *++test );
if( match ) continue;
}
if( f == fsz - 1 )
{
printf( "%3i. ", fidx++ );
}
else
{
AnsiPrintf( ANSI_BLACK ANSI_BOLD, "inl. " );
}
AnsiPrintf( ANSI_CYAN, "%s ", txt );
txt = worker.GetString( frame.file );
if( frame.line == 0 )
{
AnsiPrintf( ANSI_YELLOW, "(%s)", txt );
}
else
{
AnsiPrintf( ANSI_YELLOW, "(%s:%" PRIu32 ")", txt, frame.line );
}
if( frameData->imageName.Active() )
{
AnsiPrintf( ANSI_MAGENTA, " %s\n", worker.GetString( frameData->imageName ) );
}
else
{
printf( "\n" );
}
}
}
}
}
}
void PrintCaptureProgress( tracy::Worker& worker, int64_t firstTime, int64_t memoryLimit )
{
if( !IsTerminal() ) return;
auto& lock = worker.GetMbpsDataLock();
lock.lock();
const auto mbps = worker.GetMbpsData().back();
const auto compRatio = worker.GetCompRatio();
const auto netTotal = worker.GetDataTransferred();
const auto queueSize = worker.GetSendQueueSize();
lock.unlock();
const char* unit = "Mbps";
float unitsPerMbps = 1.f;
if( mbps < 0.1f )
{
unit = "Kbps";
unitsPerMbps = 1000.f;
}
AnsiPrintf( ANSI_ERASE_LINE ANSI_CYAN ANSI_BOLD, "\r%7.2f %s", mbps * unitsPerMbps, unit );
printf( " /" );
AnsiPrintf( ANSI_CYAN ANSI_BOLD, "%5.1f%%", compRatio * 100.f );
printf( " =" );
AnsiPrintf( ANSI_YELLOW ANSI_BOLD, "%7.2f Mbps", mbps / compRatio );
printf( " | " );
AnsiPrintf( ANSI_YELLOW, "Tx: " );
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 ) );
}
printf( " | " );
AnsiPrintf( ANSI_RED, "%s", tracy::TimeToString( worker.GetLastTime() - firstTime ) );
printf( " | " );
AnsiPrintf( ANSI_RED ANSI_BOLD, "%s query backlog", tracy::RealToString( queueSize ) );
fflush( stdout );
}

View File

@@ -0,0 +1,33 @@
#ifndef __CAPTUREOUTPUT_HPP__
#define __CAPTUREOUTPUT_HPP__
#include <stdint.h>
#define ANSI_RESET "\033[0m"
#define ANSI_BOLD "\033[1m"
#define ANSI_BLACK "\033[30m"
#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"
namespace tracy { class Worker; }
void InitTerminalDetection();
bool IsTerminal();
#ifdef __GNUC__
[[gnu::format( __printf__, 2, 3 )]]
#endif
void AnsiPrintf( const char* ansiEscape, const char* format, ... );
int WaitForConnection( tracy::Worker& worker );
void PrintWorkerFailure( tracy::Worker& worker );
void PrintCaptureProgress( tracy::Worker& worker, int64_t firstTime, int64_t memoryLimit );
#endif

View File

@@ -1,6 +1,5 @@
#ifdef _WIN32
# include <windows.h>
# include <io.h>
#else
# include <unistd.h>
#endif
@@ -8,21 +7,20 @@
#include <atomic>
#include <chrono>
#include <inttypes.h>
#include <mutex>
#include <signal.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include "../../public/common/TracyProtocol.hpp"
#include "../../public/common/TracyStackFrames.hpp"
#include "../../server/TracyFileWrite.hpp"
#include "../../server/TracyMemory.hpp"
#include "../../server/TracyPrint.hpp"
#include "../../server/TracySysUtil.hpp"
#include "../../server/TracyWorker.hpp"
#include "../../public/common/TracyVersion.hpp"
#include "GitRef.hpp"
#include "CaptureOutput.hpp"
#ifdef _WIN32
# include "../../getopt/getopt.h"
@@ -38,60 +36,12 @@ static std::atomic<bool> s_disconnect { false };
void SigInt( int )
{
// Relaxed order is closest to a traditional `volatile` write.
// We don't need stronger ordering since this signal handler doesn't do
// anything else that would need to be ordered relatively to this.
s_disconnect.store(true, std::memory_order_relaxed);
}
static bool s_isStdoutATerminal = false;
void InitIsStdoutATerminal() {
#ifdef _WIN32
s_isStdoutATerminal = _isatty( fileno( stdout ) );
#else
s_isStdoutATerminal = isatty( fileno( stdout ) );
#endif
}
bool IsStdoutATerminal() { return s_isStdoutATerminal; }
#define ANSI_RESET "\033[0m"
#define ANSI_BOLD "\033[1m"
#define ANSI_BLACK "\033[30m"
#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"
// Like printf, but if stdout is a terminal, prepends the output with
// the given `ansiEscape` and appends ANSI_RESET.
void AnsiPrintf( const char* ansiEscape, const char* format, ... ) {
if( IsStdoutATerminal() )
{
// Prepend ansiEscape and append ANSI_RESET.
char buf[256];
va_list args;
va_start( args, format );
vsnprintf( buf, sizeof buf, format, args );
va_end( args );
printf( "%s%s" ANSI_RESET, ansiEscape, buf );
}
else
{
// Just a normal printf.
va_list args;
va_start( args, format );
vfprintf( stdout, format, args );
va_end( args );
}
}
[[noreturn]] void Usage()
{
printf( "tracy-capture %i.%i.%i / %s\n\n", tracy::Version::Major, tracy::Version::Minor, tracy::Version::Patch, tracy::GitRef );
printf( "Usage: capture -o output.tracy [-a address] [-p port] [-f] [-s seconds] [-m memlimit]\n" );
exit( 1 );
}
@@ -106,7 +56,7 @@ int main( int argc, char** argv )
}
#endif
InitIsStdoutATerminal();
InitTerminalDetection();
bool overwrite = false;
const char* address = "127.0.0.1";
@@ -165,27 +115,9 @@ int main( int argc, char** argv )
printf( "Connecting to %s:%i...", address, port );
fflush( stdout );
tracy::Worker worker( address, port, memoryLimit );
while( !worker.HasData() )
{
const auto handshake = worker.GetHandshakeStatus();
if( handshake == tracy::HandshakeProtocolMismatch )
{
printf( "\nThe client you are trying to connect to uses incompatible protocol version.\nMake sure you are using the same Tracy version on both client and server.\n" );
return 1;
}
if( handshake == tracy::HandshakeNotAvailable )
{
printf( "\nThe client you are trying to connect to is no longer able to sent profiling data,\nbecause another server was already connected to it.\nYou can do the following:\n\n 1. Restart the client application.\n 2. Rebuild the client application with on-demand mode enabled.\n" );
return 2;
}
if( handshake == tracy::HandshakeDropped )
{
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 ) );
}
printf( "\nQueue delay: %s\nTimer resolution: %s\n", tracy::TimeToString( worker.GetDelay() ), tracy::TimeToString( worker.GetResolution() ) );
int result = WaitForConnection( worker );
if( result != 0 ) return result;
printf( "\nTimer resolution: %s\n", tracy::TimeToString( worker.GetResolution() ) );
#ifdef _WIN32
signal( SIGINT, SigInt );
@@ -197,59 +129,18 @@ int main( int argc, char** argv )
#endif
const auto firstTime = worker.GetFirstTime();
auto& lock = worker.GetMbpsDataLock();
const auto t0 = std::chrono::high_resolution_clock::now();
while( worker.IsConnected() )
{
// Relaxed order is sufficient here because `s_disconnect` is only ever
// set by this thread or by the SigInt handler, and that handler does
// nothing else than storing `s_disconnect`.
if( s_disconnect.load( std::memory_order_relaxed ) )
{
worker.Disconnect();
// Relaxed order is sufficient because only this thread ever reads
// this value.
s_disconnect.store(false, std::memory_order_relaxed );
break;
}
lock.lock();
const auto mbps = worker.GetMbpsData().back();
const auto compRatio = worker.GetCompRatio();
const auto netTotal = worker.GetDataTransferred();
lock.unlock();
// Output progress info only if destination is a TTY to avoid bloating
// log files (so this is not just about usage of ANSI color codes).
if( IsStdoutATerminal() )
{
const char* unit = "Mbps";
float unitsPerMbps = 1.f;
if( mbps < 0.1f )
{
unit = "Kbps";
unitsPerMbps = 1000.f;
}
AnsiPrintf( ANSI_ERASE_LINE ANSI_CYAN ANSI_BOLD, "\r%7.2f %s", mbps * unitsPerMbps, unit );
printf( " /");
AnsiPrintf( ANSI_CYAN ANSI_BOLD, "%5.1f%%", compRatio * 100.f );
printf( " =");
AnsiPrintf( ANSI_YELLOW ANSI_BOLD, "%7.2f Mbps", mbps / compRatio );
printf( " | ");
AnsiPrintf( ANSI_YELLOW, "Tx: ");
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 ) );
}
printf( " | ");
AnsiPrintf( ANSI_RED, "%s", tracy::TimeToString( worker.GetLastTime() - firstTime ) );
fflush( stdout );
}
PrintCaptureProgress( worker, firstTime, memoryLimit );
std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
if( seconds != -1 )
@@ -257,90 +148,13 @@ int main( int argc, char** argv )
const auto dur = std::chrono::high_resolution_clock::now() - t0;
if( std::chrono::duration_cast<std::chrono::seconds>(dur).count() >= seconds )
{
// Relaxed order is sufficient because only this thread ever reads
// this value.
s_disconnect.store(true, std::memory_order_relaxed );
}
}
}
const auto t1 = std::chrono::high_resolution_clock::now();
const auto& failure = worker.GetFailureType();
if( failure != tracy::Worker::Failure::None )
{
AnsiPrintf( ANSI_RED ANSI_BOLD, "\nInstrumentation failure: %s", tracy::Worker::GetFailureString( failure ) );
auto& fd = worker.GetFailureData();
if( !fd.message.empty() )
{
printf( "\nContext: %s", fd.message.c_str() );
}
if( fd.callstack != 0 )
{
AnsiPrintf( ANSI_BOLD, "\nFailure callstack:\n" );
auto& cs = worker.GetCallstack( fd.callstack );
int fidx = 0;
for( auto& entry : cs )
{
auto frameData = worker.GetCallstackFrame( entry );
if( !frameData )
{
printf( "%3i. %p\n", fidx++, (void*)worker.GetCanonicalPointer( entry ) );
}
else
{
const auto fsz = frameData->size;
for( uint8_t f=0; f<fsz; f++ )
{
const auto& frame = frameData->data[f];
auto txt = worker.GetString( frame.name );
if( fidx == 0 && f != fsz-1 )
{
auto test = tracy::s_tracyStackFrames;
bool match = false;
do
{
if( strcmp( txt, *test ) == 0 )
{
match = true;
break;
}
}
while( *++test );
if( match ) continue;
}
if( f == fsz-1 )
{
printf( "%3i. ", fidx++ );
}
else
{
AnsiPrintf( ANSI_BLACK ANSI_BOLD, "inl. " );
}
AnsiPrintf( ANSI_CYAN, "%s ", txt );
txt = worker.GetString( frame.file );
if( frame.line == 0 )
{
AnsiPrintf( ANSI_YELLOW, "(%s)", txt );
}
else
{
AnsiPrintf( ANSI_YELLOW, "(%s:%" PRIu32 ")", txt, frame.line );
}
if( frameData->imageName.Active() )
{
AnsiPrintf( ANSI_MAGENTA, " %s\n", worker.GetString( frameData->imageName ) );
}
else
{
printf( "\n" );
}
}
}
}
}
}
PrintWorkerFailure( worker );
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() ),

View File

@@ -0,0 +1,438 @@
#ifdef _WIN32
# include <windows.h>
#else
# include <unistd.h>
#endif
#include <atomic>
#include <chrono>
#include <cstdint>
#include <cstring>
#include <filesystem>
#include <map>
#include <mutex>
#include <signal.h>
#include <string>
#include <thread>
#include <unordered_set>
#include <vector>
#include "../../getopt/getopt.h"
#include "../../public/common/TracySocket.hpp"
#include "../../public/common/TracyVersion.hpp"
#include "../../server/TracyBroadcast.hpp"
#include "../../server/TracyFileWrite.hpp"
#include "../../server/TracyMemory.hpp"
#include "../../server/TracyPrint.hpp"
#include "../../server/TracySysUtil.hpp"
#include "../../server/TracyWorker.hpp"
#include "GitRef.hpp"
#include "CaptureOutput.hpp"
static std::atomic<bool> g_shutdown{false};
static std::mutex g_clientsMutex;
static uint16_t g_listenPort = 8086;
static std::string g_filterName;
static int g_filterPort = 0;
static int64_t g_memoryLimit = -1;
void SigInt( int )
{
g_shutdown.store( true, std::memory_order_relaxed );
}
struct ClientStats
{
std::atomic<float> mbps{0};
std::atomic<int64_t> txBytes{0};
std::atomic<int64_t> memUsage{0};
std::atomic<int64_t> firstTime{-1};
};
struct ClientSession
{
std::string id;
std::string programName;
std::string address;
uint16_t port;
std::string outputFile;
std::thread thread;
std::atomic<bool> active{true};
std::atomic<bool> finished{false};
ClientStats stats;
std::atomic<uint64_t> fileSize{0};
};
static std::map<std::string, ClientSession*> g_clients;
static std::unordered_set<std::string> g_outputFiles;
[[noreturn]] void Usage()
{
printf( "tracy-capture-daemon %i.%i.%i / %s\n\n", tracy::Version::Major, tracy::Version::Minor, tracy::Version::Patch, tracy::GitRef );
printf( "Usage: tracy-capture-daemon -o <output_dir> [options]\n\n" );
printf( "Options:\n" );
printf( " -o, --output <dir> Output directory (required)\n" );
printf( " -p, --port <port> UDP listen port (default: 8086)\n" );
printf( " -m, --memory <limit> Memory limit per client as %% of system RAM\n" );
printf( " --filter-name <pattern> Only capture clients matching program name\n" );
printf( " --filter-port <port> Only capture clients with specific data port\n" );
printf( " -h, --help Show this help\n" );
printf( " -V, --version Show version information\n" );
exit( 1 );
}
std::string SanitizeName( const std::string& name )
{
std::string result;
for( char c : name )
{
if( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) || ( c >= '0' && c <= '9' ) || c == '_' || c == '-' )
{
result += c;
}
else if( c == ' ' || c == '\t' )
{
result += '_';
}
}
if( result.empty() ) result = "unknown";
return result;
}
std::string GenerateOutputFilename( const std::string& outputDir, const std::string& programName, const std::string& address, uint16_t port )
{
std::string base = SanitizeName( programName ) + "_" + address + "_" + std::to_string( port );
std::string candidate = base + ".tracy";
std::string path = outputDir + "/" + candidate;
int idx = 0;
while( g_outputFiles.count( path ) || std::filesystem::exists( path ) )
{
idx++;
candidate = base + "_" + std::to_string( idx ) + ".tracy";
path = outputDir + "/" + candidate;
}
g_outputFiles.insert( path );
return path;
}
bool MatchesFilters( const tracy::BroadcastMessage& msg )
{
if( !g_filterName.empty() )
{
if( strstr( msg.programName, g_filterName.c_str() ) == nullptr )
{
return false;
}
}
if( g_filterPort > 0 && msg.listenPort != g_filterPort )
{
return false;
}
return true;
}
void CaptureThread( ClientSession* session, const std::string& address, uint16_t port, int64_t memoryLimit, const std::string& outputFile )
{
printf( "Connecting to %s:%u...\n", address.c_str(), port );
fflush( stdout );
tracy::Worker worker( address.c_str(), port, memoryLimit );
int result = WaitForConnection( worker );
if( result != 0 )
{
session->active = false;
session->finished = true;
return;
}
printf( "Connected to %s (%s:%u)\n", session->programName.c_str(), address.c_str(), port );
int64_t firstTime = worker.GetFirstTime();
session->stats.firstTime = firstTime;
while( session->active && worker.IsConnected() )
{
auto& lock = worker.GetMbpsDataLock();
lock.lock();
float mbps = worker.GetMbpsData().back();
int64_t txTotal = worker.GetDataTransferred();
lock.unlock();
session->stats.mbps = mbps;
session->stats.txBytes = txTotal;
session->stats.memUsage = tracy::memUsage.load( std::memory_order_relaxed );
std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
}
printf( "\nSaving %s...", outputFile.c_str() );
fflush( stdout );
auto file = std::unique_ptr<tracy::FileWrite>( tracy::FileWrite::Open( outputFile.c_str(), tracy::FileCompression::Zstd, 3, 4 ) );
if( file )
{
worker.Write( *file, false );
file->Finish();
auto stats = file->GetCompressionStatistics();
session->fileSize = stats.second;
AnsiPrintf( ANSI_GREEN ANSI_BOLD, " done!\n" );
}
else
{
AnsiPrintf( ANSI_RED ANSI_BOLD, " failed!\n" );
}
session->finished = true;
session->active = false;
}
void RefreshDisplay( const std::string& listenAddr )
{
if( !IsTerminal() ) return;
printf( "\033[H\033[J" );
size_t clientCount = 0;
{
std::lock_guard<std::mutex> lock( g_clientsMutex );
clientCount = g_clients.size();
}
printf( "[%zu client%s] Listening on %s:%u... Press Ctrl+C to stop\n\n", clientCount, clientCount == 1 ? "" : "s", listenAddr.c_str(), g_listenPort );
int idx = 1;
float totalMbps = 0;
int64_t totalTx = 0;
int64_t totalMem = 0;
{
std::lock_guard<std::mutex> lock( g_clientsMutex );
for( auto& [id, session] : g_clients )
{
printf( " [%d] %s @ %s:%u ", idx, session->programName.c_str(), session->address.c_str(), session->port );
if( session->finished )
{
printf( "finished (" );
printf( "%s", tracy::MemSizeToString( session->fileSize.load() ) );
printf( ")" );
}
else if( session->active )
{
float mbps = session->stats.mbps.load();
int64_t tx = session->stats.txBytes.load();
int64_t mem = session->stats.memUsage.load();
int64_t firstTime = session->stats.firstTime.load();
printf( "%.1f Mbps | %s | %s", mbps, tracy::MemSizeToString( tx ), tracy::MemSizeToString( mem ) );
totalMbps += mbps;
totalTx += tx;
totalMem += mem;
}
else
{
printf( "connecting..." );
}
printf( "\n" );
idx++;
}
}
printf( "\nTotal: %.1f Mbps | %s | Mem: %s", totalMbps, tracy::MemSizeToString( totalTx ), tracy::MemSizeToString( totalMem ) );
fflush( stdout );
}
void PrintSummary()
{
printf( "\n\n=== Capture Summary ===\n" );
std::lock_guard<std::mutex> lock( g_clientsMutex );
int idx = 1;
int64_t totalSize = 0;
for( auto& [id, session] : g_clients )
{
int64_t size = session->fileSize.load();
totalSize += size;
printf( " [%d] %s @ %s:%u -> %s (%s)\n", idx++, session->programName.c_str(), session->address.c_str(), session->port, session->outputFile.c_str(), tracy::MemSizeToString( size ) );
}
printf( "\nTotal: %zu files, %s\n", g_clients.size(), tracy::MemSizeToString( totalSize ) );
}
int main( int argc, char** argv )
{
#ifdef _WIN32
if( !AttachConsole( ATTACH_PARENT_PROCESS ) )
{
AllocConsole();
SetConsoleMode( GetStdHandle( STD_OUTPUT_HANDLE ), 0x07 );
}
#endif
std::string outputDir;
static struct option longOptions[] = {
{ "output", required_argument, nullptr, 'o' },
{ "port", required_argument, nullptr, 'p' },
{ "memory", required_argument, nullptr, 'm' },
{ "filter-name", required_argument, nullptr, 1 },
{ "filter-port", required_argument, nullptr, 2 },
{ "help", no_argument, nullptr, 'h' },
{ "version", no_argument, nullptr, 'V' },
{ nullptr, 0, nullptr, 0 }
};
int c;
while( ( c = getopt_long( argc, argv, "o:p:m:hV", longOptions, nullptr ) ) != -1 )
{
switch( c )
{
case 'o':
outputDir = optarg;
break;
case 'p':
g_listenPort = atoi( optarg );
break;
case 'm':
g_memoryLimit = std::clamp( atoll( optarg ), 1ll, 999ll ) * tracy::GetPhysicalMemorySize() / 100;
break;
case 1:
g_filterName = optarg;
break;
case 2:
g_filterPort = atoi( optarg );
break;
case 'h':
Usage();
break;
case 'V':
printf( "tracy-capture-daemon %i.%i.%i / %s\n", tracy::Version::Major, tracy::Version::Minor, tracy::Version::Patch, tracy::GitRef );
exit( 0 );
default:
Usage();
break;
}
}
if( outputDir.empty() )
{
fprintf( stderr, "Error: Output directory is required (-o)\n\n" );
Usage();
}
std::filesystem::create_directories( outputDir );
InitTerminalDetection();
#ifdef _WIN32
signal( SIGINT, SigInt );
#else
struct sigaction sigint, oldsigint;
memset( &sigint, 0, sizeof( sigint ) );
sigint.sa_handler = SigInt;
sigaction( SIGINT, &sigint, &oldsigint );
#endif
tracy::UdpListen udpSocket;
if( !udpSocket.Listen( g_listenPort ) )
{
fprintf( stderr, "Error: Failed to listen on port %u\n", g_listenPort );
return 1;
}
printf( "Listening on 0.0.0.0:%u... Press Ctrl+C to stop\n", g_listenPort );
printf( "Output directory: %s\n", outputDir.c_str() );
const std::string listenAddr = "0.0.0.0";
auto lastDisplay = std::chrono::steady_clock::now();
while( !g_shutdown )
{
tracy::IpAddress clientAddr;
size_t len;
const char* msg = udpSocket.Read( len, clientAddr, 100 );
if( msg )
{
auto parsed = tracy::ParseBroadcastMessage( msg, len );
if( parsed )
{
std::string clientId = std::to_string( parsed->pid ) + "_" + clientAddr.GetText() + "_" + std::to_string( parsed->listenPort );
bool isNew = false;
{
std::lock_guard<std::mutex> lock( g_clientsMutex );
isNew = g_clients.find( clientId ) == g_clients.end();
}
if( isNew && MatchesFilters( *parsed ) )
{
std::string addressStr = clientAddr.GetText();
std::string outputFile = GenerateOutputFilename( outputDir, parsed->programName, addressStr, parsed->listenPort );
auto session = new ClientSession();
session->id = clientId;
session->programName = parsed->programName;
session->address = addressStr;
session->port = parsed->listenPort;
session->outputFile = outputFile;
session->active = true;
{
std::lock_guard<std::mutex> lock( g_clientsMutex );
g_clients[clientId] = session;
}
session->thread = std::thread( CaptureThread, session, addressStr, parsed->listenPort, g_memoryLimit, outputFile );
}
}
}
auto now = std::chrono::steady_clock::now();
if( std::chrono::duration_cast<std::chrono::milliseconds>( now - lastDisplay ).count() >= 100 )
{
RefreshDisplay( listenAddr );
lastDisplay = now;
}
}
printf( "\n\nShutting down... waiting for %zu client(s) to finish\n", g_clients.size() );
{
std::lock_guard<std::mutex> lock( g_clientsMutex );
for( auto& [id, session] : g_clients )
{
session->active = false;
}
}
{
std::lock_guard<std::mutex> lock( g_clientsMutex );
for( auto& [id, session] : g_clients )
{
if( session->thread.joinable() )
{
session->thread.join();
}
}
}
PrintSummary();
{
std::lock_guard<std::mutex> lock( g_clientsMutex );
for( auto& [id, session] : g_clients )
{
delete session;
}
g_clients.clear();
}
return 0;
}

37
cmake/GitRef.cmake Normal file
View File

@@ -0,0 +1,37 @@
function(add_git_ref target)
if(NOT DEFINED GIT_REV)
set(GIT_REV "HEAD")
endif()
get_property(_git_ref_created GLOBAL PROPERTY _GIT_REF_CREATED)
if(NOT _git_ref_created)
set_property(GLOBAL PROPERTY _GIT_REF_CREATED TRUE)
find_package(Git)
set_property(GLOBAL PROPERTY _GIT_FOUND "${Git_FOUND}")
if(Git_FOUND)
add_custom_target(git-ref
COMMAND ${CMAKE_COMMAND} -E echo "#pragma once" > GitRef.hpp.tmp
COMMAND ${GIT_EXECUTABLE} -C ${CMAKE_CURRENT_SOURCE_DIR} log -1 "--format=namespace tracy { static inline const char* GitRef = %x22%h%x22; }" ${GIT_REV} >> GitRef.hpp.tmp || echo "namespace tracy { static inline const char* GitRef = \"unknown\"; }" >> GitRef.hpp.tmp
COMMAND ${CMAKE_COMMAND} -E copy_if_different GitRef.hpp.tmp GitRef.hpp
BYPRODUCTS GitRef.hpp GitRef.hpp.tmp
VERBATIM
)
else()
message(WARNING "git not found, using 'unknown' as git ref.")
add_custom_command(
OUTPUT GitRef.hpp
COMMAND ${CMAKE_COMMAND} -E echo "#pragma once" > GitRef.hpp
COMMAND ${CMAKE_COMMAND} -E echo "namespace tracy { static inline const char* GitRef = \"unknown\"; }" >> GitRef.hpp
VERBATIM
)
endif()
endif()
target_include_directories(${target} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
get_property(_git_found GLOBAL PROPERTY _GIT_FOUND)
if(_git_found)
add_dependencies(${target} git-ref)
else()
target_sources(${target} PUBLIC GitRef.hpp)
endif()
endfunction()

View File

@@ -1,8 +1,15 @@
include(${CMAKE_CURRENT_LIST_DIR}/options.cmake)
set_option(NO_ISA_EXTENSIONS "Disable ISA extensions (don't pass -march=native or -mcpu=native to the compiler)" OFF)
set_option(NO_LTO "Disable interprocedural optimization (LTO)" OFF)
set_option(NO_MOLD_LINKER "Disable mold linker (use default linker)" OFF)
set_option(NO_CCACHE "Disable ccache acceleration" OFF)
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)
if(COMPILER_SUPPORTS_MCPU_NATIVE)
add_compile_options(-mcpu=native)
endif()
else()
@@ -24,24 +31,33 @@ endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "15")
message(FATAL_ERROR "Apple Clang 15 or newer is required.")
elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "16")
# AppleClang 15 has issues with to_chars in <chrono> if target is too old
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-mmacosx-version-min=13.3>)
endif()
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)
# /MP is MSVC-specific for multi-processor compilation
if(MSVC)
add_compile_options(/MP)
endif()
endif()
if(EMSCRIPTEN)
add_compile_options(-pthread -DIMGUI_IMPL_OPENGL_ES2)
endif()
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT EMSCRIPTEN)
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT EMSCRIPTEN AND NOT NO_LTO)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT NO_MOLD_LINKER)
find_program(MOLD_LINKER mold)
if(MOLD_LINKER)
set(CMAKE_LINKER_TYPE "MOLD")
@@ -51,10 +67,12 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_SYSTEM_NAME STREQUAL "Linux"
endif()
endif()
find_program(CCACHE ccache)
if(CCACHE)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
if(NOT NO_CCACHE)
find_program(CCACHE ccache)
if(CCACHE)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
endif()
endif()
file(GENERATE OUTPUT .gitignore CONTENT "*")

View File

@@ -1,8 +1,8 @@
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;
diff --git i/backends/imgui_impl_opengl3_loader.h w/backends/imgui_impl_opengl3_loader.h
index 4ca0536..a1ff572 100644
--- i/backends/imgui_impl_opengl3_loader.h
+++ w/backends/imgui_impl_opengl3_loader.h
@@ -180,6 +180,7 @@ typedef khronos_uint8_t GLubyte;
#define GL_VERSION 0x1F02
#define GL_EXTENSIONS 0x1F03
#define GL_LINEAR 0x2601
@@ -10,7 +10,7 @@ index d6ffa5a2d..e48372c64 100644
#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);
@@ -244,8 +245,10 @@ GLAPI void APIENTRY glGenTextures (GLsizei n, GLuint *textures);
#define GL_TEXTURE0 0x84C0
#define GL_ACTIVE_TEXTURE 0x84E0
typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
@@ -21,16 +21,16 @@ index d6ffa5a2d..e48372c64 100644
#endif
#endif /* GL_VERSION_1_3 */
#ifndef GL_VERSION_1_4
@@ -478,7 +481,7 @@ GL3W_API GL3WglProc imgl3wGetProcAddress(const char *proc);
@@ -481,7 +484,7 @@ GL3W_API GL3WglProc imgl3wGetProcAddress(const char *proc);
/* gl3w internal state */
union ImGL3WProcs {
- GL3WglProc ptr[59];
+ GL3WglProc ptr[60];
- GL3WglProc ptr[63];
+ GL3WglProc ptr[64];
struct {
PFNGLACTIVETEXTUREPROC ActiveTexture;
PFNGLATTACHSHADERPROC AttachShader;
@@ -494,6 +497,7 @@ union ImGL3WProcs {
@@ -497,6 +500,7 @@ union ImGL3WProcs {
PFNGLCLEARPROC Clear;
PFNGLCLEARCOLORPROC ClearColor;
PFNGLCOMPILESHADERPROC CompileShader;
@@ -38,7 +38,7 @@ index d6ffa5a2d..e48372c64 100644
PFNGLCREATEPROGRAMPROC CreateProgram;
PFNGLCREATESHADERPROC CreateShader;
PFNGLDELETEBUFFERSPROC DeleteBuffers;
@@ -559,6 +563,7 @@ GL3W_API extern union ImGL3WProcs imgl3wProcs;
@@ -563,6 +567,7 @@ GL3W_API extern union ImGL3WProcs imgl3wProcs;
#define glClear imgl3wProcs.gl.Clear
#define glClearColor imgl3wProcs.gl.ClearColor
#define glCompileShader imgl3wProcs.gl.CompileShader
@@ -46,7 +46,7 @@ index d6ffa5a2d..e48372c64 100644
#define glCreateProgram imgl3wProcs.gl.CreateProgram
#define glCreateShader imgl3wProcs.gl.CreateShader
#define glDeleteBuffers imgl3wProcs.gl.DeleteBuffers
@@ -854,6 +859,7 @@ static const char *proc_names[] = {
@@ -859,6 +864,7 @@ static const char *proc_names[] = {
"glClear",
"glClearColor",
"glCompileShader",

View File

@@ -0,0 +1,13 @@
diff --git a/backends/imgui_impl_opengl3.cpp b/backends/imgui_impl_opengl3.cpp
index a9e32b7ac..2cdbc4812 100644
--- a/backends/imgui_impl_opengl3.cpp
+++ b/backends/imgui_impl_opengl3.cpp
@@ -1069,7 +1069,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
bd->HasPolygonMode = (!bd->GlProfileIsES2 && !bd->GlProfileIsES3);
#endif
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
- bd->HasBindSampler = (bd->GlVersion >= 330 || bd->GlProfileIsES3);
+ //bd->HasBindSampler = (bd->GlVersion >= 330 || bd->GlProfileIsES3);
#endif
bd->HasClipOrigin = (bd->GlVersion >= 450);
#ifdef IMGUI_IMPL_OPENGL_HAS_EXTENSIONS

48
cmake/options.cmake Normal file
View File

@@ -0,0 +1,48 @@
# Reusable option macros for Tracy CMake projects
#
# Usage:
# set_option(OPTION_NAME "Help text" ON/OFF [TARGET]) - for boolean options
# set_option_value(VAR_NAME "Help text" "value" [TARGET]) - for value options (CACHE STRING)
# set_option_value_as_string(VAR_NAME "Help text" "value" [TARGET]) - for value options as C string literals
#
# [TARGET] is optional and specifies a target to which the option will
# be added as a compile definition (e.g., -DOPTION_NAME or -DVAR_NAME=value).
# Boolean option (ON/OFF).
macro(set_option option help value)
option(${option} ${help} ${value})
if(${option})
message(STATUS "${option}: ON")
if(${ARGC} GREATER 3)
target_compile_definitions(${ARGV3} PUBLIC ${option})
endif()
else()
message(STATUS "${option}: OFF")
endif()
endmacro()
# Value option (string/number).
macro(set_option_value var help default)
set(${var} ${default} CACHE STRING "${help}")
if(${var})
message(STATUS "${var}: ${${var}}")
if(${ARGC} GREATER 3)
target_compile_definitions(${ARGV3} PUBLIC ${var}=${${var}})
endif()
else()
message(STATUS "${var}: (not set)")
endif()
endmacro()
# Value option embedded as a C string literal (VAR="value").
macro(set_option_value_as_string var help default)
set(${var} ${default} CACHE STRING "${help}")
if(${var})
message(STATUS "${var}: ${${var}}")
if(${ARGC} GREATER 3)
target_compile_definitions(${ARGV3} PUBLIC "${var}=\"${${var}}\"")
endif()
else()
message(STATUS "${var}: (not set)")
endif()
endmacro()

View File

@@ -0,0 +1,14 @@
diff --git i/include/ppqsort/parallel/cpp/thread_pool.h w/include/ppqsort/parallel/cpp/thread_pool.h
--- i/include/ppqsort/parallel/cpp/thread_pool.h
+++ w/include/ppqsort/parallel/cpp/thread_pool.h
@@ -134,7 +134,9 @@ namespace ppqsort::impl::cpp {
alignas(parameters::cacheline_size) std::atomic<std::size_t> pending_tasks_{0};
alignas(parameters::cacheline_size) std::atomic<std::size_t> total_tasks_{0};
alignas(parameters::cacheline_size) std::atomic<bool> to_stop_{false};
- std::binary_semaphore threads_done_semaphore_{0}; // used to wait for all tasks to finish
+ // counting_semaphore: multiple workers may concurrently observe total_tasks_ == 0
+ // and call release(); a binary_semaphore would assert when the count exceeds 1.
+ std::counting_semaphore<> threads_done_semaphore_{0};
std::mutex mtx_priority_;
bool stopped = false;
};

View File

@@ -14,6 +14,7 @@ list(TRANSFORM TRACY_COMMON_SOURCES PREPEND "${TRACY_COMMON_DIR}/")
set(TRACY_SERVER_DIR ${CMAKE_CURRENT_LIST_DIR}/../server)
set(TRACY_SERVER_SOURCES
TracyBroadcast.cpp
TracyMemory.cpp
TracyMmap.cpp
TracyPrint.cpp

39
cmake/tidy-cmake.patch Normal file
View File

@@ -0,0 +1,39 @@
diff --git i/CMakeLists.txt w/CMakeLists.txt
index 8efec25..c1d101e 100644
--- i/CMakeLists.txt
+++ w/CMakeLists.txt
@@ -17,7 +17,7 @@
# @date Consult git log.
##############################################################################
-cmake_minimum_required (VERSION 2.8.12)
+cmake_minimum_required (VERSION 3.10)
set(LIB_NAME tidy)
set(LIBTIDY_DESCRIPTION "${LIB_NAME} - HTML syntax checker")
@@ -528,6 +528,7 @@ if (UNIX AND SUPPORT_CONSOLE_APP)
# Run the built EXE to generate xml output .
add_custom_command(
+ POST_BUILD
TARGET man
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${LIB_NAME} -xml-help > ${TIDYHELP}
COMMENT "Generate ${TIDYHELP}"
@@ -536,6 +537,7 @@ if (UNIX AND SUPPORT_CONSOLE_APP)
# Run the built EXE to generate more xml output.
add_custom_command(
+ POST_BUILD
TARGET man
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${LIB_NAME} -xml-config > ${TIDYCONFIG}
COMMENT "Generate ${TIDYCONFIG}"
@@ -544,8 +546,8 @@ if (UNIX AND SUPPORT_CONSOLE_APP)
# Run xsltproc to generate the install files.
add_custom_command(
+ POST_BUILD
TARGET man
- DEPENDS ${TIDYHELP}
COMMAND xsltproc ARGS ${TIDY1XSL} ${TIDYHELP} > ${CMAKE_CURRENT_BINARY_DIR}/${TIDY_MANFILE}
COMMENT "Generate ${TIDY_MANFILE}"
VERBATIM

View File

@@ -11,6 +11,8 @@ 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)
option(DOWNLOAD_LIBCURL "Force download libcURL" OFF)
option(DOWNLOAD_PUGIXML "Force download pugixml" OFF)
# capstone
@@ -24,10 +26,11 @@ else()
CPMAddPackage(
NAME capstone
GITHUB_REPOSITORY capstone-engine/capstone
GIT_TAG 6.0.0-Alpha1
GIT_TAG 6.0.0-Alpha9
OPTIONS
"CAPSTONE_X86_ATT_DISABLE ON"
"CAPSTONE_ALPHA_SUPPORT OFF"
"CAPSTONE_ARC_SUPPORT OFF"
"CAPSTONE_HPPA_SUPPORT OFF"
"CAPSTONE_LOONGARCH_SUPPORT OFF"
"CAPSTONE_M680X_SUPPORT OFF"
@@ -52,7 +55,7 @@ else()
)
add_library(TracyCapstone INTERFACE)
target_include_directories(TracyCapstone INTERFACE ${capstone_SOURCE_DIR}/include/capstone)
target_link_libraries(TracyCapstone INTERFACE capstone)
target_link_libraries(TracyCapstone INTERFACE capstone_static)
endif()
# GLFW
@@ -91,7 +94,7 @@ else()
CPMAddPackage(
NAME freetype
GITHUB_REPOSITORY freetype/freetype
GIT_TAG VER-2-13-3
GIT_TAG VER-2-14-3
OPTIONS
"FT_DISABLE_HARFBUZZ ON"
"FT_WITH_HARFBUZZ OFF"
@@ -134,11 +137,12 @@ target_include_directories(TracyGetOpt PUBLIC ${GETOPT_DIR})
CPMAddPackage(
NAME ImGui
GITHUB_REPOSITORY ocornut/imgui
GIT_TAG v1.91.9b-docking
GIT_TAG v1.92.8-docking
DOWNLOAD_ONLY TRUE
PATCHES
"${CMAKE_CURRENT_LIST_DIR}/imgui-emscripten.patch"
"${CMAKE_CURRENT_LIST_DIR}/imgui-loader.patch"
"${CMAKE_CURRENT_LIST_DIR}/imgui-no-samplers.patch"
)
set(IMGUI_SOURCES
@@ -157,9 +161,16 @@ 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")
target_compile_definitions(TracyImGui PUBLIC "IMGUI_USE_WCHAR32")
#target_compile_definitions(TracyImGui PUBLIC "IMGUI_DISABLE_OBSOLETE_FUNCTIONS")
if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND LEGACY)
find_package(X11 REQUIRED)
target_link_libraries(TracyImGui PUBLIC ${X11_LIBRARIES})
endif()
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions(TracyImGui PRIVATE "IMGUI_DISABLE_DEBUG_TOOLS")
target_compile_definitions(TracyImGui PRIVATE "IMGUI_DISABLE_DEBUG_TOOLS" "IMGUI_DISABLE_DEMO_WINDOWS")
endif()
# NFD
@@ -174,7 +185,7 @@ if(NOT NO_FILESELECTOR AND NOT EMSCRIPTEN)
CPMAddPackage(
NAME nfd
GITHUB_REPOSITORY btzy/nativefiledialog-extended
GIT_TAG v1.2.1
GIT_TAG v1.3.0
EXCLUDE_FROM_ALL TRUE
OPTIONS
"NFD_PORTAL ${NFD_PORTAL}"
@@ -186,8 +197,111 @@ endif()
CPMAddPackage(
NAME PPQSort
GITHUB_REPOSITORY GabTux/PPQSort
VERSION 1.0.5
VERSION 1.0.6
PATCHES
"${CMAKE_CURRENT_LIST_DIR}/ppqsort-nodebug.patch"
"${CMAKE_CURRENT_LIST_DIR}/ppqsort-semaphore.patch"
EXCLUDE_FROM_ALL TRUE
)
# json
CPMAddPackage(
NAME json
GITHUB_REPOSITORY nlohmann/json
GIT_TAG v3.12.0
EXCLUDE_FROM_ALL TRUE
)
# md4c
CPMAddPackage(
NAME md4c
GITHUB_REPOSITORY mity/md4c
GIT_TAG 755ce49acdc7cd682d4502b4796db5ed6a1230fb
OPTIONS
"BUILD_SHARED_LIBS OFF"
EXCLUDE_FROM_ALL TRUE
)
if(NOT EMSCRIPTEN)
# base64
set(BUILD_SHARED_LIBS_SAVE ${BUILD_SHARED_LIBS})
set(BUILD_SHARED_LIBS OFF)
CPMAddPackage(
NAME base64
GITHUB_REPOSITORY aklomp/base64
GIT_TAG v0.5.2
OPTIONS
"BASE64_BUILD_CLI OFF"
"BASE64_WITH_OpenMP OFF"
EXCLUDE_FROM_ALL TRUE
)
set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_SAVE})
# tidy
CPMAddPackage(
NAME tidy
GITHUB_REPOSITORY htacg/tidy-html5
GIT_TAG 5.8.0
PATCHES
"${CMAKE_CURRENT_LIST_DIR}/tidy-cmake.patch"
EXCLUDE_FROM_ALL TRUE
)
# usearch
CPMAddPackage(
NAME usearch
GITHUB_REPOSITORY unum-cloud/usearch
GIT_TAG v2.25.2
EXCLUDE_FROM_ALL TRUE
)
# pugixml
pkg_check_modules(PUGIXML pugixml)
if (PUGIXML_FOUND AND NOT DOWNLOAD_PUGIXML)
add_library(TracyPugixml INTERFACE)
target_include_directories(TracyPugixml INTERFACE ${PUGIXML_INCLUDE_DIRS})
target_link_libraries(TracyPugixml INTERFACE ${PUGIXML_LINK_LIBRARIES})
else()
CPMAddPackage(
NAME pugixml
GITHUB_REPOSITORY zeux/pugixml
GIT_TAG v1.16
EXCLUDE_FROM_ALL TRUE
)
add_library(TracyPugixml INTERFACE)
target_link_libraries(TracyPugixml INTERFACE pugixml)
endif()
# libcurl
pkg_check_modules(LIBCURL libcurl>=7.87.0)
if (LIBCURL_FOUND AND NOT DOWNLOAD_LIBCURL)
add_library(TracyLibcurl INTERFACE)
target_include_directories(TracyLibcurl INTERFACE ${LIBCURL_INCLUDE_DIRS})
target_link_libraries(TracyLibcurl INTERFACE ${LIBCURL_LINK_LIBRARIES})
else()
CPMAddPackage(
NAME libcurl
GITHUB_REPOSITORY curl/curl
GIT_TAG curl-8_20_0
OPTIONS
"BUILD_STATIC_LIBS ON"
"BUILD_SHARED_LIBS OFF"
"HTTP_ONLY ON"
"CURL_ZSTD OFF"
"CURL_USE_LIBPSL OFF"
EXCLUDE_FROM_ALL TRUE
)
add_library(TracyLibcurl INTERFACE)
target_link_libraries(TracyLibcurl INTERFACE libcurl_static)
target_include_directories(TracyLibcurl INTERFACE ${libcurl_SOURCE_DIR}/include)
endif()
endif()

View File

@@ -1,7 +1,5 @@
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)
@@ -17,12 +15,14 @@ project(
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/config.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/vendor.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/server.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/GitRef.cmake)
set(PROGRAM_FILES
src/csvexport.cpp
)
add_executable(${PROJECT_NAME} ${PROGRAM_FILES} ${COMMON_FILES} ${SERVER_FILES})
add_git_ref(${PROJECT_NAME})
target_link_libraries(${PROJECT_NAME} PRIVATE TracyServer TracyGetOpt)
set_property(DIRECTORY ${CMAKE_CURRENT_LIST_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME})

View File

@@ -16,22 +16,27 @@
#include "../../server/TracyFileRead.hpp"
#include "../../server/TracyWorker.hpp"
#include "../../getopt/getopt.h"
#include "../../public/common/TracyVersion.hpp"
#include "GitRef.hpp"
void print_usage_exit(int e)
{
fprintf(stderr, "tracy-csvexport %i.%i.%i / %s\n\n", tracy::Version::Major, tracy::Version::Minor, tracy::Version::Patch, tracy::GitRef);
fprintf(stderr, "Extract statistics from a trace to a CSV format\n");
fprintf(stderr, "Usage:\n");
fprintf(stderr, " extract [OPTION...] <trace file>\n");
fprintf(stderr, "\n");
fprintf(stderr, " -h, --help Print usage\n");
fprintf(stderr, " -f, --filter arg Filter zone names (default: "")\n");
fprintf(stderr, " -s, --sep arg CSV separator (default: ,)\n");
fprintf(stderr, " -c, --case Case sensitive filtering\n");
fprintf(stderr, " -e, --self Get self times\n");
fprintf(stderr, " -u, --unwrap Report each cpu zone event\n");
fprintf(stderr, " -g, --gpu Report each gpu zone event\n" );
fprintf(stderr, " -m, --messages Report only messages\n");
fprintf(stderr, " -p, --plot Report plot data (only with -u)\n");
fprintf(stderr, " -h, --help Print usage\n");
fprintf(stderr, " -V, --version Show version information\n");
fprintf(stderr, " -f, --filter arg Filter zone names (default: "")\n");
fprintf(stderr, " -s, --sep arg CSV separator (default: ,)\n");
fprintf(stderr, " -c, --case Case sensitive filtering\n");
fprintf(stderr, " -e, --self Get self times\n");
fprintf(stderr, " -u, --unwrap Report each cpu zone event\n");
fprintf(stderr, " -g, --gpu Report each gpu zone event\n" );
fprintf(stderr, " -m, --messages Report only messages\n");
fprintf(stderr, " -p, --plot Report plot data (only with -u)\n");
fprintf(stderr, " -t, --truncated_mean arg Report truncated mean (arg is the percentile. Default is 90)\n");
exit(e);
}
@@ -46,6 +51,7 @@ struct Args {
bool show_gpu;
bool unwrapMessages;
bool plot;
int truncated_mean_percentile;
};
Args parse_args(int argc, char** argv)
@@ -55,10 +61,11 @@ Args parse_args(int argc, char** argv)
print_usage_exit(1);
}
Args args = { "", ",", "", false, false, false, false, false, false };
Args args = { "", ",", "", false, false, false, false, false, false, 0};
struct option long_opts[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'V' },
{ "filter", optional_argument, NULL, 'f' },
{ "sep", optional_argument, NULL, 's' },
{ "case", no_argument, NULL, 'c' },
@@ -67,17 +74,21 @@ Args parse_args(int argc, char** argv)
{ "gpu", no_argument, NULL, 'g' },
{ "messages", no_argument, NULL, 'm' },
{ "plot", no_argument, NULL, 'p' },
{ "truncated_mean", optional_argument, NULL, 't' },
{ NULL, 0, NULL, 0 }
};
int c;
while ((c = getopt_long(argc, argv, "hf:s:ceugmp", long_opts, NULL)) != -1)
while ((c = getopt_long(argc, argv, "hf:s:ceugmpV", long_opts, NULL)) != -1)
{
switch (c)
{
case 'h':
print_usage_exit(0);
break;
case 'V':
printf( "tracy-csvexport %i.%i.%i / %s\n", tracy::Version::Major, tracy::Version::Minor, tracy::Version::Patch, tracy::GitRef );
exit( 0 );
case 'f':
args.filter = optarg;
break;
@@ -102,6 +113,9 @@ Args parse_args(int argc, char** argv)
case 'p':
args.plot = true;
break;
case 't':
args.truncated_mean_percentile = std::clamp<int>(optarg ? std::atoi(optarg) : 90, 1, 99);
break;
default:
print_usage_exit(1);
break;
@@ -163,6 +177,53 @@ std::string join(const T& v, const char* sep) {
return s.str();
}
// Returns {pN, truncated_mean}
std::pair<int64_t, int64_t> percentile_and_truncated_mean(std::vector<int64_t>& data, const double p)
{
assert(p >= 0.0 && p <= 1.0);
if (data.empty()) {
return {0, 0};
}
std::sort(data.begin(), data.end());
const std::size_t n = data.size();
const double idx = p * (static_cast<double>(n) - 1.0);
const std::size_t idxLow = static_cast<std::size_t>(std::floor(idx));
const std::size_t idxHigh = std::min(idxLow + 1, n - 1);
const double frac = idx - static_cast<double>(idxLow);
const double low = static_cast<double>(data[idxLow]);
const double high = static_cast<double>(data[idxHigh]);
// percentile value
const double pval_double = low + (high - low) * frac;
const int64_t pval_int = static_cast<int64_t>(std::llround(pval_double));
// Compute truncated mean: average of all values <= pval_double
int64_t sum = 0;
std::size_t count = 0;
for (std::size_t i = 0; i < n; ++i) {
if (static_cast<double>(data[i]) <= pval_double) {
sum += data[i];
++count;
} else {
break; // sorted, so we can stop once we hit > pval_double
}
}
if (count == 0) {
// should not happen for p in [0,1] unless data empty, but keep defensive behaviour
return {pval_int, 0};
}
const int64_t truncated_mean = sum / count;
return {pval_int, truncated_mean};
}
// From TracyView.cpp
int64_t GetZoneChildTimeFast(
const tracy::Worker& worker,
@@ -353,6 +414,12 @@ int main(int argc, char** argv)
"name", "src_file", "src_line", "total_ns", "total_perc",
"counts", "mean_ns", "min_ns", "max_ns", "std_ns"
};
if(args.truncated_mean_percentile)
{
columns.push_back("percentile_ns");
columns.push_back("truncated_mean_ns");
}
}
std::string header = join(columns, args.separator);
printf("%s\n", header.data());
@@ -404,10 +471,11 @@ int main(int argc, char** argv)
values[3] = std::to_string(time);
values[4] = std::to_string(100. * time / last_time);
values[5] = std::to_string(zone_data.zones.size());
const auto sz = zone_data.zones.size();
values[5] = std::to_string(sz);
const auto avg = time / sz;
const auto avg = (args.self_time ? zone_data.selfTotal : zone_data.total)
/ zone_data.zones.size();
values[6] = std::to_string(avg);
const auto tmin = args.self_time ? zone_data.selfMin : zone_data.min;
@@ -415,7 +483,6 @@ int main(int argc, char** argv)
values[7] = std::to_string(tmin);
values[8] = std::to_string(tmax);
const auto sz = zone_data.zones.size();
const auto ss = zone_data.sumSq
- 2. * zone_data.total * avg
+ avg * avg * sz;
@@ -424,6 +491,24 @@ int main(int argc, char** argv)
std = sqrt(ss / (sz - 1));
values[9] = std::to_string(std);
if(args.truncated_mean_percentile)
{
std::vector<int64_t> samples;
samples.reserve( zone_data.zones.size() );
for(const auto& zone_thread_data : zone_data.zones)
{
const auto zone_event = zone_thread_data.Zone();
auto timespan = zone_event->End() - zone_event->Start();
if(args.self_time)
timespan -= GetZoneChildTimeFast( worker, *zone_event );
samples.push_back( timespan );
}
std::pair<int64_t, int64_t> pN = percentile_and_truncated_mean(samples, args.truncated_mean_percentile / 100.0);
values[10] = std::to_string(pN.first);
values[11] = std::to_string(pN.second);
}
std::string row = join(values, args.separator);
printf("%s\n", row.data());
}

View File

@@ -0,0 +1,57 @@
// Template implementations of the tracy::Platform* hooks. Pair with the
// platform header (see CustomPlatform.h) and link this into your final
// binary.
#include <stdlib.h>
#include <string.h>
#include "CustomPlatform.h"
namespace tracy
{
uint32_t PlatformGetThreadId()
{
return 0;
}
void PlatformGetHostname( char* buf, size_t size )
{
const char* placeholder = "(?)";
if( size == 0 ) return;
const size_t n = strlen( placeholder );
const size_t copy = n < size - 1 ? n : size - 1;
memcpy( buf, placeholder, copy );
buf[copy] = '\0';
}
const char* PlatformGetUserLogin()
{
return "(?)";
}
const char* PlatformGetUserFullName()
{
return nullptr;
}
bool PlatformSafeMemcpy( void* dst, const void* src, size_t size )
{
// Stub: report failure so Tracy skips the snapshot. Real impls use SEH
// on Win32, pipe(2) on POSIX, or an equivalent probe-and-copy primitive.
(void)dst; (void)src; (void)size;
return false;
}
// Stubs forward to the C runtime. Swap in the allocator you actually want.
void* PlatformMalloc( size_t size ) { return malloc( size ); }
void PlatformFree( void* ptr ) { free( ptr ); }
void* PlatformRealloc( void* ptr, size_t size ) { return realloc( ptr, size ); }
void PlatformAllocatorInit() {}
void PlatformAllocatorThreadInit() {}
void PlatformAllocatorFinalize() {}
void PlatformAllocatorThreadFinalize(){}
}

View File

@@ -0,0 +1,73 @@
// Template platform header for unsupported targets.
//
// Copy into your project, fill in the sections you need, and point Tracy at
// it via -DTRACY_PLATFORM_HEADER="\"my_platform.h\"". Provide the
// implementations in any TU linked into your final binary (see
// CustomPlatform.cpp).
//
// Use this only for the TRACY_HAS_CUSTOM_* hooks and matching Platform*
// declarations — don't set unrelated TRACY_* options here. Some are checked
// before this header is included, so the result would depend on which TU
// consulted them; set those at the build system level instead.
//
// For platform-specific features without a custom hook (call stacks,
// context switches, crash handling, system tracing, etc.), disable them at
// the build system level with the matching TRACY_NO_* macro.
#ifndef __MY_TRACY_PLATFORM_H__
#define __MY_TRACY_PLATFORM_H__
#include <stddef.h>
#include <stdint.h>
namespace tracy
{
// --- Thread id --------------------------------------------------------------
//
// Required if defaults in TracySystem.cpp do not matches your platform.
// Note pthread_self() is NOT suitable, it returns a library handle, not a kernel id.
//#define TRACY_HAS_CUSTOM_THREAD_ID
uint32_t PlatformGetThreadId();
// --- User info --------------------------------------------------------------
//
// Identifies the machine and user in the trace header. Return placeholder
// strings (e.g. "(?)") from any of these if your platform has no equivalent
// notion.
//#define TRACY_HAS_CUSTOM_USER_INFO
void PlatformGetHostname( char* buf, size_t size );
const char* PlatformGetUserLogin();
const char* PlatformGetUserFullName();
// --- Safe memory copy -------------------------------------------------------
//
// Tracy uses this to snapshot potentially-unmapped memory during sampling.
// Must not crash on unreadable input — return false instead. Plain memcpy()
// is NOT a valid implementation.
//#define TRACY_HAS_CUSTOM_SAFE_COPY
bool PlatformSafeMemcpy( void* dst, const void* src, size_t size );
// --- Allocator --------------------------------------------------------------
//
// Replaces Tracy's internal allocator. Drop in the system allocator, an
// in-house one, or any third-party allocator you like. Malloc/Free/Realloc
// must be thread-safe; ThreadInit is an optional prime, not a precondition.
// Finalize must also tear down the calling thread's per-thread state, the
// way rpmalloc_finalize() does — Tracy does not call ThreadFinalize for the
// shutdown thread before Finalize.
//#define TRACY_HAS_CUSTOM_ALLOCATOR
void* PlatformMalloc( size_t size );
void PlatformFree( void* ptr );
void* PlatformRealloc( void* ptr, size_t size );
void PlatformAllocatorInit();
void PlatformAllocatorThreadInit();
void PlatformAllocatorFinalize();
void PlatformAllocatorThreadFinalize();
}
#endif

View File

@@ -8,7 +8,7 @@
#define kSimdWidth 4
#if !defined(__arm__) && !defined(__arm64__) && !defined(__EMSCRIPTEN__)
#if !defined(__arm__) && !defined(__arm64__) && !defined(__EMSCRIPTEN__) && !defined(_M_ARM64)
// ---- SSE implementation
@@ -141,8 +141,14 @@ VM_INLINE float hmin(float4 v)
// Returns a 4-bit code where bit0..bit3 is X..W
VM_INLINE unsigned mask(float4 v)
{
#if defined(_M_ARM64)
static const uint32_t values[4] = { 1u, 2u, 4u, 8u };
const uint32x4_t movemask = vld1q_u32( values );
const uint32x4_t highbit = vdupq_n_u32( 0x80000000u );
#else
static const uint32x4_t movemask = { 1, 2, 4, 8 };
static const uint32x4_t highbit = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 };
#endif
uint32x4_t t0 = vreinterpretq_u32_f32(v.m);
uint32x4_t t1 = vtstq_u32(t0, highbit);
uint32x4_t t2 = vandq_u32(t1, movemask);

View File

@@ -12,7 +12,7 @@
#if DO_FLOAT3_WITH_SIMD
#if !defined(__arm__) && !defined(__arm64__)
#if !defined(__arm__) && !defined(__arm64__) && !defined(_M_ARM64)
// ---- SSE implementation
@@ -223,8 +223,14 @@ VM_INLINE float3 cross(float3 a, float3 b)
// Returns a 3-bit code where bit0..bit2 is X..Z
VM_INLINE unsigned mask(float3 v)
{
#if defined(_M_ARM64)
static const uint32_t values[4] = { 1u, 2u, 4u, 8u };
const uint32x4_t movemask = vld1q_u32( values );
const uint32x4_t highbit = vdupq_n_u32( 0x80000000u );
#else
static const uint32x4_t movemask = { 1, 2, 4, 8 };
static const uint32x4_t highbit = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 };
#endif
uint32x4_t t0 = vreinterpretq_u32_f32(v.m);
uint32x4_t t1 = vtstq_u32(t0, highbit);
uint32x4_t t2 = vandq_u32(t1, movemask);

View File

@@ -72,7 +72,11 @@ namespace
#if defined _M_IX86 || defined _M_X64
#pragma intrinsic(_mm_pause)
inline void Pause() { _mm_pause(); }
#endif
#elif defined(_M_ARM64)
inline void Pause() { __yield(); }
#else
inline void Pause() { /* No ops*/ }
#endif
#elif defined __i386__ || defined __x86_64__
inline void Pause() { __asm__ __volatile__("pause;"); }
#else

0
examples/cuda/README.md Normal file
View File

View File

@@ -0,0 +1,39 @@
cmake_minimum_required(VERSION 3.18)
project(CUDAGraphDemo LANGUAGES CXX CUDA)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CUDA_STANDARD 17)
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.24")
set(CMAKE_CUDA_ARCHITECTURES native)
endif()
set(TRACY_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../.."
CACHE PATH "Root of the Tracy repository")
set(TRACY_PUBLIC "${TRACY_PATH}/public")
find_package(CUDAToolkit REQUIRED)
find_package(Threads REQUIRED)
# cuda-graph-demo.cu embeds Tracy via #include <TracyClient.cpp> (unity build),
# so no separate TracyClient library is needed — just expose the public headers.
add_executable(cuda-graph-demo cuda-graph-demo.cu)
target_include_directories(cuda-graph-demo PRIVATE ${TRACY_PUBLIC})
target_link_libraries(cuda-graph-demo PRIVATE
CUDA::cupti CUDA::cuda_driver Threads::Threads ${CMAKE_DL_LIBS})
# ctest-related integration below
# to run the binaries via ctest:
# ctest --test-dir <cmake-build-dir> -R <binary-name> -C <build-config>
enable_testing()
add_test(NAME cuda-graph-demo COMMAND cuda-graph-demo)
# On Windows, CUPTI's DLL must be on PATH at runtime.
if(WIN32)
set(_cupti_dir "$<TARGET_FILE_DIR:CUDA::cupti>")
set_target_properties(cuda-graph-demo PROPERTIES
VS_DEBUGGER_ENVIRONMENT "PATH=${_cupti_dir};$ENV{PATH}")
set_tests_properties(cuda-graph-demo PROPERTIES
ENVIRONMENT "PATH=${_cupti_dir};$ENV{PATH}")
endif()

View File

@@ -0,0 +1,11 @@
TRACY_PATH=<path-to-tracy>
CUDA_TOOLKIT_PATH=/usr/local/cuda
CUDA_CUPTI_PATH=${CUDA_TOOLKIT_PATH}/extras/CUPTI
# pass -v to nvcc for verbose build information
nvcc -O2 -std=c++17 cuda-graph-demo.cu \
-o cuda-graph-demo \
-I "${TRACY_PATH}/public" \
-I "${CUDA_CUPTI_PATH}/include" -I "${CUDA_TOOLKIT_PATH}/include" \
-L "${CUDA_CUPTI_PATH}/lib64" -L "${CUDA_TOOLKIT_PATH}/lib64" \
-lcupti -lcuda

View File

@@ -0,0 +1,146 @@
#include <cuda_runtime.h>
// WARN: for simplicity, we enable and "embed" the Tracy client directly into the code
#define TRACY_ENABLE
#include <TracyClient.cpp>
#include <tracy/Tracy.hpp>
#include <tracy/TracyCUDA.hpp>
#include <cstdio>
#include <cstdlib>
#include <vector>
#define CUDA_CHECK(call) \
do { \
cudaError_t err__ = (call); \
if (err__ != cudaSuccess) { \
std::fprintf(stderr, "CUDA error %s at %s:%d: %s\n", \
cudaGetErrorName(err__), __FILE__, __LINE__, \
cudaGetErrorString(err__)); \
std::exit(EXIT_FAILURE); \
} \
} while (0)
__global__ void saxpy(float a, const float* x, float* y, int n)
{
int i = blockIdx.x * blockDim.x + threadIdx.x;
if (i < n) y[i] = a * x[i] + y[i];
}
int main()
{
// CUPTI-backed Tracy context. Auto-captures all CUDA activity from the
// point StartProfiling() is called until StopProfiling(). The background
// collector thread flushes activity into Tracy; the explicit Collect()
// calls below just force a flush at known phase boundaries.
auto* cudaCtx = TracyCUDAContext();
{
constexpr char ctxName[] = "CUDA Graph Demo";
TracyCUDAContextName(cudaCtx, ctxName, sizeof(ctxName) - 1);
}
TracyCUDAStartProfiling(cudaCtx);
constexpr int N = 1 << 16; // small N => kernel is short => launch overhead dominates
constexpr int KERNELS_PER_GRAPH = 32; // chain length captured into the graph
constexpr int OUTER_ITERS = 2000; // how many times we replay the chain
// allocate device buffers
float *dX = nullptr, *dY = nullptr;
CUDA_CHECK(cudaMalloc(&dX, N * sizeof(float)));
CUDA_CHECK(cudaMalloc(&dY, N * sizeof(float)));
std::vector<float> hX(N, 1.0f);
CUDA_CHECK(cudaMemcpy(dX, hX.data(), N * sizeof(float), cudaMemcpyHostToDevice));
cudaStream_t stream = nullptr;
CUDA_CHECK(cudaStreamCreate(&stream));
const dim3 block(256);
const dim3 grid((N + block.x - 1) / block.x);
cudaEvent_t evStart, evStop;
CUDA_CHECK(cudaEventCreate(&evStart));
CUDA_CHECK(cudaEventCreate(&evStop));
// warm-up (so first-launch lazy-init and/or JIT doesn't bias the measurement)
saxpy<<<grid, block, 0, stream>>>(0.0f, dX, dY, N);
CUDA_CHECK(cudaStreamSynchronize(stream));
// baseline: launch each kernel directly on the stream
float msStream = 0.0f;
{
ZoneScopedN("stream-launches");
CUDA_CHECK(cudaMemsetAsync(dY, 0, N * sizeof(float), stream));
CUDA_CHECK(cudaEventRecord(evStart, stream));
for (int outer = 0; outer < OUTER_ITERS; ++outer) {
for (int k = 0; k < KERNELS_PER_GRAPH; ++k) {
saxpy<<<grid, block, 0, stream>>>(1.0e-6f, dX, dY, N);
}
}
CUDA_CHECK(cudaEventRecord(evStop, stream));
CUDA_CHECK(cudaEventSynchronize(evStop));
CUDA_CHECK(cudaEventElapsedTime(&msStream, evStart, evStop));
TracyCUDACollect(cudaCtx);
}
// capture: record the same kernel chain into a graph
cudaGraph_t graph = nullptr;
cudaGraphExec_t graphExec = nullptr;
{
ZoneScopedN("graph-capture");
// cudaStreamCaptureModeRelaxed allows the calling thread to perform
// unrelated CUDA work during capture; ThreadLocal is stricter if you need
// isolation. Most short, single-stream captures work fine in either mode.
CUDA_CHECK(cudaStreamBeginCapture(stream, cudaStreamCaptureModeRelaxed));
for (int k = 0; k < KERNELS_PER_GRAPH; ++k) {
saxpy<<<grid, block, 0, stream>>>(1.0e-6f, dX, dY, N);
}
CUDA_CHECK(cudaStreamEndCapture(stream, &graph));
// Instantiate once -> reusable executable graph.
CUDA_CHECK(cudaGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
// The template graph isn't needed once instantiated.
CUDA_CHECK(cudaGraphDestroy(graph));
}
// replay: launch the instantiated graph OUTER_ITERS times
float msGraph = 0.0f;
{
ZoneScopedN("graph-launches");
CUDA_CHECK(cudaMemsetAsync(dY, 0, N * sizeof(float), stream));
CUDA_CHECK(cudaEventRecord(evStart, stream));
for (int outer = 0; outer < OUTER_ITERS; ++outer) {
CUDA_CHECK(cudaGraphLaunch(graphExec, stream));
}
CUDA_CHECK(cudaEventRecord(evStop, stream));
CUDA_CHECK(cudaEventSynchronize(evStop));
CUDA_CHECK(cudaEventElapsedTime(&msGraph, evStart, evStop));
TracyCUDACollect(cudaCtx);
}
// sanity check: y[i] = OUTER_ITERS * KERNELS_PER_GRAPH * 1e-6 * x[i]
std::vector<float> hY(N);
CUDA_CHECK(cudaMemcpy(hY.data(), dY, N * sizeof(float), cudaMemcpyDeviceToHost));
const float expected = float(OUTER_ITERS) * float(KERNELS_PER_GRAPH) * 1.0e-6f;
std::printf("Stream launches: %8.3f ms (%d kernels)\n",
msStream, OUTER_ITERS * KERNELS_PER_GRAPH);
std::printf("Graph launches: %8.3f ms (%d graph launches x %d kernels)\n",
msGraph, OUTER_ITERS, KERNELS_PER_GRAPH);
std::printf("Speedup : %8.2fx\n", msStream / msGraph);
std::printf("hY[0] = %.6e (expected %.6e)\n", hY[0], expected);
// shutdown
CUDA_CHECK(cudaGraphExecDestroy(graphExec));
CUDA_CHECK(cudaEventDestroy(evStart));
CUDA_CHECK(cudaEventDestroy(evStop));
CUDA_CHECK(cudaStreamDestroy(stream));
CUDA_CHECK(cudaFree(dX));
CUDA_CHECK(cudaFree(dY));
TracyCUDAStopProfiling(cudaCtx);
TracyCUDAContextDestroy(cudaCtx);
return 0;
}

View File

@@ -0,0 +1,63 @@
cmake_minimum_required(VERSION 3.29)
project(dyna LANGUAGES C CXX)
option(TRACY_ENABLE "Enable Tracy" ON)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_COLOR_DIAGNOSTICS ON)
include(cmake/CPM.cmake)
CPMAddPackage(
NAME glad
VERSION 2.0.8
GIT_REPOSITORY https://github.com/Dav1dde/glad.git
GIT_TAG glad2
)
add_subdirectory(${glad_SOURCE_DIR}/cmake ${CMAKE_CURRENT_BINARY_DIR}/glad)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../.. client/)
glad_add_library(glad_gl_core_33 STATIC API gl:core=3.3)
find_package(SDL3 REQUIRED)
find_package(SDL3_image REQUIRED)
add_executable(dyna
src/main.cpp
src/datapath.cpp
src/timer.cpp
src/gfx.cpp
src/texture.cpp
src/entity.cpp
src/world.cpp
src/map.cpp
src/player.cpp
src/monster.cpp
src/bomb.cpp
src/bonus.cpp
src/game.cpp
)
target_link_libraries(dyna
PRIVATE
glad_gl_core_33
SDL3::SDL3
SDL3_image::SDL3_image
Tracy::TracyClient
)
target_include_directories(dyna PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
# Mirror the data/ tree next to the executable so the game finds its assets
# when launched from the build directory (paths are resolved via SDL_GetBasePath).
add_custom_command(TARGET dyna POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_CURRENT_SOURCE_DIR}/data
$<TARGET_FILE_DIR:dyna>/data
COMMENT "Copying data/ next to dyna executable"
)
file(GENERATE OUTPUT .gitignore CONTENT "*")

7
examples/dyna/LICENSE Normal file
View File

@@ -0,0 +1,7 @@
Dyna.net copyright 2005 by Bartosz Taudul and Ralf Wrześniewski.
This program (including source code and the asset it uses) is NOT licensed
for any use other than being an example of how to integrate Tracy Profiler.
The license terms written in other parts of this repository DO NOT apply
here.

View File

@@ -0,0 +1,24 @@
# SPDX-License-Identifier: MIT
#
# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors
set(CPM_DOWNLOAD_VERSION 0.42.3)
set(CPM_HASH_SUM "a609e875fd532b067174250f6abbc3dac22fe2d64869783fb1e80bda1625c844")
if(CPM_SOURCE_CACHE)
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
elseif(DEFINED ENV{CPM_SOURCE_CACHE})
set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
else()
set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
endif()
# Expand relative path. This is important if the provided path contains a tilde (~)
get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE)
file(DOWNLOAD
https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake
${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM}
)
include(${CPM_DOWNLOAD_LOCATION})

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 667 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 B

View File

@@ -0,0 +1,12 @@
10 1 0 0
@............
.#.#.#.#.#.#.
.............
.#.#.#.#.#.#.
.............
.#.#.#.#.#.#.
.............
.#.#.#.#.#.#.
.............
.#.#.#.#.#.#.
.............

View File

@@ -0,0 +1,12 @@
20 4 0 0
.............
.#.#.#.#.#.#.
.............
.#.#.#.#.#.#.
.............
.#.#.#@#.#.#.
.............
.#.#.#.#.#.#.
.............
.#.#.#.#.#.#.
.............

View File

@@ -0,0 +1,12 @@
40 3 2 0
@............
.#.#.#.#.#.#.
.............
.#.#.#.#.#.#.
.............
.#.#.#.#.#.#.
.............
.#.#.#.#.#.#.
.............
.#.#.#.#.#.#.
.............

View File

@@ -0,0 +1,12 @@
40 3 3 0
@............
.###.#.#.###.
.............
.#.#.#.#.#.#.
.............
.###.#.#.###.
.............
.#.#.#.#.#.#.
.............
.###.#.#.###.
.............

View File

@@ -0,0 +1,12 @@
40 2 4 1
@............
.###.#.#.###.
.#.........#.
.#.#.#.#.#.#.
.............
.#.#.#.#.#.#.
.............
.#.#.#.#.#.#.
.#.........#.
.###.#.#.###.
.............

View File

@@ -0,0 +1,12 @@
50 2 2 3
.#.#.#.#.#.#.
.............
.#.#.#.#.#.#.
.....#.#.....
.#.###.###.#.
.............
.#.###.###.#.
.....#.#.....
.#.#.#.#.#.#.
.............
.#.#.#.#.#.#@

View File

@@ -0,0 +1,12 @@
60 3 3 3
@............
.#.#.###.#.#.
.............
.###.#.#.###.
.............
.#.#.###.#.#.
.............
.###.#.#.###.
.............
.#.#.###.#.#.
.............

View File

@@ -0,0 +1,12 @@
60 5 3 3
@............
.#.#.#.#.#.#.
.............
.#...#.#...#.
.............
.#.#.#.#.#.#.
.............
.#...#.#...#.
.............
.#.#.#.#.#.#.
.............

View File

@@ -0,0 +1,12 @@
90 5 5 5
@............
.#.........#.
.............
.............
.............
.............
.............
.............
.............
.#.........#.
.............

View File

@@ -0,0 +1,12 @@
30 4 4 4
@............
.#.#.#.#.#.#.
.............
.#...#.#...#.
.............
.#.#.#.#.#.#.
.............
.#...#.#...#.
.............
.#.#.#.#.#.#.
.............

143
examples/dyna/src/bomb.cpp Normal file
View File

@@ -0,0 +1,143 @@
#include "bomb.hpp"
#include "gfx.hpp"
#include "map.hpp"
#include "texture.hpp"
#include "timer.hpp"
#include "world.hpp"
#include <tracy/Tracy.hpp>
namespace dyna
{
Bomb::Bomb( int x_, int y_ )
: x( x_ )
, y( y_ )
, left( 9 )
{
}
void Bomb::draw()
{
ZoneScoped;
if( stage == Stage::exploding )
return;
if( stage == Stage::appear )
{
Textures::bomb_appear.bind( 9 - left );
}
else
{
int frame = static_cast<int>( ( time - left ) / static_cast<float>( time ) * 8 );
if( Timer::get_timestamp() / 100 % 2 == 0 )
frame++;
Textures::bomb.bind( frame );
}
Gfx::draw_square( x, y );
}
void Bomb::tick( World& world )
{
ZoneScoped;
delta += Timer::delta;
while( delta > 10 )
{
delta -= 10;
if( stage == Stage::appear )
{
if( left > 0 )
{
delta -= 10; // the fade-in advances at double speed
left--;
}
else
{
stage = Stage::ticking;
left = time;
}
}
else if( left > 0 )
{
left--;
}
else if( stage == Stage::ticking )
{
explode( world );
}
else
{
die( world );
}
}
}
void Bomb::explode( World& world )
{
ZoneScoped;
stage = Stage::exploding;
left = 200;
Map& map = world.map();
map.at( x, y ) = Field::explosion( Field::ExplosionType::center );
struct Dir
{
int dx, dy;
Field::ExplosionType through, tip;
};
const Dir dirs[4] = {
{ -1, 0, Field::ExplosionType::horizontal, Field::ExplosionType::left },
{ 1, 0, Field::ExplosionType::horizontal, Field::ExplosionType::right },
{ 0, -1, Field::ExplosionType::vertical, Field::ExplosionType::up },
{ 0, 1, Field::ExplosionType::vertical, Field::ExplosionType::down },
};
for( const Dir& d : dirs )
{
for( int i = 1; i <= maxrange; i++ )
{
int tx = x + d.dx * i;
int ty = y + d.dy * i;
if( tx < 0 || tx > map.getx() - 1 || ty < 0 || ty > map.gety() - 1 )
break;
Destruction destr = map.at( tx, ty ).destructible();
if( destr == Destruction::none )
break;
etiles.emplace_back( tx, ty );
if( map.at( tx, ty ).kind == Field::Kind::crate )
world.crates_left--;
if( i == maxrange || destr == Destruction::single )
{
map.at( tx, ty ) = Field::explosion( d.tip );
break;
}
else
{
map.at( tx, ty ) = Field::explosion( d.through );
}
}
}
}
void Bomb::die( World& world )
{
ZoneScoped;
dead = true;
Map& map = world.map();
map.at( x, y ) = Field::floor();
for( const auto& [tx, ty] : etiles )
map.at( tx, ty ) = Field::floor();
}
}

View File

@@ -0,0 +1,44 @@
#pragma once
#include <utility>
#include <vector>
namespace dyna
{
class World;
// A bomb on the grid: fades in, counts down, then paints a cross-shaped
// explosion onto the map and clears it again. Ported from bomb.cs.
class Bomb
{
public:
Bomb( int x, int y );
void draw();
void tick( World& world );
bool is_dead() const { return dead; }
private:
void explode( World& world );
void die( World& world );
enum class Stage
{
appear,
ticking,
exploding
};
int x, y; // grid coordinates
Stage stage = Stage::appear;
int left;
int delta = 0;
static constexpr int time = 150;
static constexpr int maxrange = 1;
std::vector<std::pair<int, int>> etiles; // tiles to revert to floor
bool dead = false;
};
}

View File

@@ -0,0 +1,58 @@
#include "bonus.hpp"
#include "gfx.hpp"
#include "texture.hpp"
#include "timer.hpp"
#include <tracy/Tracy.hpp>
namespace dyna
{
Vortex::Vortex( int gx, int gy )
{
x = gx; // stored in grid units, drawn via draw_square
y = gy;
set_action( Action::appear );
left = 79;
}
void Vortex::draw()
{
ZoneScoped;
int frame = static_cast<int>( ( Timer::get_timestamp() - action_start ) / 40 );
switch( action )
{
case Action::appear:
Textures::vortex_appear.bind( frame );
break;
case Action::wait:
Textures::vortex.bind( frame );
break;
default:
break;
}
Gfx::draw_square( x, y );
}
void Vortex::tick( World& )
{
ZoneScoped;
delta += Timer::delta;
while( delta > 10 )
{
delta -= 10;
if( left > 0 )
left--;
else if( action == Action::appear )
set_action( Action::wait );
}
}
void Vortex::die( World& ) {}
}

View File

@@ -0,0 +1,20 @@
#pragma once
#include "entity.hpp"
namespace dyna
{
// The level-exit portal. Unlike the other entities its coordinates are stored in
// grid units (it draws via draw_square), matching bonus.cs.
class Vortex : public Entity
{
public:
Vortex( int gx, int gy );
void draw() override;
void tick( World& world ) override;
void die( World& world ) override;
};
}

View File

@@ -0,0 +1,25 @@
#include "datapath.hpp"
#include <SDL3/SDL.h>
#include <tracy/Tracy.hpp>
namespace dyna
{
std::string data_path( const std::string& rel )
{
ZoneScoped;
ZoneText( rel.c_str(), rel.size() );
// SDL_GetBasePath returns the executable's directory (with a trailing
// separator) and is owned by SDL, so cache it for the program's lifetime.
static const std::string base = []
{
const char* p = SDL_GetBasePath();
return std::string( p ? p : "" );
}();
return base + rel;
}
}

View File

@@ -0,0 +1,14 @@
#pragma once
#include <string>
namespace dyna
{
// Resolve a path relative to the directory containing the executable, so the
// game finds its data files regardless of the current working directory (e.g.
// when launched from the build tree). The data/ tree is copied next to the
// binary at build time; see CMakeLists.txt.
std::string data_path( const std::string& rel );
}

View File

@@ -0,0 +1,39 @@
#include "entity.hpp"
#include "map.hpp"
#include "timer.hpp"
namespace dyna
{
void Entity::set_action( Action a )
{
action = a;
action_start = Timer::get_timestamp();
}
bool Entity::can_move( Action a, const Map& map ) const
{
switch( a )
{
case Action::up:
return y > 0 && !map.at( x / 64, y / 64 - 1 ).solid();
case Action::down:
return y / 64 < map.gety() - 1 && !map.at( x / 64, y / 64 + 1 ).solid();
case Action::left:
return x > 0 && !map.at( x / 64 - 1, y / 64 ).solid();
case Action::right:
return x / 64 < map.getx() - 1 && !map.at( x / 64 + 1, y / 64 ).solid();
default:
return true;
}
}
bool Entity::killed( const Map& map ) const
{
int tx = ( x + 32 ) / 64;
int ty = ( y + 32 ) / 64;
return map.at( tx, ty ).kind == Field::Kind::explosion;
}
}

View File

@@ -0,0 +1,52 @@
#pragma once
#include <cstdint>
namespace dyna
{
class Map;
class World;
// Movement/state verbs shared by the player and monsters. In the C# source this
// lived as Entity.Action; promoted to namespace scope so Game can refer to it.
enum class Action
{
wait,
up,
down,
left,
right,
death,
place_bomb,
appear
};
// Base for everything that moves on the grid. Coordinates are in pixels
// (64 per tile) and laid out top-left origin, matching entity.cs.
class Entity
{
public:
virtual ~Entity() = default;
virtual void set_action( Action a );
int getx() const { return x; }
int gety() const { return y; }
virtual void draw() = 0;
virtual void tick( World& world ) = 0;
virtual void die( World& world ) = 0;
protected:
bool can_move( Action a, const Map& map ) const;
virtual bool killed( const Map& map ) const;
int x = 0, y = 0;
std::int64_t action_start = 0;
int delta = 0;
Action action = Action::wait;
int left = 0;
};
}

210
examples/dyna/src/game.cpp Normal file
View File

@@ -0,0 +1,210 @@
#include "game.hpp"
#include "datapath.hpp"
#include "gfx.hpp"
#include "map.hpp"
#include "player.hpp"
#include "timer.hpp"
#include "world.hpp"
#include <SDL3/SDL.h>
#include <tracy/Tracy.hpp>
#include <string>
namespace dyna
{
namespace Game
{
namespace
{
struct TracySection
{
explicit TracySection( const char* name ) { Enter( name ); }
~TracySection() { Leave(); }
void Enter( const char* name )
{
idx = TracySectionEnter( "%s", name );
}
void Leave()
{
if( idx > 0 )
{
TracySectionLeave( idx );
idx = 0;
}
}
private:
uint32_t idx;
};
SDL_Keycode key = 0; // most recently pressed movement key
bool help = false;
// Run one level to completion. Returns true if the player asked to quit the
// whole application (window close), false if the level simply ended (death,
// escape, or reaching the exit) and control should return to the caller.
bool level_loop( World& world )
{
TracySection section( ( std::string( "Level " ) + world.name() ).c_str() );
Player* p = world.player();
for( ;; )
{
SDL_Event ev;
while( SDL_PollEvent( &ev ) )
{
if( ev.type == SDL_EVENT_QUIT )
return true;
if( ev.type == SDL_EVENT_KEY_DOWN && !ev.key.repeat )
{
switch( ev.key.key )
{
case SDLK_ESCAPE:
world.killed = true;
return false;
case SDLK_LEFT:
key = SDLK_LEFT;
p->move( Action::left );
break;
case SDLK_RIGHT:
key = SDLK_RIGHT;
p->move( Action::right );
break;
case SDLK_UP:
key = SDLK_UP;
p->move( Action::up );
break;
case SDLK_DOWN:
key = SDLK_DOWN;
p->move( Action::down );
break;
case SDLK_SPACE:
world.map().place_bomb( ( p->getx() + 32 ) / 64, ( p->gety() + 32 ) / 64 );
break;
default:
break;
}
}
if( ev.type == SDL_EVENT_KEY_UP )
{
switch( ev.key.key )
{
case SDLK_LEFT:
if( key == SDLK_LEFT ) p->move( Action::wait );
break;
case SDLK_RIGHT:
if( key == SDLK_RIGHT ) p->move( Action::wait );
break;
case SDLK_UP:
if( key == SDLK_UP ) p->move( Action::wait );
break;
case SDLK_DOWN:
if( key == SDLK_DOWN ) p->move( Action::wait );
break;
default:
break;
}
}
}
Gfx::clear();
Timer::tick();
world.tick();
world.draw();
Gfx::swap();
if( world.killed || world.next_level )
return false;
}
}
// Play through the levels in order. Returns true if the application should quit.
bool new_game()
{
TracySection section( "In-game" );
int level = 1;
for( ;; )
{
World world( data_path( "data/levels/" + std::to_string( level ) ), true );
if( level_loop( world ) )
return true; // window closed
if( world.killed )
return false; // died or escaped to the menu
if( ++level >= 10 )
return false; // cleared the last level
}
}
} // namespace
void menu_loop()
{
constexpr const char* sectionName = "Main menu";
TracySection section( sectionName );
World world( data_path( "data/levels/menu" ), false );
for( ;; )
{
SDL_Event ev;
while( SDL_PollEvent( &ev ) )
{
if( ev.type == SDL_EVENT_QUIT )
return;
if( ev.type == SDL_EVENT_KEY_DOWN && !ev.key.repeat )
{
switch( ev.key.key )
{
case SDLK_ESCAPE:
return;
case SDLK_SPACE:
section.Leave();
if( new_game() )
return; // window closed during play
section.Enter( sectionName );
break;
case SDLK_H:
help = !help;
break;
default:
break;
}
}
}
Gfx::clear();
Timer::tick();
world.tick();
world.draw();
if( help )
Gfx::show_help();
else
Gfx::show_menu();
Gfx::swap();
}
}
} // namespace Game
}

View File

@@ -0,0 +1,14 @@
#pragma once
namespace dyna
{
// Top-level game flow, ported from game.cs. The C# original kept the running
// game's state (player, map, win/lose flags) in static fields; that state now
// lives in a World object owned by the loops below, so nothing leaks out here.
namespace Game
{
void menu_loop();
}
}

517
examples/dyna/src/gfx.cpp Normal file
View File

@@ -0,0 +1,517 @@
#include "gfx.hpp"
#include "texture.hpp"
#include "timer.hpp"
#include <SDL3/SDL.h>
#include <tracy/Tracy.hpp>
#include <cassert>
#include <cstdio>
#include <vector>
namespace dyna
{
namespace
{
SDL_Window* g_window = nullptr;
SDL_GLContext g_gl_context = nullptr;
GLuint g_program = 0;
GLuint g_vao = 0;
GLuint g_vbo = 0;
// Current draw state, applied to every quad appended to the batch.
GLuint g_current_tex = 0;
int g_current_layer = 0;
float g_alpha = 1.0f;
// One vertex of the streaming batch: screen position, atlas-array texcoord,
// the array layer to sample and a per-vertex alpha multiplier.
struct GlVert
{
float px, py, tx, ty, layer, a;
};
// A run of consecutive vertices that share one texture, drawn in a single call.
struct DrawCmd
{
GLuint tex;
GLsizei count;
};
std::vector<GlVert> g_verts;
std::vector<DrawCmd> g_cmds;
const char* VERT_SRC = R"(
#version 330 core
uniform mat4 uProjection;
layout(location = 0) in vec2 aPosition;
layout(location = 1) in vec2 aTexCoord;
layout(location = 2) in float aLayer;
layout(location = 3) in float aAlpha;
out vec3 vTexCoord;
out float vAlpha;
void main() {
gl_Position = uProjection * vec4(aPosition, 0.0, 1.0);
vTexCoord = vec3(aTexCoord, aLayer);
vAlpha = aAlpha;
}
)";
const char* FRAG_SRC = R"(
#version 330 core
uniform sampler2DArray uTexture;
in vec3 vTexCoord;
in float vAlpha;
out vec4 fragColor;
void main() {
fragColor = texture(uTexture, vTexCoord) * vec4(1.0, 1.0, 1.0, vAlpha);
}
)";
GLuint compile_shader( GLenum type, const char* src )
{
ZoneScoped;
GLuint s = glCreateShader( type );
glShaderSource( s, 1, &src, nullptr );
glCompileShader( s );
GLint ok = 0;
glGetShaderiv( s, GL_COMPILE_STATUS, &ok );
if( !ok )
{
char log[512];
glGetShaderInfoLog( s, 512, nullptr, log );
std::fprintf( stderr, "Shader compile error: %s\n", log );
glDeleteShader( s );
return 0;
}
return s;
}
bool init_shaders()
{
ZoneScoped;
GLuint vs = compile_shader( GL_VERTEX_SHADER, VERT_SRC );
if( !vs ) return false;
GLuint fs = compile_shader( GL_FRAGMENT_SHADER, FRAG_SRC );
if( !fs )
{
glDeleteShader( vs );
return false;
}
g_program = glCreateProgram();
glAttachShader( g_program, vs );
glAttachShader( g_program, fs );
glLinkProgram( g_program );
glDeleteShader( vs );
glDeleteShader( fs );
GLint ok = 0;
glGetProgramiv( g_program, GL_LINK_STATUS, &ok );
if( !ok )
{
char log[512];
glGetProgramInfoLog( g_program, 512, nullptr, log );
std::fprintf( stderr, "Program link error: %s\n", log );
glDeleteProgram( g_program );
g_program = 0;
return false;
}
// Bottom-left origin orthographic projection, matching the original
// gluOrtho2D(0, w, 0, h) so the ported draw code carries over verbatim.
float l = 0.0f, r = static_cast<float>( Gfx::w );
float b = 0.0f, t = static_cast<float>( Gfx::h );
float proj[16] = {
2.0f / ( r - l ), 0.0f, 0.0f, 0.0f,
0.0f, 2.0f / ( t - b ), 0.0f, 0.0f,
0.0f, 0.0f, -1.0f, 0.0f,
-( r + l ) / ( r - l ), -( t + b ) / ( t - b ), 0.0f, 1.0f };
glUseProgram( g_program );
glUniformMatrix4fv( glGetUniformLocation( g_program, "uProjection" ), 1, GL_FALSE, proj );
glUniform1i( glGetUniformLocation( g_program, "uTexture" ), 0 );
glUseProgram( 0 );
return true;
}
void init_quad_vao()
{
ZoneScoped;
glGenVertexArrays( 1, &g_vao );
glGenBuffers( 1, &g_vbo );
glBindVertexArray( g_vao );
glBindBuffer( GL_ARRAY_BUFFER, g_vbo );
const GLsizei stride = sizeof( GlVert );
glEnableVertexAttribArray( 0 );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, stride, (void*)0 );
glEnableVertexAttribArray( 1 );
glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, stride, (void*)8 );
glEnableVertexAttribArray( 2 );
glVertexAttribPointer( 2, 1, GL_FLOAT, GL_FALSE, stride, (void*)16 );
glEnableVertexAttribArray( 3 );
glVertexAttribPointer( 3, 1, GL_FLOAT, GL_FALSE, stride, (void*)20 );
glBindVertexArray( 0 );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
}
// Draw and clear everything accumulated since the last flush, in submission
// order. Consecutive quads that share a texture collapse into one draw call.
void flush_batch()
{
ZoneScoped;
if( g_verts.empty() )
return;
glBindBuffer( GL_ARRAY_BUFFER, g_vbo );
glBufferData( GL_ARRAY_BUFFER,
static_cast<GLsizeiptr>( g_verts.size() * sizeof( GlVert ) ),
g_verts.data(), GL_STREAM_DRAW );
glUseProgram( g_program );
glBindVertexArray( g_vao );
GLint offset = 0;
for( const DrawCmd& cmd : g_cmds )
{
glBindTexture( GL_TEXTURE_2D_ARRAY, cmd.tex );
glDrawArrays( GL_TRIANGLES, offset, cmd.count );
offset += cmd.count;
}
glBindVertexArray( 0 );
glUseProgram( 0 );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
g_verts.clear();
g_cmds.clear();
}
// Frame image capture, following the OpenGL example in the Tracy manual. The
// backbuffer is downscaled on the GPU to a small fixed size and read back
// asynchronously, so a screenshot can be attached to every frame without
// stalling the CPU on the GPU. Several buffer sets are cycled because rendering
// runs a few frames ahead of the GPU.
// Half the render resolution, preserving its aspect ratio; both dimensions
// stay divisible by 4 as FrameImage requires.
constexpr int FI_W = Gfx::w / 2;
constexpr int FI_H = Gfx::h / 2;
constexpr int FI_COUNT = 4;
GLuint g_fi_texture[FI_COUNT];
GLuint g_fi_framebuffer[FI_COUNT];
GLuint g_fi_pbo[FI_COUNT];
GLsync g_fi_fence[FI_COUNT] = {};
int g_fi_idx = 0;
std::vector<int> g_fi_queue;
void init_frame_images()
{
ZoneScoped;
glGenTextures( FI_COUNT, g_fi_texture );
glGenFramebuffers( FI_COUNT, g_fi_framebuffer );
glGenBuffers( FI_COUNT, g_fi_pbo );
for( int i = 0; i < FI_COUNT; i++ )
{
glBindTexture( GL_TEXTURE_2D, g_fi_texture[i] );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, FI_W, FI_H, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr );
glBindFramebuffer( GL_FRAMEBUFFER, g_fi_framebuffer[i] );
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, g_fi_texture[i], 0 );
glBindBuffer( GL_PIXEL_PACK_BUFFER, g_fi_pbo[i] );
glBufferData( GL_PIXEL_PACK_BUFFER, FI_W * FI_H * 4, nullptr, GL_STREAM_READ );
}
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
glBindBuffer( GL_PIXEL_PACK_BUFFER, 0 );
}
void shutdown_frame_images()
{
ZoneScoped;
glDeleteTextures( FI_COUNT, g_fi_texture );
glDeleteFramebuffers( FI_COUNT, g_fi_framebuffer );
glDeleteBuffers( FI_COUNT, g_fi_pbo );
}
// Send any captures the GPU has already finished, then queue a capture of the
// frame just rendered. Call after the batch is flushed but before swapping.
void capture_frame_image()
{
ZoneScoped;
// Hand finished captures from earlier frames to the profiler. The queue
// size is the number of frames we are still ahead of the GPU, which is the
// frame lag Tracy needs as the FrameImage offset.
while( !g_fi_queue.empty() )
{
const int idx = g_fi_queue.front();
if( glClientWaitSync( g_fi_fence[idx], 0, 0 ) == GL_TIMEOUT_EXPIRED ) break;
glDeleteSync( g_fi_fence[idx] );
glBindBuffer( GL_PIXEL_PACK_BUFFER, g_fi_pbo[idx] );
void* ptr = glMapBufferRange( GL_PIXEL_PACK_BUFFER, 0, FI_W * FI_H * 4, GL_MAP_READ_BIT );
FrameImage( ptr, FI_W, FI_H, g_fi_queue.size(), true );
glUnmapBuffer( GL_PIXEL_PACK_BUFFER );
g_fi_queue.erase( g_fi_queue.begin() );
}
// Downscale the current backbuffer into the next buffer set and start an
// asynchronous read-back, signalled by a fence.
assert( g_fi_queue.empty() || g_fi_queue.front() != g_fi_idx ); // buffer overrun
glBindFramebuffer( GL_DRAW_FRAMEBUFFER, g_fi_framebuffer[g_fi_idx] );
glBlitFramebuffer( 0, 0, Gfx::w, Gfx::h, 0, 0, FI_W, FI_H, GL_COLOR_BUFFER_BIT, GL_LINEAR );
glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 );
glBindFramebuffer( GL_READ_FRAMEBUFFER, g_fi_framebuffer[g_fi_idx] );
glBindBuffer( GL_PIXEL_PACK_BUFFER, g_fi_pbo[g_fi_idx] );
glReadPixels( 0, 0, FI_W, FI_H, GL_RGBA, GL_UNSIGNED_BYTE, nullptr );
glBindFramebuffer( GL_READ_FRAMEBUFFER, 0 );
g_fi_fence[g_fi_idx] = glFenceSync( GL_SYNC_GPU_COMMANDS_COMPLETE, 0 );
g_fi_queue.emplace_back( g_fi_idx );
g_fi_idx = ( g_fi_idx + 1 ) % FI_COUNT;
}
} // namespace
namespace Render
{
bool init()
{
ZoneScoped;
if( !init_shaders() ) return false;
init_quad_vao();
init_frame_images();
return true;
}
void shutdown()
{
ZoneScoped;
shutdown_frame_images();
if( g_vbo ) glDeleteBuffers( 1, &g_vbo );
if( g_vao ) glDeleteVertexArrays( 1, &g_vao );
if( g_program ) glDeleteProgram( g_program );
g_vbo = g_vao = g_program = 0;
}
void use_texture( GLuint tex, int layer )
{
g_current_tex = tex;
g_current_layer = layer;
}
GLuint make_texture( int w, int h, int layers, const void* rgba )
{
ZoneScoped;
GLuint tex = 0;
glGenTextures( 1, &tex );
glBindTexture( GL_TEXTURE_2D_ARRAY, tex );
glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glTexImage3D( GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, w, h, layers, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgba );
return tex;
}
} // namespace Render
namespace Gfx
{
void clear()
{
glClear( GL_COLOR_BUFFER_BIT );
}
void swap()
{
ZoneScoped;
flush_batch();
capture_frame_image();
SDL_GL_SwapWindow( g_window );
FrameMark;
}
void alpha( float a )
{
g_alpha = a;
}
void draw_quad( const Vertex corners[4] )
{
ZoneScoped;
// Two triangles, vertices appended in submission order so painter ordering
// (and the transient per-monster alpha) is preserved by the batch.
const int idx[6] = { 0, 1, 2, 0, 2, 3 };
for( int i : idx )
{
const Vertex& c = corners[i];
g_verts.push_back( { c.x, c.y, c.u, c.v,
static_cast<float>( g_current_layer ), g_alpha } );
}
if( !g_cmds.empty() && g_cmds.back().tex == g_current_tex )
g_cmds.back().count += 6;
else
g_cmds.push_back( { g_current_tex, 6 } );
}
void draw_sprite( int x, int y )
{
ZoneScoped;
float fx = static_cast<float>( x );
float fy = static_cast<float>( y );
float top = static_cast<float>( h ) - fy;
float bottom = static_cast<float>( h ) - ( fy + 64.0f );
Vertex corners[4] = {
{ fx, top, 0.0f, 0.0f },
{ fx + 64.0f, top, 1.0f, 0.0f },
{ fx + 64.0f, bottom, 1.0f, 1.0f },
{ fx, bottom, 0.0f, 1.0f },
};
draw_quad( corners );
}
void draw_square( int x, int y )
{
draw_sprite( x * 64, y * 64 );
}
void show_help()
{
ZoneScoped;
Textures::menu.bind();
const float fw = static_cast<float>( w );
const float fh = static_cast<float>( h );
Vertex bg[4] = {
{ 0.0f, fh, 0.0f, 0.0f },
{ fw, fh, 832.0f / 1024, 0.0f },
{ fw, 0.0f, 832.0f / 1024, 704.0f / 1024 },
{ 0.0f, 0.0f, 0.0f, 704.0f / 1024 },
};
draw_quad( bg );
int t = static_cast<int>( Timer::get_timestamp() / 40 );
Textures::p_r.bind( t );
draw_sprite( 150, 85 );
Textures::m1_r.bind( t );
draw_sprite( 75, 160 );
Textures::m2_r.bind( t );
draw_sprite( 150, 160 );
Textures::m3_r.bind( t );
draw_sprite( 225, 160 );
Textures::bomb.bind( static_cast<int>( Timer::get_timestamp() / 100 % 2 ) );
draw_sprite( 150, 235 );
Textures::wall.bind();
draw_sprite( 150, 310 );
Textures::crate.bind();
draw_sprite( 150, 385 );
Textures::vortex.bind( t );
draw_sprite( 150, 460 );
Textures::bonus1.bind( t );
draw_sprite( 112, 535 );
Textures::bonus2.bind( t );
draw_sprite( 187, 535 );
}
void show_menu()
{
ZoneScoped;
Textures::menu.bind();
Vertex logo[4] = {
{ float( ( w - 594 ) / 2 ), float( h - 50 ), 1.0f, 0.0f },
{ float( ( w + 594 ) / 2 ), float( h - 50 ), 1.0f, 594.0f / 1024 },
{ float( ( w + 594 ) / 2 ), float( h - 50 - 180 ), 1.0f - 180.0f / 1024, 594.0f / 1024 },
{ float( ( w - 594 ) / 2 ), float( h - 50 - 180 ), 1.0f - 180.0f / 1024, 0.0f },
};
draw_quad( logo );
Vertex prompt[4] = {
{ float( ( w - 527 ) / 2 ), 335.0f, 0.0f, 704.0f / 1024 },
{ float( ( w + 527 ) / 2 ), 335.0f, 527.0f / 1024, 704.0f / 1024 },
{ float( ( w + 527 ) / 2 ), 20.0f, 527.0f / 1024, 1019.0f / 1024 },
{ float( ( w - 527 ) / 2 ), 20.0f, 0.0f, 1019.0f / 1024 },
};
draw_quad( prompt );
}
} // namespace Gfx
namespace Init
{
bool all()
{
ZoneScoped;
if( !SDL_Init( SDL_INIT_VIDEO ) )
{
std::fprintf( stderr, "SDL_Init failed: %s\n", SDL_GetError() );
return false;
}
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 3 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );
g_window = SDL_CreateWindow( "Dyna.net", Gfx::w, Gfx::h, SDL_WINDOW_OPENGL );
if( !g_window )
{
std::fprintf( stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError() );
return false;
}
g_gl_context = SDL_GL_CreateContext( g_window );
if( !g_gl_context )
{
std::fprintf( stderr, "SDL_GL_CreateContext failed: %s\n", SDL_GetError() );
return false;
}
int version = gladLoadGL( (GLADloadfunc)SDL_GL_GetProcAddress );
if( version == 0 )
{
std::fprintf( stderr, "gladLoadGL failed\n" );
return false;
}
SDL_GL_SetSwapInterval( 1 ); // vsync; the game is time-based so speed is unaffected
glViewport( 0, 0, Gfx::w, Gfx::h );
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
if( !Render::init() ) return false;
Timer::reset();
Textures::preload();
return true;
}
void shutdown()
{
ZoneScoped;
Render::shutdown();
if( g_gl_context ) SDL_GL_DestroyContext( g_gl_context );
if( g_window ) SDL_DestroyWindow( g_window );
SDL_Quit();
}
} // namespace Init
}

59
examples/dyna/src/gfx.hpp Normal file
View File

@@ -0,0 +1,59 @@
#pragma once
#include <glad/gl.h>
namespace dyna
{
// Screen dimensions, matching the original 13x11 grid of 64px tiles.
namespace Gfx
{
constexpr int w = 832;
constexpr int h = 704;
void clear();
void swap();
// Drawing primitives ported from gfx.cs. They render with the currently
// bound texture (see Texture::bind) and the current alpha. The coordinate
// system is bottom-left origin with y growing upward, exactly as the C#
// gluOrtho2D setup; draw_sprite/draw_square take y measured from the top
// and flip internally, so game-side coordinates stay top-left based.
void alpha( float a );
void draw_sprite( int x, int y ); // pixel position of the top-left corner
void draw_square( int x, int y ); // grid position (multiplied by 64)
// A single textured quad given four explicit (position, texcoord) corners,
// used by the menu/help screens which sample rotated regions of the atlas.
struct Vertex
{
float x, y, u, v;
};
void draw_quad( const Vertex corners[4] );
void show_help();
void show_menu();
}
// Renderer back end shared by the texture loaders.
namespace Render
{
bool init(); // shaders + streaming VBO/VAO
void shutdown(); // delete the program and buffers
// Select the array texture (and layer within it) used by subsequent draws.
void use_texture( GLuint tex, int layer );
// Upload `layers` tightly packed RGBA8 images of size w*h as one
// GL_TEXTURE_2D_ARRAY and return its name (0 on failure).
GLuint make_texture( int w, int h, int layers, const void* rgba );
}
// One-time startup/shutdown, ported from the Init class in gfx.cs.
namespace Init
{
bool all(); // SDL, GL context, renderer, textures, timer
void shutdown();
}
}

View File

@@ -0,0 +1,38 @@
#include "game.hpp"
#include "gfx.hpp"
#include <SDL3/SDL_main.h>
#include <tracy/Tracy.hpp>
#include <cstdlib>
#include <new>
// Route every heap allocation through Tracy so the profiler can track memory
// usage. The default array forms (operator new[]/delete[]) and the nothrow
// forms forward to these, so overriding the scalar operators covers them too.
void* operator new( std::size_t count )
{
void* ptr = std::malloc( count );
if( !ptr ) throw std::bad_alloc();
TracyAlloc( ptr, count );
return ptr;
}
void operator delete( void* ptr ) noexcept
{
TracyFree( ptr );
std::free( ptr );
}
int main( int /*argc*/, char* /*argv*/[] )
{
TracyNoop;
if( !dyna::Init::all() )
return 1;
dyna::Game::menu_loop();
dyna::Init::shutdown();
return 0;
}

334
examples/dyna/src/map.cpp Normal file
View File

@@ -0,0 +1,334 @@
#include "map.hpp"
#include "bomb.hpp"
#include "bonus.hpp"
#include "gfx.hpp"
#include "monster.hpp"
#include "player.hpp"
#include "texture.hpp"
#include "timer.hpp"
#include "world.hpp"
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <fstream>
#include <sstream>
#include <tracy/Tracy.hpp>
namespace dyna
{
// ---- Field --------------------------------------------------------------
Field Field::explosion( ExplosionType t )
{
Field f;
f.kind = Kind::explosion;
f.etype = t;
f.tstart = Timer::get_timestamp();
return f;
}
bool Field::solid() const
{
switch( kind )
{
case Kind::wall:
case Kind::crate:
case Kind::bomb:
return true;
default:
return false;
}
}
Destruction Field::destructible() const
{
switch( kind )
{
case Kind::floor:
return Destruction::multi;
case Kind::crate:
return Destruction::single;
default:
return Destruction::none;
}
}
void Field::draw( int x, int y ) const
{
switch( kind )
{
case Kind::wall:
Textures::wall.bind();
Gfx::draw_square( x, y );
break;
case Kind::crate:
Textures::sand.bind();
Gfx::draw_square( x, y );
Textures::crate.bind();
Gfx::draw_square( x, y );
break;
case Kind::explosion: {
Textures::sand.bind();
Gfx::draw_square( x, y );
int frame = static_cast<int>( ( Timer::get_timestamp() - tstart ) / 40 % 8 );
if( frame > 4 ) frame = 8 - frame;
switch( etype )
{
case ExplosionType::center: Textures::e_c.bind( frame ); break;
case ExplosionType::vertical: Textures::e_v.bind( frame ); break;
case ExplosionType::horizontal: Textures::e_h.bind( frame ); break;
case ExplosionType::left: Textures::e_le.bind( frame ); break;
case ExplosionType::right: Textures::e_re.bind( frame ); break;
case ExplosionType::up: Textures::e_ue.bind( frame ); break;
case ExplosionType::down: Textures::e_de.bind( frame ); break;
}
Gfx::draw_square( x, y );
break;
}
// floor, bomb and vortex tiles all show plain sand; the bomb and vortex
// sprites themselves are drawn by their entities.
case Kind::floor:
case Kind::bomb:
case Kind::vortex:
default:
Textures::sand.bind();
Gfx::draw_square( x, y );
break;
}
}
// ---- Map ----------------------------------------------------------------
Map::Map( const std::string& fn )
{
ZoneScoped;
ZoneText( fn.c_str(), fn.size() );
load( fn );
generate_destructibles();
populate_map();
}
Map::~Map() = default;
void Map::load( const std::string& fn )
{
ZoneScoped;
std::ifstream f( fn );
if( !f )
{
std::fprintf( stderr, "Cannot open level %s\n", fn.c_str() );
grid.assign( X * Y, Field::floor() );
return;
}
std::stringstream buf;
buf << f.rdbuf();
std::string content = buf.str();
size_t nl = content.find( '\n' );
std::string header = ( nl == std::string::npos ) ? content : content.substr( 0, nl );
std::sscanf( header.c_str(), "%d %d %d %d", &destructibles, &m1, &m2, &m3 );
grid.assign( X * Y, Field::floor() );
px = -1;
size_t p = ( nl == std::string::npos ) ? content.size() : nl + 1;
for( int ry = 0; ry < Y; ry++ )
{
for( int rx = 0; rx < X; rx++ )
{
char c = ( p < content.size() ) ? content[p++] : '\0';
switch( c )
{
case '.':
at( rx, ry ) = Field::floor();
break;
case '#':
at( rx, ry ) = Field::wall();
break;
case '@':
at( rx, ry ) = Field::floor();
px = rx;
py = ry;
break;
case '\n':
rx--; // newlines don't consume a grid cell
break;
default:
break;
}
}
}
}
bool Map::monster_ok( int rx, int ry, int pxx, int pyy, int r ) const
{
const Field& f = at( rx, ry );
return f.is_floor_family() && f.kind != Field::Kind::crate &&
( std::abs( rx - pxx ) > r || std::abs( ry - pyy ) > r );
}
void Map::generate_destructibles()
{
ZoneScoped;
int i = destructibles;
while( i != 0 )
{
int rx = RNG::next( X );
int ry = RNG::next( Y );
if( monster_ok( rx, ry, px, py, 1 ) )
{
at( rx, ry ) = Field::crate();
i--;
}
}
}
void Map::populate_map()
{
ZoneScoped;
for( int type = 1; type <= 3; type++ )
{
int count = ( type == 1 ) ? m1 : ( type == 2 ) ? m2
: m3;
while( count != 0 )
{
int rx = RNG::next( X );
int ry = RNG::next( Y );
if( monster_ok( rx, ry, px, py, 2 ) )
{
monsters.push_back( std::make_unique<Monster>( type, rx, ry ) );
count--;
}
}
}
}
void Map::draw()
{
ZoneScoped;
for( int ry = 0; ry < Y; ry++ )
for( int rx = 0; rx < X; rx++ )
at( rx, ry ).draw( rx, ry );
for( auto& b : bombs ) b->draw();
for( auto& e : monsters ) e->draw();
for( auto& e : bonuses ) e->draw();
}
void Map::tick( World& world )
{
ZoneScoped;
// Bombs.
for( auto& b : bombs ) b->tick( world );
bombs.erase( std::remove_if( bombs.begin(), bombs.end(),
[]( const std::unique_ptr<Bomb>& b ) { return b->is_dead(); } ),
bombs.end() );
// Monsters: tick, then retire the dead and queue their respawn timers.
for( auto& e : monsters ) e->tick( world );
for( auto& e : monsters )
{
if( e->is_dead() )
{
int delay = ( e->type() == 1 ) ? 10000 : ( e->type() == 2 ) ? 20000
: 30000;
mwait.push_back( { e->type(), Timer::get_timestamp() + delay } );
}
}
monsters.erase( std::remove_if( monsters.begin(), monsters.end(),
[]( const std::unique_ptr<Monster>& e ) { return e->is_dead(); } ),
monsters.end() );
// The respawn and exit-portal placement below need the player's position;
// they only fire during gameplay (a monster died, or every crate is gone),
// never on the player-less menu screen.
Player* player = world.player();
// Respawn monsters whose wait has elapsed.
std::int64_t now = Timer::get_timestamp();
std::vector<MWait> still_waiting;
for( const MWait& m : mwait )
{
if( m.time < now && player )
{
int rx = 0, ry = 0;
bool ok = false;
while( !ok )
{
rx = RNG::next( X );
ry = RNG::next( Y );
if( monster_ok( rx, ry, player->getx() / 64, player->gety() / 64, 3 ) )
ok = true;
}
auto monster = std::make_unique<Monster>( m.type, rx, ry );
monster->set_action( Action::appear );
monsters.push_back( std::move( monster ) );
}
else
{
still_waiting.push_back( m );
}
}
mwait = std::move( still_waiting );
// Bonuses.
for( auto& e : bonuses ) e->tick( world );
// Once every crate is gone, open the exit portal somewhere clear.
if( world.crates_left == 0 && player )
{
world.crates_left--;
int rx = 0, ry = 0;
bool ok = false;
while( !ok )
{
rx = RNG::next( X );
ry = RNG::next( Y );
if( monster_ok( rx, ry, player->getx() / 64, player->gety() / 64, 4 ) )
ok = true;
}
at( rx, ry ) = Field::vortex();
bonuses.push_back( std::make_unique<Vortex>( rx, ry ) );
}
}
std::unique_ptr<Player> Map::create_player() const
{
return std::make_unique<Player>( px, py );
}
void Map::place_bomb( int x, int y )
{
Field& f = at( x, y );
if( f.is_floor_family() && f.kind != Field::Kind::bomb )
{
f = Field::bomb();
bombs.push_back( std::make_unique<Bomb>( x, y ) );
}
}
bool Map::monster_collide( int tx, int ty ) const
{
for( const auto& e : monsters )
{
if( ( e->getx() + 32 ) / 64 == ( tx + 32 ) / 64 &&
( e->gety() + 32 ) / 64 == ( ty + 32 ) / 64 )
return true;
}
return false;
}
}

120
examples/dyna/src/map.hpp Normal file
View File

@@ -0,0 +1,120 @@
#pragma once
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
namespace dyna
{
class Player;
class Bomb;
class Monster;
class Vortex;
class World;
// How a tile reacts to an explosion sweeping through it.
enum class Destruction
{
none, // blocks the blast (wall, bomb, existing explosion, vortex)
single, // destroyed and stops the blast (crate)
multi // passable, blast continues (floor)
};
// A grid cell. The C# version used a small class hierarchy rooted at a Field
// interface; since the variants differ only in a couple of flags and how they
// draw, this collapses them into one value type tagged by Kind. Note that in
// the original everything except Wall derived from Floor, so the "is Floor"
// checks there map to "kind != Wall" here.
struct Field
{
enum class Kind
{
floor,
wall,
crate,
bomb, // tile occupied by a live bomb (solid, indestructible)
explosion, // transient blast tile
vortex // level exit portal
};
enum class ExplosionType
{
center,
vertical,
horizontal,
left,
right,
down,
up
};
Kind kind = Kind::floor;
ExplosionType etype = ExplosionType::center;
std::int64_t tstart = 0; // explosion animation start, set on creation
static Field floor() { return Field{}; }
static Field wall() { return Field{ Kind::wall, {}, 0 }; }
static Field crate() { return Field{ Kind::crate, {}, 0 }; }
static Field bomb() { return Field{ Kind::bomb, {}, 0 }; }
static Field vortex() { return Field{ Kind::vortex, {}, 0 }; }
static Field explosion( ExplosionType t );
bool solid() const;
Destruction destructible() const;
void draw( int x, int y ) const;
bool is_floor_family() const { return kind != Kind::wall; }
};
class Map
{
public:
explicit Map( const std::string& fn );
~Map(); // defined in map.cpp where the entity types are complete
Field& at( int x, int y ) { return grid[index( x, y )]; }
const Field& at( int x, int y ) const { return grid[index( x, y )]; }
void draw();
void tick( World& world );
int getx() const { return X; }
int gety() const { return Y; }
int get_crates() const { return destructibles; }
std::unique_ptr<Player> create_player() const;
void place_bomb( int x, int y );
bool monster_collide( int tx, int ty ) const;
private:
static constexpr int X = 13, Y = 11;
// Deferred monster respawn timer, mirroring Map.MWait.
struct MWait
{
int type; // 1, 2 or 3
std::int64_t time; // timestamp at which it respawns
};
static int index( int x, int y ) { return x * Y + y; }
void load( const std::string& fn );
void generate_destructibles();
void populate_map();
bool monster_ok( int rx, int ry, int px, int py, int r ) const;
std::vector<Field> grid;
int px = -10, py = -10;
int destructibles = 0;
int m1 = 0, m2 = 0, m3 = 0;
std::vector<std::unique_ptr<Bomb>> bombs;
std::vector<std::unique_ptr<Monster>> monsters;
std::vector<std::unique_ptr<Vortex>> bonuses;
std::vector<MWait> mwait;
};
}

View File

@@ -0,0 +1,227 @@
#include "monster.hpp"
#include "gfx.hpp"
#include "map.hpp"
#include "texture.hpp"
#include "timer.hpp"
#include "world.hpp"
#include <tracy/Tracy.hpp>
namespace dyna
{
namespace
{
bool is_opposite( Action a, Action b )
{
return ( a == Action::up && b == Action::down ) ||
( a == Action::down && b == Action::up ) ||
( a == Action::left && b == Action::right ) ||
( a == Action::right && b == Action::left );
}
} // namespace
Monster::Monster( int type, int gx, int gy )
: mtype( type )
, t( type == 1 ? 14 : type == 2 ? 11
: 7 )
{
x = gx * 64;
y = gy * 64;
}
void Monster::set_action( Action a )
{
Entity::set_action( a );
if( action == Action::appear )
left = 200;
}
std::vector<Action> Monster::possible_dirs( const Map& map ) const
{
std::vector<Action> dirs;
if( x > 0 && !map.at( x / 64 - 1, y / 64 ).solid() )
dirs.push_back( Action::left );
if( x / 64 < map.getx() - 1 && !map.at( x / 64 + 1, y / 64 ).solid() )
dirs.push_back( Action::right );
if( y > 0 && !map.at( x / 64, y / 64 - 1 ).solid() )
dirs.push_back( Action::up );
if( y / 64 < map.gety() - 1 && !map.at( x / 64, y / 64 + 1 ).solid() )
dirs.push_back( Action::down );
return dirs;
}
bool Monster::straight( const std::vector<Action>& dirs )
{
return is_opposite( dirs[0], dirs[1] );
}
Action Monster::any_dir( const Map& map )
{
std::vector<Action> dirs = possible_dirs( map );
if( dirs.empty() )
return Action::wait;
return dirs[RNG::next( static_cast<int>( dirs.size() ) )];
}
Action Monster::rand_dir( const Map& map )
{
Action tmp = any_dir( map );
if( is_opposite( action, tmp ) )
tmp = any_dir( map );
return tmp;
}
void Monster::think( const Map& map )
{
ZoneScoped;
if( action == Action::wait || action == Action::appear )
{
set_action( rand_dir( map ) );
return;
}
std::vector<Action> dirs = possible_dirs( map );
if( dirs.size() == 2 && straight( dirs ) )
{
left = 64;
}
else
{
Action tmp = rand_dir( map );
if( tmp == action )
{
left = 64;
}
else
{
set_action( tmp );
if( tmp != Action::wait )
left = 64;
}
}
}
void Monster::tick( World& world )
{
ZoneScoped;
Map& map = world.map();
delta += Timer::delta;
while( delta > t )
{
delta -= t;
if( action == Action::wait )
{
think( map );
}
else if( left > 0 )
{
left--;
switch( action )
{
case Action::down: y++; break;
case Action::up: y--; break;
case Action::left: x--; break;
case Action::right: x++; break;
default: break;
}
}
else
{
if( action == Action::death )
die( world );
else
think( map );
}
if( action != Action::death && killed( map ) )
{
set_action( Action::death );
left = 790 / t;
}
}
}
void Monster::die( World& )
{
dead = true;
}
const AnimTexture& Monster::texture_for( Action a ) const
{
struct Set
{
const AnimTexture* wait;
const AnimTexture* up;
const AnimTexture* down;
const AnimTexture* left;
const AnimTexture* right;
const AnimTexture* death;
};
Set s;
if( mtype == 1 )
s = { &Textures::m1_d, &Textures::m1_u, &Textures::m1_d, &Textures::m1_l, &Textures::m1_r, &Textures::m1_death };
else if( mtype == 2 )
s = { &Textures::m2_d, &Textures::m2_u, &Textures::m2_d, &Textures::m2_l, &Textures::m2_r, &Textures::m2_death };
else
s = { &Textures::m3_d, &Textures::m3_u, &Textures::m3_d, &Textures::m3_l, &Textures::m3_r, &Textures::m3_death };
switch( a )
{
case Action::up: return *s.up;
case Action::down: return *s.down;
case Action::left: return *s.left;
case Action::right: return *s.right;
case Action::death: return *s.death;
case Action::wait:
case Action::appear:
default: return *s.wait; // wait/appear use the "down" sprite
}
}
void Monster::draw()
{
ZoneScoped;
// The original returns without drawing for unexpected actions; monsters only
// ever hold the actions handled by texture_for, so always draw.
generic_draw( texture_for( action ) );
}
void Monster::generic_draw( const AnimTexture& tex )
{
int frame;
if( action == Action::wait )
{
frame = 0;
}
else if( action == Action::appear )
{
frame = 0;
Gfx::alpha( static_cast<float>( 200 - left ) / 200.0f );
}
else
{
frame = static_cast<int>( ( Timer::get_timestamp() - action_start ) / 40 );
}
tex.bind( frame );
Gfx::draw_sprite( x, y );
if( action == Action::appear )
Gfx::alpha( 1.0f );
}
}

View File

@@ -0,0 +1,41 @@
#pragma once
#include "entity.hpp"
#include <vector>
namespace dyna
{
class AnimTexture;
// The three monster variants from monster.cs differed only in speed, sprite set
// and respawn delay, so they fold into one class parameterised by `type` (1-3).
class Monster : public Entity
{
public:
Monster( int type, int gx, int gy );
void set_action( Action a ) override;
void tick( World& world ) override;
void draw() override;
void die( World& world ) override;
bool is_dead() const { return dead; }
int type() const { return mtype; }
private:
std::vector<Action> possible_dirs( const Map& map ) const;
static bool straight( const std::vector<Action>& dirs );
Action rand_dir( const Map& map );
Action any_dir( const Map& map ); // __rand_dir in the original
void think( const Map& map );
void generic_draw( const AnimTexture& tex );
const AnimTexture& texture_for( Action a ) const;
int mtype; // 1, 2 or 3
int t; // ms per movement sub-step (per-type speed)
bool dead = false;
};
}

View File

@@ -0,0 +1,127 @@
#include "player.hpp"
#include "gfx.hpp"
#include "map.hpp"
#include "texture.hpp"
#include "timer.hpp"
#include "world.hpp"
#include <tracy/Tracy.hpp>
namespace dyna
{
Player::Player( int gx, int gy )
{
x = gx * 64;
y = gy * 64;
set_action( Action::wait );
queue = Action::wait;
}
void Player::tick( World& world )
{
ZoneScoped;
Map& map = world.map();
delta += Timer::delta;
while( delta > t )
{
delta -= t;
if( left > 0 )
{
left--;
switch( action )
{
case Action::down: y++; break;
case Action::up: y--; break;
case Action::left: x--; break;
case Action::right: x++; break;
case Action::place_bomb:
if( left == 0 )
map.place_bomb( x / 64, y / 64 );
break;
default:
break;
}
}
else
{
if( action == Action::death )
{
die( world );
return;
}
if( map.at( x / 64, y / 64 ).kind == Field::Kind::vortex )
{
world.next_level = true;
return;
}
if( !can_move( queue, map ) )
queue = Action::wait;
if( action != queue )
set_action( queue );
if( action != Action::wait )
left = 64;
if( action == Action::place_bomb )
left = 32;
}
if( action != Action::death && killed( map ) )
{
set_action( Action::death );
left = 1140 / t;
}
}
}
void Player::draw()
{
ZoneScoped;
const AnimTexture* tex = nullptr;
switch( action )
{
case Action::wait: tex = &Textures::p_wait; break;
case Action::up: tex = &Textures::p_u; break;
case Action::down: tex = &Textures::p_d; break;
case Action::left: tex = &Textures::p_l; break;
case Action::right: tex = &Textures::p_r; break;
case Action::death: tex = &Textures::p_death; break;
case Action::place_bomb: tex = &Textures::p_wait; break;
default:
return;
}
int frame = static_cast<int>( Timer::get_timestamp() - action_start );
frame /= ( action == Action::death ) ? 60 : 40;
tex->bind( frame );
Gfx::draw_sprite( x, y );
}
void Player::move( Action a )
{
queue = a;
}
void Player::die( World& world )
{
world.killed = true;
}
bool Player::killed( const Map& map ) const
{
if( Entity::killed( map ) )
return true;
if( map.monster_collide( x, y ) )
return true;
return false;
}
}

View File

@@ -0,0 +1,27 @@
#pragma once
#include "entity.hpp"
namespace dyna
{
class Player : public Entity
{
public:
Player( int gx, int gy );
void tick( World& world ) override;
void draw() override;
void die( World& world ) override;
void move( Action a ); // queues the next direction; applied between tiles
protected:
bool killed( const Map& map ) const override;
private:
static constexpr int t = 6; // ms per movement sub-step
Action queue = Action::wait;
};
}

View File

@@ -0,0 +1,221 @@
#include "texture.hpp"
#include "datapath.hpp"
#include "gfx.hpp"
#include <SDL3/SDL.h>
#include <SDL3_image/SDL_image.h>
#include <tracy/Tracy.hpp>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <memory>
#include <vector>
namespace dyna
{
void GlTexture::reset()
{
if( id_ )
{
// The texture globals outlive main(), so their destructors can run after
// the GL context is already gone (which frees its textures anyway). Only
// call into GL while a context is current; otherwise just drop the name.
if( SDL_GL_GetCurrentContext() )
glDeleteTextures( 1, &id_ );
id_ = 0;
}
}
namespace
{
struct SurfaceDeleter
{
void operator()( SDL_Surface* s ) const { SDL_DestroySurface( s ); }
};
using SurfacePtr = std::unique_ptr<SDL_Surface, SurfaceDeleter>;
// Convert an arbitrary surface to tightly addressable RGBA8. Returns null on
// failure; the result owns its pixels.
SurfacePtr to_rgba( SDL_Surface* src )
{
ZoneScoped;
if( !src ) return nullptr;
return SurfacePtr{ SDL_ConvertSurface( src, SDL_PIXELFORMAT_RGBA32 ) };
}
} // namespace
bool Texture::load( const char* fn )
{
ZoneScoped;
ZoneText( fn, strlen( fn ) );
SurfacePtr image{ IMG_Load( fn ) };
if( !image )
{
std::fprintf( stderr, "Cannot open texture %s: %s\n", fn, SDL_GetError() );
return false;
}
SurfacePtr rgba = to_rgba( image.get() );
if( !rgba )
{
std::fprintf( stderr, "Cannot convert texture %s: %s\n", fn, SDL_GetError() );
return false;
}
// Pack the surface into a tight RGBA8 block, skipping any per-row padding.
const int w = rgba->w, h = rgba->h;
std::vector<std::uint8_t> packed( static_cast<size_t>( w ) * h * 4 );
const auto* pixels = static_cast<const std::uint8_t*>( rgba->pixels );
for( int row = 0; row < h; row++ )
{
std::memcpy( &packed[static_cast<size_t>( row ) * w * 4],
pixels + static_cast<size_t>( row ) * rgba->pitch,
static_cast<size_t>( w ) * 4 );
}
tex_ = GlTexture{ Render::make_texture( w, h, 1, packed.data() ) };
return static_cast<bool>( tex_ );
}
void Texture::bind() const
{
Render::use_texture( tex_.get(), 0 );
}
void AnimTexture::load( SDL_Surface* sheet, int tilex, int tiley, int n )
{
ZoneScoped;
SurfacePtr rgba = to_rgba( sheet );
if( !rgba )
{
std::fprintf( stderr, "Cannot convert sprite sheet: %s\n", SDL_GetError() );
return;
}
const auto* pixels = static_cast<const std::uint8_t*>( rgba->pixels );
const int pitch = rgba->pitch;
// Lay the n frames out back to back as the layers of an array texture.
constexpr int frame_bytes = 64 * 64 * 4;
std::vector<std::uint8_t> frames( static_cast<size_t>( n ) * frame_bytes );
for( int i = 0; i < n; i++ )
{
for( int fy = 0; fy < 64; fy++ )
{
int srcy = 64 * ( tiley + i ) + fy;
int srcx = 64 * tilex;
std::memcpy( &frames[static_cast<size_t>( i ) * frame_bytes + static_cast<size_t>( fy ) * 64 * 4],
pixels + static_cast<size_t>( srcy ) * pitch + static_cast<size_t>( srcx ) * 4,
static_cast<size_t>( 64 ) * 4 );
}
}
tex_ = GlTexture{ Render::make_texture( 64, 64, n, frames.data() ) };
frames_ = n;
}
void AnimTexture::bind( int frame ) const
{
if( frames_ <= 0 ) return;
int layer = frame % frames_;
if( layer < 0 ) layer += frames_;
Render::use_texture( tex_.get(), layer );
}
namespace Textures
{
Texture menu, sand, wall, crate;
AnimTexture p_wait, p_u, p_d, p_l, p_r, p_death;
AnimTexture bomb, bomb_appear, e_c, e_h, e_v, e_le, e_re, e_de, e_ue;
AnimTexture m1_death, m1_l, m1_r, m1_d, m1_u;
AnimTexture m2_death, m2_l, m2_r, m2_d, m2_u;
AnimTexture m3_death, m3_l, m3_r, m3_d, m3_u;
AnimTexture bonus1, bonus2;
AnimTexture vortex_appear, vortex;
void preload()
{
ZoneScoped;
menu.load( data_path( "data/gfx/menu.png" ).c_str() );
sand.load( data_path( "data/gfx/sand.png" ).c_str() );
wall.load( data_path( "data/gfx/wall.png" ).c_str() );
crate.load( data_path( "data/gfx/crate.png" ).c_str() );
{
SurfacePtr img{ IMG_Load( data_path( "data/gfx/Player.png" ).c_str() ) };
p_wait.load( img.get(), 0, 0, 20 );
p_d.load( img.get(), 1, 0, 20 );
p_u.load( img.get(), 2, 0, 20 );
p_l.load( img.get(), 3, 0, 20 );
p_r.load( img.get(), 4, 0, 20 );
p_death.load( img.get(), 5, 0, 20 );
}
{
SurfacePtr img{ IMG_Load( data_path( "data/gfx/Bomb.png" ).c_str() ) };
bomb.load( img.get(), 0, 0, 10 );
bomb_appear.load( img.get(), 5, 0, 10 );
e_c.load( img.get(), 1, 0, 5 );
e_h.load( img.get(), 2, 0, 5 );
e_v.load( img.get(), 1, 5, 5 );
e_le.load( img.get(), 3, 0, 5 );
e_re.load( img.get(), 2, 5, 5 );
e_de.load( img.get(), 4, 0, 5 );
e_ue.load( img.get(), 3, 5, 5 );
}
{
SurfacePtr img{ IMG_Load( data_path( "data/gfx/monster1.png" ).c_str() ) };
m1_death.load( img.get(), 0, 0, 20 );
m1_u.load( img.get(), 1, 0, 10 );
m1_l.load( img.get(), 2, 0, 10 );
m1_d.load( img.get(), 1, 10, 10 );
m1_r.load( img.get(), 2, 10, 10 );
}
{
SurfacePtr img{ IMG_Load( data_path( "data/gfx/monster2.png" ).c_str() ) };
m2_death.load( img.get(), 0, 0, 20 );
m2_d.load( img.get(), 1, 0, 20 );
m2_u.load( img.get(), 2, 0, 20 );
m2_l.load( img.get(), 3, 0, 20 );
m2_r.load( img.get(), 4, 0, 20 );
}
{
SurfacePtr img{ IMG_Load( data_path( "data/gfx/monster3.png" ).c_str() ) };
m3_death.load( img.get(), 0, 0, 20 );
m3_d.load( img.get(), 1, 0, 9 );
m3_u.load( img.get(), 2, 0, 9 );
m3_l.load( img.get(), 1, 10, 9 );
m3_r.load( img.get(), 2, 10, 9 );
}
{
SurfacePtr img{ IMG_Load( data_path( "data/gfx/bonusy.png" ).c_str() ) };
bonus1.load( img.get(), 0, 0, 20 );
bonus2.load( img.get(), 1, 0, 20 );
}
{
SurfacePtr img{ IMG_Load( data_path( "data/gfx/portal.png" ).c_str() ) };
vortex_appear.load( img.get(), 0, 0, 20 );
vortex.load( img.get(), 1, 0, 20 );
}
}
}
}

View File

@@ -0,0 +1,91 @@
#pragma once
#include <glad/gl.h>
struct SDL_Surface;
namespace dyna
{
// Move-only RAII owner of a GL texture name. Every texture in the game is a
// GL_TEXTURE_2D_ARRAY (static images use a single layer, animations use one
// layer per frame) so the renderer only ever has to deal with one sampler type.
class GlTexture
{
public:
GlTexture() = default;
explicit GlTexture( GLuint id ) noexcept : id_( id ) {}
~GlTexture() { reset(); }
GlTexture( GlTexture&& o ) noexcept : id_( o.id_ ) { o.id_ = 0; }
GlTexture& operator=( GlTexture&& o ) noexcept
{
if( this != &o )
{
reset();
id_ = o.id_;
o.id_ = 0;
}
return *this;
}
GlTexture( const GlTexture& ) = delete;
GlTexture& operator=( const GlTexture& ) = delete;
GLuint get() const { return id_; }
explicit operator bool() const { return id_ != 0; }
void reset(); // glDeleteTextures; safe on an empty handle
private:
GLuint id_ = 0;
};
// A single static texture loaded from a whole image file. Ported from
// texture.cs; binding just records the texture for the next draw call.
class Texture
{
public:
bool load( const char* fn );
void bind() const;
private:
GlTexture tex_;
};
// A vertical strip of 64x64 animation frames cut out of a sprite sheet, stored
// as the layers of one array texture. Mirrors AnimTexture in texture.cs.
class AnimTexture
{
public:
// Extract n frames from column `tilex`, starting at row `tiley`, where each
// coordinate is in 64px tile units. Mirrors AnimTexture.load in texture.cs.
void load( SDL_Surface* sheet, int tilex, int tiley, int n );
void bind( int frame ) const; // frame is taken modulo the frame count
private:
GlTexture tex_;
int frames_ = 0;
};
// All game textures, loaded once at startup. Mirrors the Textures class.
namespace Textures
{
extern Texture menu, sand, wall, crate;
extern AnimTexture p_wait, p_u, p_d, p_l, p_r, p_death;
extern AnimTexture bomb, bomb_appear, e_c, e_h, e_v, e_le, e_re, e_de, e_ue;
extern AnimTexture m1_death, m1_l, m1_r, m1_d, m1_u;
extern AnimTexture m2_death, m2_l, m2_r, m2_d, m2_u;
extern AnimTexture m3_death, m3_l, m3_r, m3_d, m3_u;
extern AnimTexture bonus1, bonus2;
extern AnimTexture vortex_appear, vortex;
void preload();
}
}

View File

@@ -0,0 +1,51 @@
#include "timer.hpp"
#include <SDL3/SDL.h>
#include <random>
namespace dyna
{
namespace Timer
{
int delta = 0;
static std::int64_t timestamp = 0;
void reset()
{
delta = 0;
timestamp = static_cast<std::int64_t>( SDL_GetTicks() );
}
int tick()
{
std::int64_t tmp = timestamp;
timestamp = static_cast<std::int64_t>( SDL_GetTicks() );
delta = static_cast<int>( timestamp - tmp );
return delta;
}
std::int64_t get_timestamp()
{
return timestamp;
}
}
namespace RNG
{
static std::mt19937& engine()
{
static std::mt19937 e{ std::random_device{}() };
return e;
}
int next( int n )
{
if( n <= 0 ) return 0;
std::uniform_int_distribution<int> dist( 0, n - 1 );
return dist( engine() );
}
}
}

View File

@@ -0,0 +1,25 @@
#pragma once
#include <cstdint>
namespace dyna
{
// Frame timing, ported from timer.cs. Timestamps are milliseconds since
// Timer::reset(); kept 64-bit so the modulo arithmetic the animation code
// relies on never overflows during a session.
namespace Timer
{
void reset();
int tick(); // advances the clock, returns delta in ms
std::int64_t get_timestamp();
extern int delta; // ms elapsed during the last tick()
}
// Thin wrapper over a single global PRNG, mirroring the C# RNG helper.
namespace RNG
{
int next( int n ); // uniform in [0, n)
}
}

View File

@@ -0,0 +1,40 @@
#include "world.hpp"
#include "map.hpp"
#include "player.hpp"
namespace dyna
{
World::World( const std::string& level_fn, bool with_player )
: map_( std::make_unique<Map>( level_fn ) )
, name_( level_fn.substr( level_fn.rfind( '/' ) + 1 ) )
{
if( with_player )
{
player_ = map_->create_player();
crates_left = map_->get_crates();
}
else
{
crates_left = -1; // the menu never opens an exit portal
}
}
World::~World() = default;
void World::tick()
{
map_->tick( *this );
if( player_ )
player_->tick( *this );
}
void World::draw()
{
map_->draw();
if( player_ )
player_->draw();
}
}

View File

@@ -0,0 +1,46 @@
#pragma once
#include <memory>
#include <string>
namespace dyna
{
class Map;
class Player;
// Owns the state for one running level: the map, the player (absent on the
// menu screen), and the flags the gameplay code used to reach through global
// variables. Passing a World& into the tick path replaces the old Game::p /
// Game::current_map / Game::killed globals, so there are no non-owning pointers
// to outlive the objects they point at.
class World
{
public:
// Loads `level_fn`; spawns a player from the map's '@' marker when
// with_player is set (gameplay) and leaves it null otherwise (menu).
World( const std::string& level_fn, bool with_player );
~World();
World( const World& ) = delete;
World& operator=( const World& ) = delete;
Map& map() { return *map_; }
const Map& map() const { return *map_; }
Player* player() { return player_.get(); } // null on the menu screen
const std::string& name() const { return name_; }
void tick();
void draw();
bool killed = false;
bool next_level = false;
int crates_left = 0;
private:
std::unique_ptr<Map> map_;
std::unique_ptr<Player> player_;
std::string name_;
};
}

View File

@@ -0,0 +1,83 @@
# CMakeLists.txt — OpenGL spinning triangle demo
#
# macOS:
# cmake -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -B build/ninja .
# cmake --build build/ninja
#
# Linux (requires libsdl3-dev libgl1-mesa-dev):
# cmake -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -B build/ninja .
# cmake --build build/ninja
#
# Windows:
# cmake -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -B build/ninja .
# cmake --build build/ninja
cmake_minimum_required(VERSION 3.16)
project(gl_spinning_triangle LANGUAGES C CXX)
# ---------------------------------------------------------------------------
# Tracy root — defaults to three directories above this CMakeLists.txt.
# ---------------------------------------------------------------------------
set(TRACY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../..")
option(TRACY_ENABLE "Enable Tracy profiling" ON)
# ---------------------------------------------------------------------------
# Platform — SDL3 (cross-platform windowing, must be installed on the system)
# ---------------------------------------------------------------------------
find_package(SDL3 REQUIRED)
# ---------------------------------------------------------------------------
# GL extension loader — GLEW (Windows + Linux, fetched automatically)
# ---------------------------------------------------------------------------
if(NOT APPLE)
include(FetchContent)
set(glew-cmake_BUILD_SHARED OFF CACHE BOOL "" FORCE)
set(ONLY_LIBS ON CACHE BOOL "" FORCE)
FetchContent_Declare(glew
GIT_REPOSITORY https://github.com/Perlmint/glew-cmake.git
GIT_TAG master # pin to a specific commit for reproducible builds
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(glew)
endif()
set(PLATFORM_SOURCES platform/platform_sdl3.cpp)
if(APPLE)
set(PLATFORM_LIBS SDL3::SDL3 "-framework OpenGL")
elseif(WIN32)
set(PLATFORM_LIBS SDL3::SDL3 opengl32 libglew_static)
else()
set(PLATFORM_LIBS SDL3::SDL3 GL libglew_static)
endif()
# ---------------------------------------------------------------------------
# Target
# ---------------------------------------------------------------------------
add_executable(gl_spinning_triangle
spinning_triangle.cpp
"${TRACY_DIR}/public/TracyClient.cpp"
${PLATFORM_SOURCES}
)
# Suppress upstream warnings from TracyClient.cpp
if(MSVC)
set_source_files_properties("${TRACY_DIR}/public/TracyClient.cpp"
PROPERTIES COMPILE_FLAGS "/w"
)
else()
set_source_files_properties("${TRACY_DIR}/public/TracyClient.cpp"
PROPERTIES COMPILE_FLAGS "-w"
)
endif()
target_compile_features(gl_spinning_triangle PRIVATE cxx_std_17)
if(TRACY_ENABLE)
target_compile_definitions(gl_spinning_triangle PRIVATE TRACY_ENABLE)
endif()
target_include_directories(gl_spinning_triangle PRIVATE
"${TRACY_DIR}/public"
)
target_link_libraries(gl_spinning_triangle PRIVATE ${PLATFORM_LIBS})

View File

@@ -0,0 +1,37 @@
// platform.h — interface between platform-agnostic code and platform backends
//
// Each platform_*.mm / platform_*.cpp file implements these four functions.
// Exactly one backend must be linked into the final binary.
#pragma once
#ifdef __APPLE__
# include <OpenGL/gl3.h>
#else
# include <GL/glew.h>
#endif
// Initialize the windowing system, create a window, and make an OpenGL 3.3
// Core Profile context current on the calling thread.
// Returns true on success.
bool platformInit(int width, int height, const char* title);
// Load OpenGL function pointers (no-op on macOS where the framework exports them directly).
// Must be called after platformInit() while the GL context is current.
// Returns true on success.
bool platformInitGL();
// Elapsed wall-clock time in seconds since platformInit().
double platformGetTime();
// Swap front and back buffers (present the rendered frame).
void platformSwapBuffers();
// Pixel scaling factor relative to the logical window size (1.0 on non-HiDPI displays).
// Must be called after platformInit().
void platformGetPixelDensityScale(float* x, float* y);
// Enter the platform event/render loop.
// Calls render() each frame at ~60 fps.
// Calls shutdown() exactly once before returning.
void platformRunLoop(void (*render)(), void (*shutdown)());

View File

@@ -0,0 +1,85 @@
// platform_sdl3.cpp — SDL3 windowing backend (cross-platform)
#include "platform.h" // GL headers first (gl3.h / glew.h) so SDL sees guards set
#define SDL_MAIN_HANDLED // we don't want SDL_main
#include <SDL3/SDL.h>
#include <chrono>
#include <cstdio>
static SDL_Window* sWin = nullptr;
static SDL_GLContext sCtx = nullptr;
static std::chrono::steady_clock::time_point sStartTime;
bool platformInit(int width, int height, const char* title) {
if (!SDL_Init(SDL_INIT_VIDEO)) {
fprintf(stderr, "ERROR: SDL_Init failed: %s\n", SDL_GetError());
return false;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
sWin = SDL_CreateWindow(title, width, height, SDL_WINDOW_OPENGL);
if (!sWin) {
fprintf(stderr, "ERROR: SDL_CreateWindow failed: %s\n", SDL_GetError());
SDL_Quit();
return false;
}
SDL_SetWindowPosition(sWin, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
sCtx = SDL_GL_CreateContext(sWin);
if (!sCtx) {
fprintf(stderr, "ERROR: SDL_GL_CreateContext failed: %s\n", SDL_GetError());
SDL_DestroyWindow(sWin);
SDL_Quit();
return false;
}
SDL_GL_SetSwapInterval(1);
sStartTime = std::chrono::steady_clock::now();
return true;
}
bool platformInitGL() {
#ifndef __APPLE__
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return false;
}
#endif
return true;
}
double platformGetTime() {
return std::chrono::duration<double>(
std::chrono::steady_clock::now() - sStartTime).count();
}
void platformSwapBuffers() { SDL_GL_SwapWindow(sWin); }
void platformGetPixelDensityScale(float* x, float* y) {
int pw, ph, ww, wh;
SDL_GetWindowSizeInPixels(sWin, &pw, &ph);
SDL_GetWindowSize(sWin, &ww, &wh);
*x = (ww > 0) ? (float)pw / (float)ww : 1.0f;
*y = (wh > 0) ? (float)ph / (float)wh : 1.0f;
}
void platformRunLoop(void (*render)(), void (*shutdown)()) {
bool running = true;
while (running) {
SDL_Event e;
while (SDL_PollEvent(&e)) {
if (e.type == SDL_EVENT_QUIT) running = false;
if (e.type == SDL_EVENT_KEY_DOWN && e.key.key == SDLK_ESCAPE) running = false;
}
if (running) render();
}
shutdown();
SDL_GL_DestroyContext(sCtx);
SDL_DestroyWindow(sWin);
SDL_Quit();
}

View File

@@ -0,0 +1,145 @@
// spinning_triangle.cpp — OpenGL spinning triangle demo with Tracy GPU profiling.
#ifdef __APPLE__
// NOTE: OpenGL is only available on MacOS (no iOS support)
// Including and using anything related to OpenGL on Apple (like <OpenGL/gl3.h>)
// will emit deprecation warnings, unless GL_SILENCE_DEPRECATION is defined
#define GL_SILENCE_DEPRECATION
// NOTE: TracyOpenGL.hpp will not work as expected even on Apple devices that
// support OpenGL, because the OpenGL drivers do not implement ARB_timer_query
// properly (querying GL_TIMESTAMP always resolves to 0). TracyOpenGL.hpp will
// emit a compiler warning, and a Tracy message to the trace/profiler, but the
// program will still run.
#endif
#include "platform/platform.h" // also includes OpenGL headers
#include <tracy/Tracy.hpp>
// NOTE: opt-in toggle for periodic recalibrations during Collect()
#define TRACY_OPENGL_AUTO_CALIBRATION
#include <tracy/TracyOpenGL.hpp>
static const int kWidth = 800;
static const int kHeight = 600;
static GLuint gProgram = 0;
static GLuint gVao = 0;
static GLint gAngleLoc = -1;
// Vertex colors and positions are baked in; rotation is driven by a uniform.
static const char* kVertSrc = R"(
#version 150 core
uniform float uAngle;
const vec2 kPos[3] = vec2[3](
vec2( 0.0, 0.5 ),
vec2(-0.433, -0.25 ),
vec2( 0.433, -0.25 )
);
const vec3 kCol[3] = vec3[3](
vec3(1.0, 0.0, 0.0),
vec3(0.0, 1.0, 0.0),
vec3(0.0, 0.0, 1.0)
);
out vec3 vColor;
void main() {
float c = cos(uAngle);
float s = sin(uAngle);
vec2 p = kPos[gl_VertexID];
gl_Position = vec4(p.x*c - p.y*s, p.x*s + p.y*c, 0.0, 1.0);
vColor = kCol[gl_VertexID];
}
)";
static const char* kFragSrc = R"(
#version 150 core
in vec3 vColor;
out vec4 fragColor;
void main() { fragColor = vec4(vColor, 1.0); }
)";
static GLuint compileShader(GLenum type, const char* src) {
GLuint s = glCreateShader(type);
glShaderSource(s, 1, &src, nullptr);
glCompileShader(s);
GLint ok = 0;
glGetShaderiv(s, GL_COMPILE_STATUS, &ok);
if (!ok) {
char log[512];
glGetShaderInfoLog(s, sizeof(log), nullptr, log);
fprintf(stderr, "Shader compile error: %s\n", log);
glDeleteShader(s);
return 0;
}
return s;
}
static int initGL() {
if (!platformInitGL()) return 1;
TracyGpuContext;
TracyGpuContextName("OpenGL", 6);
GLuint vert = compileShader(GL_VERTEX_SHADER, kVertSrc);
GLuint frag = compileShader(GL_FRAGMENT_SHADER, kFragSrc);
if (!vert || !frag) return 1;
gProgram = glCreateProgram();
glAttachShader(gProgram, vert);
glAttachShader(gProgram, frag);
glLinkProgram(gProgram);
glDeleteShader(vert);
glDeleteShader(frag);
GLint ok = 0;
glGetProgramiv(gProgram, GL_LINK_STATUS, &ok);
if (!ok) {
char log[512];
glGetProgramInfoLog(gProgram, sizeof(log), nullptr, log);
fprintf(stderr, "Program link error: %s\n", log);
return 1;
}
gAngleLoc = glGetUniformLocation(gProgram, "uAngle");
// Core profile requires a bound VAO even with no vertex attributes.
glGenVertexArrays(1, &gVao);
glBindVertexArray(gVao);
glClearColor(0.05f, 0.05f, 0.08f, 1.0f);
float scaleX, scaleY;
platformGetPixelDensityScale(&scaleX, &scaleY);
glViewport(0, 0, (int)(kWidth * scaleX), (int)(kHeight * scaleY));
return 0;
}
static void renderFrame() {
ZoneScoped;
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(gProgram);
{
TracyGpuZone("triangle draw");
glUniform1f(gAngleLoc, (float)platformGetTime());
glDrawArrays(GL_TRIANGLES, 0, 3);
}
platformSwapBuffers();
TracyGpuCollect;
}
static void shutdown() {
fprintf(stderr, "application is shutting down...\n");
glDeleteVertexArrays(1, &gVao);
glDeleteProgram(gProgram);
}
int main() {
if (!platformInit(kWidth, kHeight, "OpenGL Spinning Triangle"))
return 1;
if (initGL() != 0)
return 2;
platformRunLoop(renderFrame, shutdown);
return 0;
}

View File

@@ -0,0 +1,157 @@
# CMakeLists.txt — WebGPU spinning triangle demo
#
# macOS:
# clang++ -std=c++17 -ObjC++ spinning_triangle.cpp platform/platform_macos.mm \
# -I/path/to/wgpu/include -L/path/to/wgpu/lib -lwgpu_native \
# -Wl,-rpath,@executable_path \
# -framework Cocoa -framework Metal -framework QuartzCore \
# -framework Foundation -framework IOKit -framework IOSurface \
# -o spinning_triangle
#
# Windows (MSVC):
# cl /std:c++17 spinning_triangle.cpp platform/platform_windows.cpp \
# /I\path\to\wgpu\include \path\to\wgpu\lib\wgpu_native.lib \
# user32.lib gdi32.lib /Fe:spinning_triangle.exe
#
# Linux (requires libsdl3-dev):
# g++ -std=c++17 spinning_triangle.cpp platform/platform_wayland.cpp \
# xdg-shell-protocol.c \
# -I/path/to/wgpu/include -L/path/to/wgpu/lib -lwgpu_native \
# -lwayland-client -o spinning_triangle
cmake_minimum_required(VERSION 3.16)
project(spinning_triangle LANGUAGES C CXX)
# ---------------------------------------------------------------------------
# WebGPU backend — set WGPU_PATH to your wgpu-native or Dawn installation.
# The library name differs between backends:
# wgpu-native → wgpu_native
# Dawn → webgpu_dawn
# ---------------------------------------------------------------------------
set(WGPU_PATH "" CACHE PATH "Root of the WebGPU native installation (contains include/ and lib/)")
set(WGPU_LIB "" CACHE STRING "WebGPU library name (wgpu_native or webgpu_dawn); auto-detected if empty")
if(NOT WGPU_PATH)
message(FATAL_ERROR "Set WGPU_PATH to the root of your WebGPU native installation.")
endif()
# When WGPU_PATH changes, discard any previously auto-detected WGPU_LIB so
# detection re-runs against the new path.
if(NOT "${WGPU_PATH}" STREQUAL "${_WGPU_PATH_LAST}")
unset(WGPU_LIB CACHE)
set(WGPU_LIB "" CACHE STRING "WebGPU library name (wgpu_native or webgpu_dawn); auto-detected if empty")
endif()
set(_WGPU_PATH_LAST "${WGPU_PATH}" CACHE INTERNAL "")
if(NOT WGPU_LIB)
unset(_WGPU_NATIVE_LIB CACHE)
unset(_WEBGPU_DAWN_LIB CACHE)
find_library(_WGPU_NATIVE_LIB NAMES wgpu_native wgpu_native.dll PATHS "${WGPU_PATH}/lib" NO_DEFAULT_PATH)
find_library(_WEBGPU_DAWN_LIB NAMES webgpu_dawn PATHS "${WGPU_PATH}/lib" NO_DEFAULT_PATH)
if(_WGPU_NATIVE_LIB)
set(WGPU_LIB "wgpu_native" CACHE STRING "WebGPU library name (wgpu_native or webgpu_dawn); auto-detected if empty" FORCE)
elseif(_WEBGPU_DAWN_LIB)
set(WGPU_LIB "webgpu_dawn" CACHE STRING "WebGPU library name (wgpu_native or webgpu_dawn); auto-detected if empty" FORCE)
else()
message(FATAL_ERROR "Could not detect a WebGPU library in ${WGPU_PATH}/lib. Set WGPU_LIB explicitly (wgpu_native or webgpu_dawn).")
endif()
message(STATUS "WebGPU library auto-detected: ${WGPU_LIB}")
endif()
# ---------------------------------------------------------------------------
# Tracy root — defaults to two directories above this CMakeLists.txt.
# ---------------------------------------------------------------------------
set(TRACY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../..")
option(TRACY_ENABLE "Enable Tracy profiling" ON)
# ---------------------------------------------------------------------------
# macOS quarantine — pre-built WebGPU binaries downloaded from the internet
# carry a com.apple.quarantine extended attribute that prevents dyld from
# loading them ("damaged or incomplete" / Gatekeeper block). Strip it once
# at configure time so the linker and the runtime loader can both access the
# library directory without further user intervention.
# ---------------------------------------------------------------------------
if(APPLE)
execute_process(
COMMAND xattr -dr com.apple.quarantine "${WGPU_PATH}/lib"
)
endif()
# ---------------------------------------------------------------------------
# Platform — SDL3 (cross-platform windowing, must be installed on the system)
# ---------------------------------------------------------------------------
find_package(SDL3 REQUIRED)
set(PLATFORM_SOURCES platform/platform_sdl3.cpp)
if(APPLE)
set(PLATFORM_LIBS
SDL3::SDL3
"-framework Cocoa"
"-framework Metal"
"-framework QuartzCore"
"-framework Foundation"
"-framework IOKit"
"-framework IOSurface"
)
elseif(WIN32)
# wgpu-native (Rust stdlib) pull-ins: NtReadFile, GetUserProfileDirectoryW, ...
set(WGPU_NATIVE_WIN32_LIBS ntdll userenv)
# Dawn pull-ins: WKPDID_D3DDebugObjectName GUID, CompareObjectHandles, ...
set(WEBGPU_DAWN_WIN32_LIBS dxguid onecore)
set(PLATFORM_LIBS SDL3::SDL3 ${WGPU_NATIVE_WIN32_LIBS} ${WEBGPU_DAWN_WIN32_LIBS})
else()
set(PLATFORM_LIBS SDL3::SDL3)
endif()
# ---------------------------------------------------------------------------
# Target
# ---------------------------------------------------------------------------
add_executable(spinning_triangle
spinning_triangle.cpp
"${TRACY_DIR}/public/TracyClient.cpp"
${PLATFORM_SOURCES}
)
# Treat TracyClient.cpp as third-party code — suppress all warnings so that
# upstream changes don't pollute our build output.
if(MSVC)
set_source_files_properties("${TRACY_DIR}/public/TracyClient.cpp"
PROPERTIES COMPILE_FLAGS "/w"
)
else()
set_source_files_properties("${TRACY_DIR}/public/TracyClient.cpp"
PROPERTIES COMPILE_FLAGS "-w"
)
endif()
target_compile_features(spinning_triangle PRIVATE cxx_std_17)
if(TRACY_ENABLE)
target_compile_definitions(spinning_triangle PRIVATE TRACY_ENABLE)
endif()
target_include_directories(spinning_triangle PRIVATE
"${WGPU_PATH}/include"
"${TRACY_DIR}/public"
)
target_link_directories(spinning_triangle PRIVATE "${WGPU_PATH}/lib")
target_link_libraries(spinning_triangle PRIVATE
${WGPU_LIB}
${PLATFORM_LIBS}
)
# Embed the rpath so the binary finds the WebGPU dylib/so next to itself.
if(APPLE)
set_target_properties(spinning_triangle PROPERTIES
BUILD_RPATH "${WGPU_PATH}/lib"
INSTALL_RPATH "@executable_path"
)
elseif(UNIX)
set_target_properties(spinning_triangle PROPERTIES
BUILD_RPATH "${WGPU_PATH}/lib"
INSTALL_RPATH "$ORIGIN"
)
endif()

View File

@@ -0,0 +1,23 @@
// platform.h — interface between platform-agnostic code and platform backends
//
// Each platform_*.mm / platform_*.cpp file implements these five functions.
// Exactly one backend must be linked into the final binary.
#pragma once
#include <webgpu/webgpu.h>
// Initialize the windowing system and create a window of the given dimensions.
// Returns true on success.
bool platformInit(int width, int height, const char* title);
// Create a WebGPU surface backed by the platform window.
// Must be called after wgpuCreateInstance() and platformInit().
WGPUSurface platformCreateSurface(WGPUInstance instance);
// Elapsed wall-clock time in seconds since platformInit().
double platformGetTime();
// Enter the platform event/render loop.
// Calls render() each frame at ~60 fps.
// Calls shutdown() exactly once before returning.
void platformRunLoop(void (*render)(), void (*shutdown)());

View File

@@ -0,0 +1,95 @@
// platform_sdl3.cpp — SDL3 windowing backend for the WebGPU example
#include "platform.h" // webgpu/webgpu.h first
#define SDL_MAIN_HANDLED // we don't want SDL_main
#include <SDL3/SDL.h>
#ifdef __APPLE__
# include <SDL3/SDL_metal.h>
#endif
#include <chrono>
#include <cstdio>
static SDL_Window* sWin = nullptr;
static std::chrono::steady_clock::time_point sStartTime;
#ifdef __APPLE__
static SDL_MetalView sMetalView = nullptr;
#endif
bool platformInit(int width, int height, const char* title) {
if (!SDL_Init(SDL_INIT_VIDEO)) {
fprintf(stderr, "ERROR: SDL_Init failed: %s\n", SDL_GetError());
return false;
}
SDL_WindowFlags flags = 0;
#ifdef __APPLE__
flags |= SDL_WINDOW_METAL;
#endif
sWin = SDL_CreateWindow(title, width, height, flags);
if (!sWin) {
fprintf(stderr, "ERROR: SDL_CreateWindow failed: %s\n", SDL_GetError());
SDL_Quit();
return false;
}
SDL_SetWindowPosition(sWin, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
sStartTime = std::chrono::steady_clock::now();
return true;
}
WGPUSurface platformCreateSurface(WGPUInstance instance) {
WGPUSurfaceDescriptor desc = {};
SDL_PropertiesID props = SDL_GetWindowProperties(sWin);
#if defined(__APPLE__)
sMetalView = SDL_Metal_CreateView(sWin);
if (!sMetalView) {
fprintf(stderr, "ERROR: SDL_Metal_CreateView failed\n");
return nullptr;
}
WGPUSurfaceSourceMetalLayer metalDesc = {};
metalDesc.chain.sType = WGPUSType_SurfaceSourceMetalLayer;
metalDesc.layer = SDL_Metal_GetLayer(sMetalView);
desc.nextInChain = &metalDesc.chain;
#elif defined(_WIN32)
WGPUSurfaceSourceWindowsHWND hwndDesc = {};
hwndDesc.chain.sType = WGPUSType_SurfaceSourceWindowsHWND;
hwndDesc.hinstance = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WIN32_INSTANCE_POINTER, nullptr);
hwndDesc.hwnd = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WIN32_HWND_POINTER, nullptr);
desc.nextInChain = &hwndDesc.chain;
#else // Linux / X11
WGPUSurfaceSourceXlibWindow x11Desc = {};
x11Desc.chain.sType = WGPUSType_SurfaceSourceXlibWindow;
x11Desc.display = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_X11_DISPLAY_POINTER, nullptr);
x11Desc.window = (uint32_t)SDL_GetNumberProperty(props, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
desc.nextInChain = &x11Desc.chain;
#endif
return wgpuInstanceCreateSurface(instance, &desc);
}
double platformGetTime() {
return std::chrono::duration<double>(
std::chrono::steady_clock::now() - sStartTime).count();
}
void platformRunLoop(void (*render)(), void (*shutdown)()) {
bool running = true;
while (running) {
SDL_Event e;
while (SDL_PollEvent(&e)) {
if (e.type == SDL_EVENT_QUIT) running = false;
if (e.type == SDL_EVENT_KEY_DOWN && e.key.key == SDLK_ESCAPE) running = false;
}
if (running) render();
}
shutdown();
#ifdef __APPLE__
SDL_Metal_DestroyView(sMetalView);
#endif
SDL_DestroyWindow(sWin);
SDL_Quit();
}

View File

@@ -0,0 +1,352 @@
// spinning_triangle.cpp — platform-agnostic WebGPU spinning triangle demo.
#include "platform/platform.h"
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <webgpu/webgpu.h>
#include <tracy/Tracy.hpp>
#include <tracy/TracyWebGPU.hpp>
// ---------------------------------------------------------------------------
// Globals
// ---------------------------------------------------------------------------
static const int kWidth = 800;
static const int kHeight = 600;
static WGPUInstance gInstance = nullptr;
static WGPUSurface gSurface = nullptr;
static WGPUAdapter gAdapter = nullptr;
static WGPUDevice gDevice = nullptr;
static WGPUQueue gQueue = nullptr;
static WGPURenderPipeline gPipeline = nullptr;
static WGPUBuffer gUniformBuf = nullptr;
static WGPUBindGroup gBindGroup = nullptr;
static TracyWebGPUCtx gTracyCtx = nullptr;
static WGPUTextureFormat gSurfaceFormat = WGPUTextureFormat_BGRA8Unorm;
// TODO: this can become platformError() instead
int error(int code, const char* message) {
fprintf(stderr, "ERROR: %s (code: %d)\n", message, code);
return code;
}
// ---------------------------------------------------------------------------
// WGSL shader — vertex colours baked in, rotation via a uniform float.
// ---------------------------------------------------------------------------
static const char* kShaderSource = R"(
struct Uniforms {
angle: f32,
};
@group(0) @binding(0) var<uniform> u: Uniforms;
struct VSOut {
@builtin(position) pos: vec4f,
@location(0) color: vec3f,
};
@vertex
fn vs_main(@builtin(vertex_index) vi: u32) -> VSOut {
var positions = array<vec2f, 3>(
vec2f( 0.0, 0.5),
vec2f(-0.433, -0.25),
vec2f( 0.433, -0.25),
);
var colors = array<vec3f, 3>(
vec3f(1.0, 0.0, 0.0),
vec3f(0.0, 1.0, 0.0),
vec3f(0.0, 0.0, 1.0),
);
let c = cos(u.angle);
let s = sin(u.angle);
let p = positions[vi];
let rotated = vec2f(p.x * c - p.y * s, p.x * s + p.y * c);
var out: VSOut;
out.pos = vec4f(rotated, 0.0, 1.0);
out.color = colors[vi];
return out;
}
@fragment
fn fs_main(@location(0) color: vec3f) -> @location(0) vec4f {
return vec4f(color, 1.0);
}
)";
// ---------------------------------------------------------------------------
// Adapter / Device request callbacks (current wgpu-native API)
// ---------------------------------------------------------------------------
static void onAdapterReady(WGPURequestAdapterStatus status,
WGPUAdapter adapter,
WGPUStringView message,
void* userdata1, void* /*userdata2*/) {
if (status == WGPURequestAdapterStatus_Success) {
*(WGPUAdapter*)userdata1 = adapter;
} else {
fprintf(stderr, "Adapter request failed: %.*s\n",
(int)message.length, message.data);
}
}
static void onDeviceReady(WGPURequestDeviceStatus status,
WGPUDevice device,
WGPUStringView message,
void* userdata1, void* /*userdata2*/) {
if (status == WGPURequestDeviceStatus_Success) {
*(WGPUDevice*)userdata1 = device;
} else {
fprintf(stderr, "Device request failed: %.*s\n",
(int)message.length, message.data);
}
}
// ---------------------------------------------------------------------------
// WebGPU init
// ---------------------------------------------------------------------------
static int initWebGPU() {
// Adapter
WGPURequestAdapterOptions adapterOpts = {};
adapterOpts.compatibleSurface = gSurface;
WGPURequestAdapterCallbackInfo adapterCB = {};
adapterCB.mode = WGPUCallbackMode_AllowProcessEvents;
adapterCB.callback = onAdapterReady;
adapterCB.userdata1 = &gAdapter;
wgpuInstanceRequestAdapter(gInstance, &adapterOpts, adapterCB);
while (!gAdapter) { wgpuInstanceProcessEvents(gInstance); }
if (!gAdapter) return error(11, "No adapter");
WGPUUncapturedErrorCallbackInfo errorCB = {};
errorCB.callback = [](WGPUDevice const*, WGPUErrorType type,
WGPUStringView message, void*, void*) {
fprintf(stderr, "[WGPU ERROR] type=%d %.*s\n",
(int)type, (int)message.length, message.data);
};
WGPUDeviceDescriptor deviceDesc = {};
deviceDesc.uncapturedErrorCallbackInfo = errorCB;
TracyWebGPUSetupDeviceDescriptor(deviceDesc);
WGPURequestDeviceCallbackInfo deviceCB = {};
deviceCB.mode = WGPUCallbackMode_AllowProcessEvents;
deviceCB.callback = onDeviceReady;
deviceCB.userdata1 = &gDevice;
wgpuAdapterRequestDevice(gAdapter, &deviceDesc, deviceCB);
while (!gDevice) { wgpuInstanceProcessEvents(gInstance); }
if (!gDevice) return error(12, "No device");
gQueue = wgpuDeviceGetQueue(gDevice);
gTracyCtx = TracyWebGPUContext(gInstance, gDevice, gQueue);
TracyWebGPUContextName(gTracyCtx, "WebGPU", 6);
// Configure surface
WGPUSurfaceConfiguration config = {};
config.device = gDevice;
config.format = gSurfaceFormat;
config.usage = WGPUTextureUsage_RenderAttachment;
config.alphaMode = WGPUCompositeAlphaMode_Opaque;
config.width = kWidth;
config.height = kHeight;
config.presentMode = WGPUPresentMode_Fifo;
wgpuSurfaceConfigure(gSurface, &config);
// Shader module
WGPUShaderSourceWGSL wgslSrc = {};
wgslSrc.chain.sType = WGPUSType_ShaderSourceWGSL;
wgslSrc.code = { kShaderSource, WGPU_STRLEN };
WGPUShaderModuleDescriptor smDesc = {};
smDesc.nextInChain = (WGPUChainedStruct*)&wgslSrc;
WGPUShaderModule shaderMod = wgpuDeviceCreateShaderModule(gDevice, &smDesc);
// Uniform buffer (one f32 for rotation angle)
WGPUBufferDescriptor bufDesc = {};
bufDesc.usage = WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst;
bufDesc.size = sizeof(float);
gUniformBuf = wgpuDeviceCreateBuffer(gDevice, &bufDesc);
// Bind group layout + bind group
WGPUBindGroupLayoutEntry bglEntry = {};
bglEntry.binding = 0;
bglEntry.visibility = WGPUShaderStage_Vertex;
bglEntry.buffer.type = WGPUBufferBindingType_Uniform;
bglEntry.buffer.minBindingSize = sizeof(float);
WGPUBindGroupLayoutDescriptor bglDesc = {};
bglDesc.entryCount = 1;
bglDesc.entries = &bglEntry;
WGPUBindGroupLayout bgl = wgpuDeviceCreateBindGroupLayout(gDevice, &bglDesc);
WGPUBindGroupEntry bgEntry = {};
bgEntry.binding = 0;
bgEntry.buffer = gUniformBuf;
bgEntry.size = sizeof(float);
WGPUBindGroupDescriptor bgDesc = {};
bgDesc.layout = bgl;
bgDesc.entryCount = 1;
bgDesc.entries = &bgEntry;
gBindGroup = wgpuDeviceCreateBindGroup(gDevice, &bgDesc);
// Pipeline layout
WGPUPipelineLayoutDescriptor plDesc = {};
plDesc.bindGroupLayoutCount = 1;
plDesc.bindGroupLayouts = &bgl;
WGPUPipelineLayout pipelineLayout = wgpuDeviceCreatePipelineLayout(gDevice, &plDesc);
// Render pipeline
WGPUColorTargetState colorTarget = {};
colorTarget.format = gSurfaceFormat;
colorTarget.writeMask = WGPUColorWriteMask_All;
WGPUFragmentState fragState = {};
fragState.module = shaderMod;
fragState.entryPoint = { "fs_main", WGPU_STRLEN };
fragState.targetCount = 1;
fragState.targets = &colorTarget;
WGPURenderPipelineDescriptor rpDesc = {};
rpDesc.layout = pipelineLayout;
rpDesc.vertex.module = shaderMod;
rpDesc.vertex.entryPoint = { "vs_main", WGPU_STRLEN };
rpDesc.primitive.topology = WGPUPrimitiveTopology_TriangleList;
rpDesc.multisample.count = 1;
rpDesc.multisample.mask = 0xFFFFFFFF;
rpDesc.fragment = &fragState;
gPipeline = wgpuDeviceCreateRenderPipeline(gDevice, &rpDesc);
// Cleanup intermediates
wgpuShaderModuleRelease(shaderMod);
wgpuPipelineLayoutRelease(pipelineLayout);
wgpuBindGroupLayoutRelease(bgl);
return 0;
}
// ---------------------------------------------------------------------------
// Frame rendering
// ---------------------------------------------------------------------------
// Returns the surface texture for the current frame, or {.texture=nullptr} on
// a skippable condition (timeout, occlusion) or an error.
static WGPUSurfaceTexture getWindowSurface() {
WGPUSurfaceTexture surfTex = {};
wgpuSurfaceGetCurrentTexture(gSurface, &surfTex);
if (surfTex.status == WGPUSurfaceGetCurrentTextureStatus_SuccessOptimal ||
surfTex.status == WGPUSurfaceGetCurrentTextureStatus_SuccessSuboptimal)
return surfTex;
// Timeout and Occluded are normal OS events (window covered / on a different Space).
bool silent = surfTex.status == WGPUSurfaceGetCurrentTextureStatus_Timeout;
#ifdef WGPU_H_
silent = silent || surfTex.status == (WGPUSurfaceGetCurrentTextureStatus)WGPUSurfaceGetCurrentTextureStatus_Occluded;
#endif
if (!silent)
fprintf(stderr, "Failed to get surface texture (status %d)\n", surfTex.status);
if (surfTex.texture) wgpuTextureRelease(surfTex.texture);
surfTex.texture = nullptr;
return surfTex;
}
static void renderFrame() {
ZoneScoped;
// Update rotation angle
float angle = (float)platformGetTime();
wgpuQueueWriteBuffer(gQueue, gUniformBuf, 0, &angle, sizeof(float));
WGPUSurfaceTexture surfTex = getWindowSurface();
if (!surfTex.texture) return;
WGPUTextureView view = wgpuTextureCreateView(surfTex.texture, nullptr);
// Command encoder
WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(gDevice, nullptr);
// Render pass
WGPURenderPassColorAttachment colorAtt = {};
colorAtt.view = view;
colorAtt.loadOp = WGPULoadOp_Clear;
colorAtt.storeOp = WGPUStoreOp_Store;
colorAtt.clearValue = { 0.05, 0.05, 0.08, 1.0 };
colorAtt.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED;
WGPURenderPassDescriptor passDesc = {};
passDesc.colorAttachmentCount = 1;
passDesc.colorAttachments = &colorAtt;
{
ZoneScopedN("render-pass");
TracyWebGPUNamedZone(gTracyCtx, tracyZone, encoder, passDesc, "triangle draw", true);
WGPURenderPassEncoder pass = wgpuCommandEncoderBeginRenderPass(encoder, &passDesc);
wgpuRenderPassEncoderSetPipeline(pass, gPipeline);
wgpuRenderPassEncoderSetBindGroup(pass, 0, gBindGroup, 0, nullptr);
wgpuRenderPassEncoderDraw(pass, 3, 1, 0, 0);
wgpuRenderPassEncoderEnd(pass);
wgpuRenderPassEncoderRelease(pass);
}
// Submit
WGPUCommandBuffer cmdBuf = wgpuCommandEncoderFinish(encoder, nullptr);
wgpuQueueSubmit(gQueue, 1, &cmdBuf);
// Present
wgpuSurfacePresent(gSurface);
// Process Events
wgpuInstanceProcessEvents(gInstance);
TracyWebGPUCollect(gTracyCtx);
// Cleanup
wgpuCommandBufferRelease(cmdBuf);
wgpuCommandEncoderRelease(encoder);
wgpuTextureViewRelease(view);
wgpuTextureRelease(surfTex.texture);
}
// ---------------------------------------------------------------------------
// Shutdown
// ---------------------------------------------------------------------------
static void shutdown() {
fprintf(stderr, "application is shutting down...\n");
TracyWebGPUDestroy(gTracyCtx);
if (gBindGroup) wgpuBindGroupRelease(gBindGroup);
if (gUniformBuf) wgpuBufferRelease(gUniformBuf);
if (gPipeline) wgpuRenderPipelineRelease(gPipeline);
if (gQueue) wgpuQueueRelease(gQueue);
if (gDevice) wgpuDeviceRelease(gDevice);
if (gAdapter) wgpuAdapterRelease(gAdapter);
if (gSurface) wgpuSurfaceRelease(gSurface);
if (gInstance) wgpuInstanceRelease(gInstance);
}
// ---------------------------------------------------------------------------
// main
// ---------------------------------------------------------------------------
int main(int argc, char* argv[]) {
if (!platformInit(kWidth, kHeight, "WebGPU Spinning Triangle"))
return 1;
gInstance = wgpuCreateInstance(nullptr);
if (!gInstance) return error(2, "Failed to create WebGPU instance.");
gSurface = platformCreateSurface(gInstance);
if (!gSurface) return error(3, "Failed to create surface.");
if (initWebGPU() != 0) return 4;
platformRunLoop(renderFrame, shutdown);
return 0;
}

View File

@@ -1,4 +1,4 @@
// g++ identify.cpp -lpthread ../public/common/tracy_lz4.cpp ../zstd/common/*.c ../zstd/decompress/*.c ../zstd/decompress/huf_decompress_amd64.S
// g++ identify.cpp -lpthread ../public/common/tracy_lz4.cpp -lzstd
#include <memory>
#include <stdint.h>
@@ -8,7 +8,7 @@
#include "../public/common/TracyVersion.hpp"
static const uint8_t FileHeader[8] { 't', 'r', 'a', 'c', 'y', tracy::Version::Major, tracy::Version::Minor, tracy::Version::Patch };
enum { FileHeaderMagic = 5 };
constexpr size_t FileHeaderMagic = 5;
int main( int argc, char** argv )
{

View File

@@ -1,26 +0,0 @@
#!/bin/sh
rm -rf tracy-build
mkdir tracy-build
./update-meson-version.sh
if [ ! -f vswhere.exe ]; then
wget https://github.com/microsoft/vswhere/releases/download/2.8.4/vswhere.exe
fi
MSVC=`./vswhere.exe -property installationPath -version '[17.0,17.999]' | head -n 1`
MSVC=`wslpath "$MSVC" | tr -d '\r'`
MSBUILD=$MSVC/MSBuild/Current/Bin/MSBuild.exe
for i in capture csvexport import-chrome update; do
echo $i...
"$MSBUILD" ../$i/build/win32/$i.sln /t:Clean /p:Configuration=Release /p:Platform=x64 /noconsolelogger /nologo -m
"$MSBUILD" ../$i/build/win32/$i.sln /t:Build /p:Configuration=Release /p:Platform=x64 /noconsolelogger /nologo -m
cp ../$i/build/win32/x64/Release/$i.exe tracy-build/
done
echo profiler...
"$MSBUILD" ../profiler/build/win32/Tracy.sln /t:Clean /p:Configuration=Release /p:Platform=x64 /noconsolelogger /nologo -m
"$MSBUILD" ../profiler/build/win32/Tracy.sln /t:Build /p:Configuration=Release /p:Platform=x64 /noconsolelogger /nologo -m
cp ../profiler/build/win32/x64/Release/Tracy.exe tracy-build/

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