From 855c79458683411f73dd411c0b129cae5dc43ab9 Mon Sep 17 00:00:00 2001 From: PJB3005 Date: Sat, 11 Apr 2026 16:11:19 +0200 Subject: [PATCH 1/5] Improve dDlst_list_c::draw debug group code to also go to tracy, be less of a performance hog when active. --- include/dusk/gx_helper.h | 3 +++ src/d/d_drawlist.cpp | 30 ++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/include/dusk/gx_helper.h b/include/dusk/gx_helper.h index bf81424c99..8f71cbdf26 100644 --- a/include/dusk/gx_helper.h +++ b/include/dusk/gx_helper.h @@ -5,6 +5,7 @@ #include #include +#include "tracy/Tracy.hpp" #define GX_DEBUG_GROUP(name, ...) \ do { \ @@ -51,4 +52,6 @@ struct GXScopedDebugGroup { } }; +#define GX_AND_TRACY_SCOPED(name) GXScopedDebugGroup scope(name); ZoneScopedN(name); + #endif // DUSK_GX_HELPER_H diff --git a/src/d/d_drawlist.cpp b/src/d/d_drawlist.cpp index 8a564914c0..98a22ecf13 100644 --- a/src/d/d_drawlist.cpp +++ b/src/d/d_drawlist.cpp @@ -10,6 +10,10 @@ #include "SSystem/SComponent/c_math.h" #include "d/d_com_inf_game.h" #include "d/d_drawlist.h" + +#include + +#include "absl/container/flat_hash_map.h" #include "d/d_s_play.h" #include "dusk/frame_interpolation.h" #include "dusk/gx_helper.h" @@ -1923,14 +1927,32 @@ int dDlst_list_c::set(dDlst_base_c**& p_start, dDlst_base_c**& p_end, dDlst_base return 1; } +#if TARGET_PC && (TRACY_ENABLE || PARTIAL_DEBUG) +static absl::flat_hash_map typeDrawNames; + +static const char* getTypeDrawName(dDlst_base_c* dlst) { + const auto& info = typeid(*dlst); + auto& elem = typeDrawNames[info]; + if (elem) [[likely]] { + return elem; + } + + const auto size = snprintf(nullptr, 0, "%s::draw()", info.name()); + // Note: pointer is intentionally never freed, Tracy needs it. + const auto buf = static_cast(malloc(size+1)); + snprintf(buf, size+1, "%s::draw()", info.name()); + elem = buf; + return buf; +} +#endif + void dDlst_list_c::draw(dDlst_base_c** p_start, dDlst_base_c** p_end) { for (; p_start < p_end; p_start++) { dDlst_base_c* dlst = *p_start; -#if DEBUG && TARGET_PC - char buf[64]; - snprintf(buf, sizeof(buf), "%s::draw()", typeid(dlst).name()); - GXScopedDebugGroup scope(buf); +#if TARGET_PC && (TRACY_ENABLE || PARTIAL_DEBUG) + const auto name = getTypeDrawName(dlst); + GX_AND_TRACY_SCOPED(name); #endif dlst->draw(); } From bcf7b4ca857a1be1a20d9ff85a7408b58153949c Mon Sep 17 00:00:00 2001 From: PJB3005 Date: Sat, 11 Apr 2026 16:11:41 +0200 Subject: [PATCH 2/5] Bunch of debug/tracy groups for J2D --- libs/JSystem/src/J2DGraph/J2DPicture.cpp | 2 ++ libs/JSystem/src/J2DGraph/J2DPictureEx.cpp | 1 + libs/JSystem/src/J2DGraph/J2DScreen.cpp | 2 ++ libs/JSystem/src/J2DGraph/J2DTextBox.cpp | 2 ++ libs/JSystem/src/J2DGraph/J2DTextBoxEx.cpp | 1 + libs/JSystem/src/J2DGraph/J2DWindow.cpp | 2 ++ libs/JSystem/src/J2DGraph/J2DWindowEx.cpp | 1 + src/d/d_meter2_draw.cpp | 1 + 8 files changed, 12 insertions(+) diff --git a/libs/JSystem/src/J2DGraph/J2DPicture.cpp b/libs/JSystem/src/J2DGraph/J2DPicture.cpp index 8072c32d41..774b3d31af 100644 --- a/libs/JSystem/src/J2DGraph/J2DPicture.cpp +++ b/libs/JSystem/src/J2DGraph/J2DPicture.cpp @@ -511,6 +511,7 @@ void J2DPicture::drawSelf(f32 param_0, f32 param_1) { } void J2DPicture::drawSelf(f32 param_0, f32 param_1, Mtx* param_2) { + GX_AND_TRACY_SCOPED("J2DPicture::drawSelf") if (mTexture[0] != NULL && mTextureNum != 0) { drawFullSet(mGlobalBounds.i.x + param_0, mGlobalBounds.i.y + param_1, getWidth(), getHeight(), param_2); @@ -527,6 +528,7 @@ void J2DPicture::drawFullSet(f32 param_0, f32 param_1, f32 param_2, f32 param_3, void J2DPicture::draw(f32 x, f32 y, f32 width, f32 height, bool mirrorX, bool mirrorY, bool rotate90) { + GX_AND_TRACY_SCOPED("J2DPicture::draw") if (isVisible() && mTextureNum != 0 && mTexture[0] != NULL) { f32 x2 = x + width; f32 y2 = y + height; diff --git a/libs/JSystem/src/J2DGraph/J2DPictureEx.cpp b/libs/JSystem/src/J2DGraph/J2DPictureEx.cpp index 6c4048ba31..62925c4a98 100644 --- a/libs/JSystem/src/J2DGraph/J2DPictureEx.cpp +++ b/libs/JSystem/src/J2DGraph/J2DPictureEx.cpp @@ -79,6 +79,7 @@ bool J2DPictureEx::prepareTexture(u8 param_0) { } void J2DPictureEx::drawSelf(f32 param_0, f32 param_1, f32 (*param_2)[3][4]) { + GX_AND_TRACY_SCOPED("J2DPictureEx::drawSelf") if (mMaterial != NULL) { mMaterial->setGX(); GXClearVtxDesc(); diff --git a/libs/JSystem/src/J2DGraph/J2DScreen.cpp b/libs/JSystem/src/J2DGraph/J2DScreen.cpp index eec5ef057d..c44859046d 100644 --- a/libs/JSystem/src/J2DGraph/J2DScreen.cpp +++ b/libs/JSystem/src/J2DGraph/J2DScreen.cpp @@ -278,6 +278,8 @@ J2DPane* J2DScreen::searchUserInfo(u64 tag) { } void J2DScreen::drawSelf(f32 param_0, f32 param_1, Mtx* param_2) { + GX_AND_TRACY_SCOPED("J2DScreen::drawSelf") + JUtility::TColor color(mColor); u8 alpha = (color.a * mAlpha) / 255; diff --git a/libs/JSystem/src/J2DGraph/J2DTextBox.cpp b/libs/JSystem/src/J2DGraph/J2DTextBox.cpp index 86b36bdadf..970f120140 100644 --- a/libs/JSystem/src/J2DGraph/J2DTextBox.cpp +++ b/libs/JSystem/src/J2DGraph/J2DTextBox.cpp @@ -391,6 +391,8 @@ void J2DTextBox::drawSelf(f32 param_0, f32 param_1) { } void J2DTextBox::drawSelf(f32 param_0, f32 param_1, Mtx* p_mtx) { + GX_AND_TRACY_SCOPED("J2DTextBox::drawSelf") + Mtx m; J2DPrint print(mFont, mCharSpacing, mLineSpacing, mCharColor, mGradientColor, mBlackColor, diff --git a/libs/JSystem/src/J2DGraph/J2DTextBoxEx.cpp b/libs/JSystem/src/J2DGraph/J2DTextBoxEx.cpp index f615c44c8c..0911740898 100644 --- a/libs/JSystem/src/J2DGraph/J2DTextBoxEx.cpp +++ b/libs/JSystem/src/J2DGraph/J2DTextBoxEx.cpp @@ -93,6 +93,7 @@ J2DTextBoxEx::~J2DTextBoxEx() { } void J2DTextBoxEx::drawSelf(f32 param_0, f32 param_1, Mtx* p_mtx) { + GX_AND_TRACY_SCOPED("J2DTextBoxEx::drawSelf") Mtx m; JUTFont* font = NULL; diff --git a/libs/JSystem/src/J2DGraph/J2DWindow.cpp b/libs/JSystem/src/J2DGraph/J2DWindow.cpp index 35de369709..655dff4938 100644 --- a/libs/JSystem/src/J2DGraph/J2DWindow.cpp +++ b/libs/JSystem/src/J2DGraph/J2DWindow.cpp @@ -410,6 +410,8 @@ void J2DWindow::drawSelf(f32 param_0, f32 param_1) { } void J2DWindow::drawSelf(f32 param_0, f32 param_1, Mtx* param_2) { + GX_AND_TRACY_SCOPED("J2DWindow::drawSelf") + JGeometry::TBox2 stack_50(mBounds); stack_50.addPos(JGeometry::TVec2(param_0, param_1)); if (stack_50.getWidth() >= field_0x140 && stack_50.getHeight() >= field_0x142) { diff --git a/libs/JSystem/src/J2DGraph/J2DWindowEx.cpp b/libs/JSystem/src/J2DGraph/J2DWindowEx.cpp index b8c4e5f79e..fe4c5df9e6 100644 --- a/libs/JSystem/src/J2DGraph/J2DWindowEx.cpp +++ b/libs/JSystem/src/J2DGraph/J2DWindowEx.cpp @@ -122,6 +122,7 @@ J2DWindowEx::~J2DWindowEx() { } void J2DWindowEx::drawSelf(f32 param_0, f32 param_1, f32 (*param_2)[3][4]) { + GX_AND_TRACY_SCOPED("J2DWindowEx::drawSelf") JGeometry::TBox2 aTStack_50(mBounds); Mtx auStack_40; aTStack_50.addPos(JGeometry::TVec2(param_0, param_1)); diff --git a/src/d/d_meter2_draw.cpp b/src/d/d_meter2_draw.cpp index 28f25aa0cd..417dcad319 100644 --- a/src/d/d_meter2_draw.cpp +++ b/src/d/d_meter2_draw.cpp @@ -1562,6 +1562,7 @@ void dMeter2Draw_c::setAlphaLifeAnimeMax() { } void dMeter2Draw_c::drawKanteraScreen(u8 i_meterType) { + GX_AND_TRACY_SCOPED("drawKanteraScreen"); J2DGrafContext* graf_ctx = dComIfGp_getCurrentGrafPort(); mpMagicParent->setAlphaRate(mMeterAlphaRate[i_meterType]); From cffb4b24005f457113b0a1326e2d1cc161fe8aca Mon Sep 17 00:00:00 2001 From: PJB3005 Date: Sat, 11 Apr 2026 16:13:45 +0200 Subject: [PATCH 3/5] Make J2DPictureEx not draw if zero alpha Reduces the amount of draw calls from inactive UI elements by a lot. --- libs/JSystem/src/J2DGraph/J2DPictureEx.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/libs/JSystem/src/J2DGraph/J2DPictureEx.cpp b/libs/JSystem/src/J2DGraph/J2DPictureEx.cpp index 62925c4a98..ba69048a4b 100644 --- a/libs/JSystem/src/J2DGraph/J2DPictureEx.cpp +++ b/libs/JSystem/src/J2DGraph/J2DPictureEx.cpp @@ -78,9 +78,21 @@ bool J2DPictureEx::prepareTexture(u8 param_0) { return true; } +#if TARGET_PC +bool checkAlphaCull(const J2DPictureEx* pic) { + return pic->mColorAlpha == 0; +} +#endif + void J2DPictureEx::drawSelf(f32 param_0, f32 param_1, f32 (*param_2)[3][4]) { GX_AND_TRACY_SCOPED("J2DPictureEx::drawSelf") if (mMaterial != NULL) { +#if TARGET_PC + if (checkAlphaCull(this)) { + return; + } +#endif + mMaterial->setGX(); GXClearVtxDesc(); GXSetVtxDesc(GX_VA_POS, GX_DIRECT); From c29f6737e5a7d10372f04f9778979d2e9afe7437 Mon Sep 17 00:00:00 2001 From: PJB3005 Date: Sat, 11 Apr 2026 17:10:04 +0200 Subject: [PATCH 4/5] Guess this isn't going to Tracy. --- src/d/d_drawlist.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/d/d_drawlist.cpp b/src/d/d_drawlist.cpp index 98a22ecf13..1474b6f24d 100644 --- a/src/d/d_drawlist.cpp +++ b/src/d/d_drawlist.cpp @@ -14,6 +14,7 @@ #include #include "absl/container/flat_hash_map.h" +#include "client/TracyScoped.hpp" #include "d/d_s_play.h" #include "dusk/frame_interpolation.h" #include "dusk/gx_helper.h" @@ -1952,7 +1953,7 @@ void dDlst_list_c::draw(dDlst_base_c** p_start, dDlst_base_c** p_end) { #if TARGET_PC && (TRACY_ENABLE || PARTIAL_DEBUG) const auto name = getTypeDrawName(dlst); - GX_AND_TRACY_SCOPED(name); + GXScopedDebugGroup scope(name); #endif dlst->draw(); } From 14e77aed9c297471a59321523cce9bf06b968490 Mon Sep 17 00:00:00 2001 From: PJB3005 Date: Sat, 11 Apr 2026 21:46:14 +0200 Subject: [PATCH 5/5] Fix JUTResFont duplicating texture data I misunderstood the way this code works the first time. --- libs/JSystem/src/JUtility/JUTResFont.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/JSystem/src/JUtility/JUTResFont.cpp b/libs/JSystem/src/JUtility/JUTResFont.cpp index 10443d6404..206968f053 100644 --- a/libs/JSystem/src/JUtility/JUTResFont.cpp +++ b/libs/JSystem/src/JUtility/JUTResFont.cpp @@ -435,10 +435,10 @@ void JUTResFont::loadImage(int code, GXTexMapID id){ mHeight = cellRow * cellH; #if TARGET_PC - const auto found = mGlyphTextures->textures.find(code); + const auto found = mGlyphTextures->textures.find(pageIdx); GXTexObj* texObj; if (found == mGlyphTextures->textures.end()) { - texObj = &mGlyphTextures->textures[code]; + texObj = &mGlyphTextures->textures[pageIdx]; void* pImg = &mpGlyphBlocks[i]->data[pageIdx * mpGlyphBlocks[i]->textureSize]; GXInitTexObj(texObj, pImg, mpGlyphBlocks[i]->textureWidth, mpGlyphBlocks[i]->textureHeight, (GXTexFmt)(u16)mpGlyphBlocks[i]->textureFormat,