diff --git a/.gitmodules b/.gitmodules index aa3f3bc4b0..bdd445a910 100644 --- a/.gitmodules +++ b/.gitmodules @@ -28,3 +28,6 @@ [submodule "source/extern/curl"] path = source/extern/curl url = https://github.com/TeamForbiddenLLC/curl.git +[submodule "source/extern/tracy"] + path = source/extern/tracy + url = https://github.com/wolfpld/tracy.git diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 72cdb99e67..7d875aff27 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -56,6 +56,7 @@ OPTION(USE_SYSTEM_OGG "Prefer system OGG instead of the bundled one" OFF) OPTION(USE_SYSTEM_FREETYPE "Prefer system freetype instead of the bundled one" OFF) OPTION(USE_SYSTEM_VORBIS "Prefer system vorbis instead of the bundled one" OFF) + option(USE_PACKAGE_ASSETS "package assets" OFF) # We compile third-party libs from source diff --git a/source/client/CMakeLists.txt b/source/client/CMakeLists.txt index 8edd5d48f8..3bd082f80c 100644 --- a/source/client/CMakeLists.txt +++ b/source/client/CMakeLists.txt @@ -249,8 +249,7 @@ elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows") add_custom_command(TARGET ${QFUSION_CLIENT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_BINARY_DIR}/warfork-qfusion/steam_appid.txt ${CMAKE_BINARY_DIR}/warfork-qfusion/$(CONFIGURATION)/) endif() -target_link_libraries(${QFUSION_CLIENT_NAME} PRIVATE CURL::libcurl ${CLIENT_PLATFORM_LIBRARIES} ${DISCORD_LIBRARY} ${STEAMSHIMPARENT_LIBRARY}) - +target_link_libraries(${QFUSION_CLIENT_NAME} PRIVATE CURL::libcurl ${CLIENT_PLATFORM_LIBRARIES} ${DISCORD_LIBRARY} ${STEAMSHIMPARENT_LIBRARY} Tracy::TracyClient) qf_set_output_dir(${QFUSION_CLIENT_NAME} "") if (BUILD_STEAMLIB) diff --git a/source/client/cl_screen.c b/source/client/cl_screen.c index 55f9122053..d9c8ad5f3c 100644 --- a/source/client/cl_screen.c +++ b/source/client/cl_screen.c @@ -34,6 +34,8 @@ end of unit intermissions #include "client.h" #include "ftlib.h" +#include "tracy/TracyC.h" + float scr_con_current; // aproaches scr_conlines at scr_conspeed float scr_con_previous; @@ -674,6 +676,7 @@ static void SCR_RenderView( float stereo_separation ) */ void SCR_UpdateScreen( void ) { + TracyCFrameMark static dynvar_t *updatescreen = NULL; int numframes; int i; @@ -731,6 +734,8 @@ void SCR_UpdateScreen( void ) for( i = 0; i < numframes; i++ ) { + static const char* const cl_frame = "Render Frame"; + TracyCFrameMarkStart(cl_frame); RF_BeginFrame( separation[i], forceclear, forcevsync ); if( scr_draw_loading == 2 ) @@ -787,5 +792,6 @@ void SCR_UpdateScreen( void ) Dynvar_CallListeners( updatescreen, NULL ); RF_EndFrame(); + TracyCFrameMarkEnd(cl_frame); } } diff --git a/source/extern/CMakeLists.txt b/source/extern/CMakeLists.txt index 7648b7a353..eaa12a454a 100644 --- a/source/extern/CMakeLists.txt +++ b/source/extern/CMakeLists.txt @@ -108,4 +108,10 @@ endif() endif() +option(TRACY_STATIC "" OFF ) +SET(TRACY_ENABLE OFF CACHE BOOL "Enable profiling") +add_compile_definitions(TRACY_IMPORTS) +add_subdirectory(tracy) +qf_set_output_dir(TracyClient libs) + set(STB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/stb PARENT_SCOPE) diff --git a/source/extern/tracy b/source/extern/tracy new file mode 160000 index 0000000000..e49c25f2f5 --- /dev/null +++ b/source/extern/tracy @@ -0,0 +1 @@ +Subproject commit e49c25f2f5afbc01b8f92f1f4d7d85ae65ee64c5 diff --git a/source/ref_nri/CMakeLists.txt b/source/ref_nri/CMakeLists.txt index 676982a9cf..080dc61256 100644 --- a/source/ref_nri/CMakeLists.txt +++ b/source/ref_nri/CMakeLists.txt @@ -32,7 +32,7 @@ file(GLOB STB_HEADERS add_library(ref_nri SHARED ${REF_NRI_HEADERS} ${REF_NRI_COMMON_SOURCES} ${REF_NRI_PLATFORM_SOURCES}) target_include_directories(ref_nri PRIVATE ${STB_INCLUDE_DIR} "../ref_base" "${NRI_DIR}/External/vulkan/include") target_link_libraries(ref_nri PRIVATE NRI) -target_link_libraries(ref_nri PRIVATE glslang::glslang glslang::glslang-default-resource-limits glslang::SPIRV glslang::SPVRemapper qcore) +target_link_libraries(ref_nri PRIVATE glslang::glslang glslang::glslang-default-resource-limits glslang::SPIRV glslang::SPVRemapper qcore Tracy::TracyClient) target_include_directories(ref_nri PRIVATE ${NRI_INCLUDE_DIR}) target_include_directories(ref_nri PRIVATE ${MINIZ_INCLUDE_DIR}) qf_set_output_dir(ref_nri libs) diff --git a/source/ref_nri/r_frontend.c b/source/ref_nri/r_frontend.c index 87e8bb519a..e6a99e2650 100644 --- a/source/ref_nri/r_frontend.c +++ b/source/ref_nri/r_frontend.c @@ -28,6 +28,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "stb_ds.h" #include "r_capture.h" +#include "tracy/TracyC.h" + static ref_frontend_t rrf; @@ -200,6 +202,7 @@ rserr_t RF_Init( const char *applicationName, const char *screenshotPrefix, int rserr_t RF_SetMode( int x, int y, int width, int height, int displayFrequency, bool fullScreen, bool stereo ) { + TracyCZone(ctx, 1); rsh.nri.helperI.WaitForIdle( rsh.cmdQueue ); if( fullScreen ) { @@ -327,6 +330,7 @@ rserr_t RF_SetMode( int x, int y, int width, int height, int displayFrequency, b RB_Init(); + TracyCZoneEnd(ctx); return rserr_ok; } @@ -404,6 +408,7 @@ void RF_Shutdown( bool verbose ) static void RF_CheckCvars( void ) { + TracyCZone(ctx, 1); // disallow bogus r_maxfps values, reset to default value instead if( r_maxfps->modified ) { if( r_maxfps->integer <= 0 ) { @@ -459,10 +464,12 @@ static void RF_CheckCvars( void ) } r_outlines_scale->modified = false; } + TracyCZoneEnd(ctx); } void RF_BeginFrame( float cameraSeparation, bool forceClear, bool forceVsync ) { + TracyCZone(ctx, 1); RF_CheckCvars(); // run cinematic passes on shaders @@ -539,12 +546,10 @@ void RF_BeginFrame( float cameraSeparation, bool forceClear, bool forceVsync ) rrf.cameraSeparation = cameraSeparation; - memset( &rf.stats, 0, sizeof( rf.stats ) ); // update fps meter // copy in changes from R_BeginFrame - // rrf.frame->BeginFrame( rrf.frame, cameraSeparation, forceClear, forceVsync ); const unsigned int time = ri.Sys_Milliseconds(); rf.fps.count++; rf.fps.time = time; @@ -557,7 +562,7 @@ void RF_BeginFrame( float cameraSeparation, bool forceClear, bool forceVsync ) rf.width2D = -1; rf.height2D = -1; R_Set2DMode(frame, true ); - + TracyCZoneEnd(ctx); } static inline void __R_PolyBlendPostPass(struct frame_cmd_buffer_s* frame) { @@ -595,6 +600,7 @@ static inline void __R_ApplyBrightnessBlend(struct frame_cmd_buffer_s* frame) { void RF_EndFrame( void ) { + TracyCZone(ctx, 1); const uint32_t bufferedFrameIndex = rsh.swapchainCount % NUMBER_FRAMES_FLIGHT; struct frame_cmd_buffer_s *frame = &rsh.frameCmds[bufferedFrameIndex]; @@ -727,6 +733,8 @@ void RF_EndFrame( void ) rsh.swapchainCount++; rsh.frameCount++; + + TracyCZoneEnd(ctx); } void RF_BeginRegistration( void ) diff --git a/source/ref_nri/r_image.c b/source/ref_nri/r_image.c index c825c50a10..a49437b798 100644 --- a/source/ref_nri/r_image.c +++ b/source/ref_nri/r_image.c @@ -38,9 +38,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "r_ktx_loader.h" #include - #include +#include "tracy/TracyC.h" + #define MAX_GLIMAGES 8192 #define IMAGES_HASH_SIZE 64 #define IMAGE_SAMPLER_HASH_SIZE 1024 @@ -700,6 +701,7 @@ static bool R_IsKTXFormatValid( int format, int type ) //TODO: move ktx loader to a seperate file static bool __R_LoadKTX( image_t *image, const char *pathname ) { + TracyCZone(ctx, 1); const uint_fast16_t numFaces = ( ( image->flags & IT_CUBEMAP ) ? 6 : 1 ); if( image->flags & ( IT_FLIPX|IT_FLIPY|IT_FLIPDIAGONAL ) ) return false; @@ -867,10 +869,12 @@ static bool __R_LoadKTX( image_t *image, const char *pathname ) R_KTXFreeContext(&ktxContext); R_FreeFile( buffer ); R_DeferDataSync(); + TracyCZoneEnd(ctx); return true; error: // must not be reached after actually starting uploading the texture R_KTXFreeContext(&ktxContext); R_FreeFile( buffer ); + TracyCZoneEnd(ctx); return false; } @@ -1022,7 +1026,7 @@ static uint16_t __R_calculateMipMapLevel(int flags, int width, int height, uint3 struct image_s *R_LoadImage( const char *name, uint8_t **pic, int width, int height, int flags, int minmipsize, int tags, int samples ) { - + TracyCZone(ctx, 1); struct image_s *image = __R_AllocImage( qCToStrRef(name) ); image->width = width; @@ -1105,6 +1109,7 @@ struct image_s *R_LoadImage( const char *name, uint8_t **pic, int width, int hei } } arrfree( tmpBuffer ); + TracyCZoneEnd(ctx); return image; } @@ -1132,6 +1137,7 @@ image_t *R_CreateImage( const char *name, int width, int height, int layers, int static void __FreeImage( struct frame_cmd_buffer_s *cmd, struct image_s *image ) { + TracyCZone(ctx, 1); { __FreeGPUImageData(cmd, image); // R_ReleaseNriTexture(image); @@ -1160,11 +1166,13 @@ static void __FreeImage( struct frame_cmd_buffer_s *cmd, struct image_s *image ) image->prev = NULL; ri.Mutex_Unlock( r_imagesLock ); } + TracyCZoneEnd(ctx); } void R_ReplaceImage( image_t *image, uint8_t **pic, int width, int height, int flags, int minmipsize, int samples ) { + TracyCZone(ctx, 1); assert( image ); assert( image->texture ); const NriTextureDesc* textureDesc = rsh.nri.coreI.GetTextureDesc(image->texture); @@ -1207,6 +1215,7 @@ void R_ReplaceImage( image_t *image, uint8_t **pic, int width, int height, int f image->minmipsize = minmipsize; R_ReplaceSubImage(image, 0, 0, 0, pic, width, height); + TracyCZoneEnd(ctx); } /* @@ -1214,6 +1223,7 @@ void R_ReplaceImage( image_t *image, uint8_t **pic, int width, int height, int f */ void R_ReplaceSubImage( image_t *image, int layer, int x, int y, uint8_t **pic, int width, int height ) { + TracyCZone(ctx, 1); assert( image ); assert( image->texture ); @@ -1254,6 +1264,7 @@ void R_ReplaceSubImage( image_t *image, int layer, int x, int y, uint8_t **pic, R_DeferDataSync(); image->registrationSequence = rsh.registrationSequence; + TracyCZoneEnd(ctx); } /* @@ -1261,6 +1272,7 @@ void R_ReplaceSubImage( image_t *image, int layer, int x, int y, uint8_t **pic, */ void R_ReplaceImageLayer( image_t *image, int layer, uint8_t **pic ) { + TracyCZone(ctx, 1); assert( image ); assert( image->texture ); @@ -1301,6 +1313,7 @@ void R_ReplaceImageLayer( image_t *image, int layer, uint8_t **pic ) R_DeferDataSync(); image->registrationSequence = rsh.registrationSequence; + TracyCZoneEnd(ctx); } /* @@ -1311,6 +1324,7 @@ void R_ReplaceImageLayer( image_t *image, int layer, uint8_t **pic ) */ image_t *R_FindImage( const char *name, const char *suffix, int flags, int minmipsize, int tags ) { + TracyCZone(ctx, 1); assert( name ); assert( name[0] ); struct UploadImgBuffer { @@ -1577,6 +1591,7 @@ image_t *R_FindImage( const char *name, const char *suffix, int flags, int minmi T_FreeTextureBuf(&uploads[i].buffer); } qStrFree(&resolvedPath); + TracyCZoneEnd(ctx); return image; } @@ -1909,6 +1924,7 @@ void R_TouchImage( image_t *image, int tags ) */ void R_FreeUnusedImagesByTags( int tags ) { + TracyCZone(ctx, 1); int i; image_t *image; int keeptags = ~tags; @@ -1931,6 +1947,7 @@ void R_FreeUnusedImagesByTags( int tags ) __FreeImage( R_ActiveFrameCmd(),image ); } + TracyCZoneEnd(ctx); } /* @@ -1946,6 +1963,7 @@ void R_FreeUnusedImages( void ) */ void R_ShutdownImages( void ) { + TracyCZone(ctx, 1); int i; image_t *image; @@ -1977,6 +1995,7 @@ void R_ShutdownImages( void ) r_imagesPool = NULL; r_screenShotBuffer = NULL; r_screenShotBufferSize = 0; + TracyCZoneEnd(ctx); } diff --git a/source/ref_nri/r_model.c b/source/ref_nri/r_model.c index 2983d7641a..d26ba449e3 100644 --- a/source/ref_nri/r_model.c +++ b/source/ref_nri/r_model.c @@ -24,6 +24,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "r_local.h" #include "iqm.h" +#include "tracy/TracyC.h" + void Mod_LoadAliasMD3Model( model_t *mod, model_t *parent, void *buffer, bspFormatDesc_t *unused ); void Mod_LoadSkeletalModel( model_t *mod, model_t *parent, void *buffer, bspFormatDesc_t *unused ); void Mod_LoadQ3BrushModel( model_t *mod, model_t *parent, void *buffer, bspFormatDesc_t *format ); @@ -1288,6 +1290,7 @@ static void R_FinishMapConfig( const model_t *mod ) */ void R_RegisterWorldModel( const char *model, const dvis_t *pvsData ) { + TracyCZone( ctx, 1 ); r_prevworldmodel = rsh.worldModel; rsh.worldModel = NULL; rsh.worldBrushModel = NULL; @@ -1301,6 +1304,7 @@ void R_RegisterWorldModel( const char *model, const dvis_t *pvsData ) mod_isworldmodel = false; if( !rsh.worldModel ) { + TracyCZoneEnd( ctx ); return; } @@ -1308,8 +1312,9 @@ void R_RegisterWorldModel( const char *model, const dvis_t *pvsData ) mapConfig = mod_mapConfigs[rsh.worldModel - mod_known]; R_TouchModel( rsh.worldModel ); - rsh.worldBrushModel = ( mbrushmodel_t * )rsh.worldModel->extradata; - rsh.worldBrushModel->pvs = ( dvis_t * )pvsData; + rsh.worldBrushModel = (mbrushmodel_t *)rsh.worldModel->extradata; + rsh.worldBrushModel->pvs = (dvis_t *)pvsData; + TracyCZoneEnd( ctx ); } /* diff --git a/source/ref_nri/r_texture_buffer_load.c b/source/ref_nri/r_texture_buffer_load.c index 82ba14a083..6218dc75f6 100644 --- a/source/ref_nri/r_texture_buffer_load.c +++ b/source/ref_nri/r_texture_buffer_load.c @@ -6,14 +6,18 @@ #include "../qcommon/qfiles.h" +#include "tracy/TracyC.h" + static uint32_t pallet[256]; bool T_LoadImagePCX(char *filename, struct texture_buf_s* buffer, uint8_t** pallet) { + TracyCZone(ctx, 1); void* const raw; size_t len = R_LoadFile( filename, (void **)&raw ); if(raw == NULL) { ri.Com_Printf(S_COLOR_YELLOW "can't resolve file: %s", filename); + TracyCZoneEnd(ctx); return false; } @@ -35,10 +39,10 @@ bool T_LoadImagePCX(char *filename, struct texture_buf_s* buffer, uint8_t** pall if( sizeof(*pcx) > len ) { ri.Com_DPrintf( S_COLOR_YELLOW "PCX file %s was malformed", filename ); + TracyCZoneEnd(ctx); return false; } - pcx->xmin = LittleShort( pcx->xmin ); pcx->ymin = LittleShort( pcx->ymin ); pcx->xmax = LittleShort( pcx->xmax ); @@ -50,6 +54,7 @@ bool T_LoadImagePCX(char *filename, struct texture_buf_s* buffer, uint8_t** pall if( (sizeof(*pcx) + (pcx->ymax * pcx->xmax) + sizeof(uint32_t) * 256) > len ) { ri.Com_Printf( S_COLOR_YELLOW "PCX file %s was malformed", filename ); + TracyCZoneEnd(ctx); return false; } @@ -58,6 +63,7 @@ bool T_LoadImagePCX(char *filename, struct texture_buf_s* buffer, uint8_t** pall len < 768 ) { ri.Com_Printf( S_COLOR_YELLOW "Bad pcx file %s\n", filename ); R_FreeFile( pcx ); + TracyCZoneEnd(ctx); return false; } @@ -101,9 +107,8 @@ bool T_LoadImagePCX(char *filename, struct texture_buf_s* buffer, uint8_t** pall R_FreeFile( pcx); - + TracyCZoneEnd(ctx); return true; - } static void __R_stbi_free_image(void* p) { @@ -112,6 +117,7 @@ static void __R_stbi_free_image(void* p) { } bool T_LoadImageSTBI(char *filename, struct texture_buf_s* buffer ) { + TracyCZone(ctx, 1); uint8_t* data; size_t size = R_LoadFile( filename, ( void ** ) &data ); if(data == NULL) { @@ -145,11 +151,13 @@ bool T_LoadImageSTBI(char *filename, struct texture_buf_s* buffer ) { default: stbi_image_free(stbiBuffer); ri.Com_Printf(S_COLOR_YELLOW "unhandled channel count: %d", channelCount); + TracyCZoneEnd(ctx); return false; } R_FreeFile( data ); const int res = T_AliasTextureBuf_Free(buffer, &desc, stbiBuffer, 0, stbiBuffer, __R_stbi_free_image); assert(res == TEXTURE_BUF_SUCCESS); + TracyCZoneEnd(ctx); return true; } @@ -157,14 +165,13 @@ void T_SetPallet(uint32_t p[256]) { memcpy(pallet, p, sizeof(pallet)); } - - uint32_t* T_Pallet() { return pallet; } //https://developer.valvesoftware.com/wiki/WAL bool T_LoadImageWAL(char *filename, struct texture_buf_s* tex) { + TracyCZone(ctx, 1); // load the file uint8_t* const buf = NULL; const size_t size = R_LoadFile( filename, (void **)&buf); @@ -219,9 +226,10 @@ bool T_LoadImageWAL(char *filename, struct texture_buf_s* tex) { *( (uint32_t *)block ) = pallet[p]; } } - Mem_ValidationAllAllocations(); + Mem_ValidationAllAllocations(); R_FreeFile( buf ); + TracyCZoneEnd(ctx); return true; } diff --git a/source/tracy b/source/tracy new file mode 160000 index 0000000000..7fc3366086 --- /dev/null +++ b/source/tracy @@ -0,0 +1 @@ +Subproject commit 7fc3366086d745fcf09ddb446dbf3e6d3b5bb5fa