diff --git a/src/common/debug.h b/src/common/debug.h index f89590aa..98f6d3eb 100644 --- a/src/common/debug.h +++ b/src/common/debug.h @@ -12,3 +12,40 @@ #endif #include + +static inline bool IsProfilerConnected() { + return tracy::GetProfiler().IsConnected(); +} + +#define CUSTOM_LOCK(type, varname) \ + tracy::LockableCtx varname { \ + []() -> const tracy::SourceLocationData* { \ + static constexpr tracy::SourceLocationData srcloc{nullptr, #type " " #varname, \ + TracyFile, TracyLine, 0}; \ + return &srcloc; \ + }() \ + } + +#define TRACK_ALLOC(ptr, size, pool) TracyAllocN(std::bit_cast(ptr), (size), (pool)) +#define TRACK_FREE(ptr, pool) TracyFreeN(std::bit_cast(ptr), (pool)) + +enum MarkersPallete : int { + EmulatorMarkerColor = 0x264653, + RendererMarkerColor = 0x2a9d8f, + HleMarkerColor = 0xe9c46a, + Reserved0 = 0xf4a261, + Reserved1 = 0xe76f51, +}; + +#define EMULATOR_TRACE ZoneScopedC(EmulatorMarkerColor) +#define RENDERER_TRACE ZoneScopedC(RendererMarkerColor) +#define HLE_TRACE ZoneScopedC(HleMarkerColor) + +#define TRACE_WARN(msg) \ + [](const auto& msg) { TracyMessageC(msg.c_str(), msg.size(), tracy::Color::DarkOrange); }(msg); +#define TRACE_ERROR(msg) \ + [](const auto& msg) { TracyMessageC(msg.c_str(), msg.size(), tracy::Color::Red); }(msg) +#define TRACE_CRIT(msg) \ + [](const auto& msg) { TracyMessageC(msg.c_str(), msg.size(), tracy::Color::HotPink); }(msg) + +#define FRAME_END FrameMark diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index 0fd344b5..460b7376 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -13,6 +13,7 @@ #include "common/bounded_threadsafe_queue.h" #include "common/config.h" +#include "common/debug.h" #include "common/io_file.h" #include "common/logging/backend.h" #include "common/logging/log.h" @@ -167,6 +168,24 @@ public: void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num, const char* function, std::string message) { + // Propagate important log messages to the profiler + if (IsProfilerConnected()) { + const auto& msg_str = std::format("[{}] {}", GetLogClassName(log_class), message); + switch (log_level) { + case Level::Warning: + TRACE_WARN(msg_str); + break; + case Level::Error: + TRACE_ERROR(msg_str); + break; + case Level::Critical: + TRACE_CRIT(msg_str); + break; + default: + break; + } + } + if (!filter.CheckMessage(log_class, log_level)) { return; } diff --git a/src/core/memory.cpp b/src/core/memory.cpp index a6068053..5029f82c 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -3,6 +3,7 @@ #include "common/alignment.h" #include "common/assert.h" +#include "common/debug.h" #include "common/scope_exit.h" #include "core/libraries/error_codes.h" #include "core/libraries/kernel/memory_management.h" @@ -123,6 +124,7 @@ int MemoryManager::MapMemory(void** out_addr, VAddr virtual_addr, size_t size, M // Perform the mapping. *out_addr = impl.Map(mapped_addr, size, alignment, phys_addr, is_exec); + TRACK_ALLOC(*out_addr, size, "VMEM"); return ORBIS_OK; } @@ -149,6 +151,7 @@ void MemoryManager::UnmapMemory(VAddr virtual_addr, size_t size) { // Unmap the memory region. impl.Unmap(virtual_addr, size, phys_addr); + TRACK_FREE(virtual_addr, "VMEM"); } int MemoryManager::QueryProtection(VAddr addr, void** start, void** end, u32* prot) { diff --git a/src/emulator.cpp b/src/emulator.cpp index 793d996a..c5facd19 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -8,6 +8,7 @@ #include #include #include "common/config.h" +#include "common/debug.h" #include "common/logging/backend.h" #include "common/path_util.h" #include "common/singleton.h" @@ -121,6 +122,7 @@ void Emulator::Run(const std::filesystem::path& file) { window.waitEvent(); Libraries::VideoOut::Flip(FlipPeriod); Libraries::VideoOut::Vblank(); + FRAME_END; } std::exit(0); diff --git a/src/video_core/amdgpu/liverpool.cpp b/src/video_core/amdgpu/liverpool.cpp index 7f275e8c..e0cf86aa 100644 --- a/src/video_core/amdgpu/liverpool.cpp +++ b/src/video_core/amdgpu/liverpool.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "common/assert.h" +#include "common/debug.h" #include "common/thread.h" #include "video_core/amdgpu/liverpool.h" #include "video_core/amdgpu/pm4_cmds.h" @@ -9,6 +10,10 @@ namespace AmdGpu { +static const char* dcb_task_name{"DCB_TASK"}; +static const char* ccb_task_name{"CCB_TASK"}; +static const char* asc_task_name{"ACB_TASK"}; + std::array Liverpool::ConstantEngine::constants_heap; Liverpool::Liverpool() { @@ -69,12 +74,16 @@ void Liverpool::Process(std::stop_token stoken) { } void Liverpool::WaitGpuIdle() { + RENDERER_TRACE; + while (const auto old = num_submits.load()) { num_submits.wait(old); } } Liverpool::Task Liverpool::ProcessCeUpdate(std::span ccb) { + TracyFiberEnter(ccb_task_name); + while (!ccb.empty()) { const auto* header = reinterpret_cast(ccb.data()); const u32 type = header->type; @@ -109,7 +118,9 @@ Liverpool::Task Liverpool::ProcessCeUpdate(std::span ccb) { case PM4ItOpcode::WaitOnDeCounterDiff: { const auto diff = it_body[0]; while ((cblock.de_count - cblock.ce_count) >= diff) { + TracyFiberLeave; co_yield {}; + TracyFiberEnter(ccb_task_name); } break; } @@ -120,9 +131,13 @@ Liverpool::Task Liverpool::ProcessCeUpdate(std::span ccb) { } ccb = ccb.subspan(header->type3.NumWords() + 1); } + + TracyFiberLeave; } Liverpool::Task Liverpool::ProcessGraphics(std::span dcb, std::span ccb) { + TracyFiberEnter(dcb_task_name); + cblock.Reset(); // TODO: potentially, ASCs also can depend on CE and in this case the @@ -132,7 +147,9 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span dcb, std::span dcb, std::span(header); ASSERT(wait_reg_mem->engine.Value() == PM4CmdWaitRegMem::Engine::Me); while (!wait_reg_mem->Test()) { + TracyFiberLeave; co_yield {}; + TracyFiberEnter(dcb_task_name); } break; } @@ -340,7 +359,9 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span dcb, std::span dcb, std::span acb) { diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 291d38fd..abb6d328 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "common/config.h" +#include "common/debug.h" #include "core/memory.h" #include "video_core/amdgpu/liverpool.h" #include "video_core/renderer_vulkan/vk_instance.h" @@ -33,6 +34,8 @@ Rasterizer::Rasterizer(const Instance& instance_, Scheduler& scheduler_, Rasterizer::~Rasterizer() = default; void Rasterizer::Draw(bool is_indexed, u32 index_offset) { + RENDERER_TRACE; + const auto cmdbuf = scheduler.CommandBuffer(); const auto& regs = liverpool->regs; const u32 num_indices = SetupIndexBuffer(is_indexed, index_offset); @@ -104,6 +107,8 @@ void Rasterizer::Draw(bool is_indexed, u32 index_offset) { } void Rasterizer::DispatchDirect() { + RENDERER_TRACE; + const auto cmdbuf = scheduler.CommandBuffer(); const auto& cs_program = liverpool->regs.cs_program; const ComputePipeline* pipeline = pipeline_cache.GetComputePipeline();