feat/tracy: basic tracy implementation

This commit is contained in:
JuiceyDev 2026-04-05 21:07:02 +02:00
parent 9c0dfd60d5
commit 4cdc29bbf4
7 changed files with 161 additions and 106 deletions

View file

@ -89,6 +89,12 @@ pip install meson ninja
Or follow the [Meson quickstart guide](https://mesonbuild.com/Quick-guide.html).
### Tracy profiler
This project can be built with Tracy profiling support. Tracy is available as a meson subproject (bundled in `subprojects/tracy`) and many distributions provide the Tracy tooling; on Arch/Manjaro you can get the latest build from the AUR as `tracy-git`.
Tracy can be directly enabled if you enable the tracy meson option before compiling.
#### Docker (alternative)
If you don't want to install dependencies, use the included devcontainer. Open the project in VS Code with the [Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension, or build manually:

View file

@ -1,16 +1,16 @@
project(
'4jcraft',
['cpp', 'c'],
version: '0.1.0',
meson_version: '>= 1.3',
default_options: [
'cpp_std=c++23',
'warning_level=0',
'buildtype=debugoptimized', # for now
'unity=on', # merge source files per target
'unity_size=8', # TODO: mess around with this
'b_pch=true', # precompiled headers
],
'4jcraft',
['cpp', 'c'],
version: '0.1.0',
meson_version: '>= 1.3',
default_options: [
'cpp_std=c++23',
'warning_level=0',
'buildtype=debugoptimized', # for now
'unity=on', # merge source files per target
'unity_size=8', # TODO: mess around with this
'b_pch=true', # precompiled headers
],
)
pymod = import('python')
@ -19,30 +19,30 @@ python = pymod.find_installation('python3', required: true)
cc = meson.get_compiler('cpp')
global_cpp_defs = [
'-DSPLIT_SAVES',
'-D_LARGE_WORLDS',
'-D_EXTENDED_ACHIEVEMENTS',
'-D_DEBUG_MENUS_ENABLED',
'-D_DEBUG',
'-D_FORTIFY_SOURCE=2',
'-DDEBUG',
'-DSPLIT_SAVES',
'-D_LARGE_WORLDS',
'-D_EXTENDED_ACHIEVEMENTS',
'-D_DEBUG_MENUS_ENABLED',
'-D_DEBUG',
'-D_FORTIFY_SOURCE=2',
'-DDEBUG',
]
if host_machine.system() == 'linux'
global_cpp_defs += ['-Dlinux', '-D__linux', '-D__linux__']
global_cpp_defs += ['-Dlinux', '-D__linux', '-D__linux__']
endif
if get_option('renderer') == 'gles'
global_cpp_defs += ['-DGLES']
gl_dep = dependency('glesv2', required: true)
glu_dep = dependency('', required: false)
global_cpp_defs += ['-DGLES']
gl_dep = dependency('glesv2', required: true)
glu_dep = dependency('', required: false)
else
gl_dep = dependency('gl', required: true)
glu_dep = dependency('glu', required: true)
gl_dep = dependency('gl', required: true)
glu_dep = dependency('glu', required: true)
endif
if get_option('enable_vsync')
global_cpp_defs += ['-DENABLE_VSYNC']
global_cpp_defs += ['-DENABLE_VSYNC']
endif
if get_option('classic_panorama')
@ -50,22 +50,22 @@ if get_option('classic_panorama')
endif
if get_option('enable_frame_profiler')
global_cpp_defs += ['-DENABLE_FRAME_PROFILER']
global_cpp_defs += ['-DENABLE_FRAME_PROFILER']
endif
if get_option('ui_backend') == 'shiggy'
global_cpp_defs += ['-D_ENABLEIGGY']
global_cpp_defs += ['-D_ENABLEIGGY']
endif
if get_option('ui_backend') == 'java'
global_cpp_defs += '-DENABLE_JAVA_GUIS'
global_cpp_defs += '-DENABLE_JAVA_GUIS'
endif
add_project_arguments(global_cpp_defs, language: ['cpp', 'c'])
global_cpp_args = [
'-Wshift-count-overflow',
'-pipe',
'-Wshift-count-overflow',
'-pipe',
]
add_project_arguments(global_cpp_args, language: 'cpp')
@ -79,6 +79,20 @@ stb_dep = declare_dependency(include_directories: stb)
miniaudio_dep = dependency('miniaudio')
tracy_opt = get_option('tracy')
if not tracy_opt.disabled()
tracy_proj = subproject('tracy', required: tracy_opt, default_options: ['tracy_enable=true'])
if tracy_proj.found()
tracy_client_dep = tracy_proj.get_variable('tracy_dep')
add_project_arguments('-DTRACY_ENABLE', language: ['cpp', 'c'])
else
tracy_client_dep = dependency('', required: false)
endif
else
tracy_client_dep = dependency('', required: false)
endif
subdir('targets/util')
subdir('targets/java')
subdir('targets/nbt')
@ -86,4 +100,4 @@ subdir('targets/platform')
subdir('targets/resources')
subdir('targets/minecraft')
subdir('targets/app')
subdir('targets/app')

View file

@ -7,8 +7,8 @@ option(
)
option('classic_panorama',
type : 'boolean',
value : false,
type : 'boolean',
value : false,
description : 'Enable classic java edition panorama (ui_backend=java ONLY).')
option(
@ -40,3 +40,10 @@ option(
value: 'frustum',
description: 'Occlusion culling mode. Off disables ALL CULLING (debug only!), Frustum disables offscreen rendering (default), BFS is experimental connectivity culling, hardware uses GPU queries.',
)
option(
'tracy',
type: 'feature',
value: 'auto',
description: 'Enable Tracy profiler'
)

View file

@ -92,6 +92,13 @@
#include "minecraft/server/PlayerList.h"
#include "minecraft/server/level/ServerPlayer.h"
#ifdef TRACY_ENABLE
#include <tracy/Tracy.hpp>
#else
#define ZoneScoped
#define ZoneScopedN(name)
#endif
class BeaconTileEntity;
class BrewingStandTileEntity;
class DispenserTileEntity;
@ -2202,6 +2209,7 @@ void Game::SetActionConfirmed(void* param) {
}
void Game::HandleXuiActions(void) {
ZoneScoped;
eXuiAction eAction;
eTMSAction eTMS;
void* param;
@ -4394,6 +4402,7 @@ void Game::InitTime() {
// Desc: Updates the elapsed time since our last frame.
//-------------------------------------------------------------------------------------
void Game::UpdateTime() {
ZoneScoped;
auto qwNewTime = time_util::clock::now();
auto qwDeltaTime = qwNewTime - m_Time.qwTime;
@ -5557,6 +5566,7 @@ void Game::unlockSaveNotification() {
}
int Game::RemoteSaveThreadProc(void* lpParameter) {
ZoneScoped;
// The game should be stopped while we are doing this, but the connections
// ticks may try to create some AABB's or Vec3's
Compression::UseDefaultThreadStorage();

View file

@ -1,102 +1,106 @@
exclude_sources = [
' ! -path "*/common/*"',
' ! -path "*/linux/*"',
' ! -path "*/windows/*"',
' ! -path "*/common/*"',
' ! -path "*/linux/*"',
' ! -path "*/windows/*"',
]
# all sources except common/, linux/, windows/
client_sources = run_command(
'sh',
'-c', 'find "'
+ meson.current_source_dir()
+ '" \\( -name "*.cpp" -o -name "*.c" \\)'
+ ' '.join(exclude_sources),
check: true,
'sh',
'-c', 'find "'
+ meson.current_source_dir()
+ '" \\( -name "*.cpp" -o -name "*.c" \\)'
+ ' '.join(exclude_sources),
check: true,
).stdout().strip().split('\n')
exclude_platform_common_sources = [
' ! -name "UIScene_InGameSaveManagementMenu.cpp"',
' ! -name "UIScene_InGameSaveManagementMenu.cpp"',
]
# all sources in common/
platform_sources = run_command(
'sh',
'-c', 'find "'
+ meson.current_source_dir() / 'common'
+ '" \\( -name "*.cpp" -o -name "*.c" \\)'
+ ' '.join(exclude_platform_common_sources),
check: true,
'sh',
'-c', 'find "'
+ meson.current_source_dir() / 'common'
+ '" \\( -name "*.cpp" -o -name "*.c" \\)'
+ ' '.join(exclude_platform_common_sources),
check: true,
).stdout().strip().split('\n')
# linux-specific files
if host_machine.system() == 'linux'
platform_sources += run_command(
'sh',
'-c', 'find "'
+ meson.current_source_dir() / 'linux'
+ '" \\( -name "*.cpp" -o -name "*.c" \\) ',
check: true,
).stdout().strip().split('\n')
platform_sources += run_command(
'sh',
'-c', 'find "'
+ meson.current_source_dir() / 'linux'
+ '" \\( -name "*.cpp" -o -name "*.c" \\) ',
check: true,
).stdout().strip().split('\n')
endif
client_dependencies = [
java_dep,
nbt_dep,
render_dep,
input_dep,
profile_dep,
storage_dep,
assets_localisation_dep,
platform_dep,
minecraft_dep,
gl_dep,
glu_dep,
thread_dep,
dl_dep,
dependency('zlib'),
miniaudio_dep,
stb_dep,
util_dep,
java_dep,
nbt_dep,
render_dep,
input_dep,
profile_dep,
storage_dep,
assets_localisation_dep,
platform_dep,
minecraft_dep,
gl_dep,
glu_dep,
thread_dep,
dl_dep,
dependency('zlib'),
miniaudio_dep,
stb_dep,
util_dep,
tracy_client_dep,
]
if get_option('ui_backend') == 'shiggy'
shiggy_dep = dependency(
'shiggy',
fallback: ['shiggy', 'shiggy_dep'],
)
client_dependencies += shiggy_dep
shiggy_dep = dependency(
'shiggy',
fallback: ['shiggy', 'shiggy_dep'],
)
client_dependencies += shiggy_dep
endif
platform_services_src = files('../platform/PlatformServices.cpp')
client = executable(
'Minecraft.Client',
client_sources + platform_sources + platform_services_src + localisation[1],
include_directories: include_directories('include', '..'),
dependencies: client_dependencies,
cpp_args: global_cpp_args
+ global_cpp_defs
+ [
'-DUNICODE',
'-D_UNICODE',
],
c_args: global_cpp_defs + ['-DUNICODE', '-D_UNICODE'],
install: true,
install_dir: '',
'Minecraft.Client',
client_sources
+ platform_sources
+ platform_services_src
+ localisation[1],
include_directories: include_directories('include', '..'),
dependencies: client_dependencies,
cpp_args: global_cpp_args
+ global_cpp_defs
+ [
'-DUNICODE',
'-D_UNICODE',
],
c_args: global_cpp_defs + ['-DUNICODE', '-D_UNICODE'],
install: true,
install_dir: '',
)
custom_target(
'copy_assets_to_client',
input: [client, media_archive],
output: 'assets.stamp',
command: [
python,
meson.project_source_root() / 'scripts/copy_assets_to_client.py',
meson.project_source_root(),
meson.project_build_root(),
meson.current_build_dir(),
'@INPUT1@',
'@OUTPUT@',
],
build_by_default: true,
)
'copy_assets_to_client',
input: [client, media_archive],
output: 'assets.stamp',
command: [
python,
meson.project_source_root() / 'scripts/copy_assets_to_client.py',
meson.project_source_root(),
meson.project_build_root(),
meson.current_build_dir(),
'@INPUT1@',
'@OUTPUT@',
],
build_by_default: true,
)

View file

@ -131,6 +131,13 @@
#include "minecraft/world/level/chunk/SparseDataStorage.h"
#include "minecraft/world/level/chunk/SparseLightStorage.h"
#ifdef TRACY_ENABLE
#include <tracy/Tracy.hpp>
#else
#define ZoneScoped
#define ZoneScopedN(name)
#endif
class ChunkSource;
// #define DISABLE_SPU_CODE
@ -1019,6 +1026,7 @@ void Minecraft::createPrimaryLocalPlayer(int iPad) {
}
void Minecraft::run_middle() {
ZoneScoped;
static int64_t lastTime = 0;
static bool bFirstTimeIntoGame = true;
static bool bAutosaveTimerSet = false;
@ -1166,6 +1174,7 @@ void Minecraft::run_middle() {
// 4J-PB - Once we're in the level, check if the players have
// the level in their banned list and ask if they want to play
// it
ZoneScopedN("Render Viewports");
for (int i = 0; i < XUSER_MAX_COUNT; i++) {
if (localplayers[i] && (app.GetBanListCheck(i) == false) &&
!Minecraft::GetInstance()->isTutorial() &&
@ -1813,6 +1822,7 @@ void Minecraft::run_middle() {
*/
}
} // lock_guard scope
FrameMark;
}
void Minecraft::run_end() { destroy(); }
@ -1990,6 +2000,7 @@ void Minecraft::verify() {
}
void Minecraft::levelTickUpdateFunc(void* pParam) {
ZoneScoped;
Level* pLevel = (Level*)pParam;
pLevel->tick();
}
@ -2003,6 +2014,7 @@ void Minecraft::levelTickThreadInitFunc() {
// textures are to be updated - this will be true for the last time this tick
// runs with bFirst true
void Minecraft::tick(bool bFirst, bool bUpdateTextures) {
ZoneScoped;
int iPad = player->GetXboxPad();
// OutputDebugString("Minecraft::tick\n");
@ -4517,6 +4529,7 @@ int Minecraft::InGame_SignInReturned(void* pParam, bool bContinue, int iPad) {
}
void Minecraft::tickAllConnections() {
ZoneScoped;
int oldIdx = getLocalPlayerIdx();
for (unsigned int i = 0; i < XUSER_MAX_COUNT; i++) {
std::shared_ptr<MultiplayerLocalPlayer> mplp = localplayers[i];

View file

@ -58,6 +58,7 @@ lib_minecraft = static_library('minecraft',
assets_localisation_dep,
platform_dep,
util_dep,
tracy_client_dep,
dependency('zlib'),
],
include_directories : include_directories('..'),