mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-14 11:18:58 +02:00
basic tracy support via cmake and some fixes in code (allows sample based-profiling, no instrumentation included)
This commit is contained in:
parent
f0a4ac7359
commit
0b2e265d6d
9 changed files with 118 additions and 0 deletions
|
|
@ -219,6 +219,8 @@ cmake_dependent_option(YUZU_CMD "Compile the eden-cli executable" ON "NOT ANDROI
|
|||
|
||||
cmake_dependent_option(YUZU_CRASH_DUMPS "Compile crash dump (Minidump) support" OFF "WIN32 OR PLATFORM_LINUX" OFF)
|
||||
|
||||
option(ENABLE_TRACY "Enable Tracy profiler support" OFF)
|
||||
|
||||
option(YUZU_DOWNLOAD_TIME_ZONE_DATA "Always download time zone binaries" ON)
|
||||
set(YUZU_TZDB_PATH "" CACHE STRING "Path to a pre-downloaded timezone database")
|
||||
|
||||
|
|
@ -662,6 +664,29 @@ if (WIN32 AND YUZU_CRASH_DUMPS)
|
|||
# target_include_directories(libbreakpad_client INTERFACE "${BREAKPAD_CLIENT_INCLUDE_DIR}")
|
||||
endif()
|
||||
|
||||
if (ENABLE_TRACY)
|
||||
AddJsonPackage(tracy)
|
||||
|
||||
if (tracy_ADDED)
|
||||
include_directories(${tracy_SOURCE_DIR}/public)
|
||||
# build tracy client as its own static library even if overkill
|
||||
add_library(tracy_client STATIC ${tracy_SOURCE_DIR}/public/TracyClient.cpp)
|
||||
target_include_directories(tracy_client PRIVATE src)
|
||||
|
||||
# Avoid tracy errors (This sets it to W0 instead of W3 though? TODO: fix this)
|
||||
if (MSVC AND CXX_CLANG)
|
||||
target_compile_options(tracy_client PRIVATE /W3)
|
||||
endif()
|
||||
|
||||
add_compile_definitions(TRACY_ENABLE)
|
||||
add_compile_definitions(TRACY_SAMPLING_PROFILER_MANUAL_START) # See yuzu\main.cpp
|
||||
add_compile_definitions(TRACY_ON_DEMAND) # Use on demand mode to avoid profiling emulator start up and game load screens
|
||||
add_compile_definitions(TRACY_FIBERS)
|
||||
|
||||
add_library(Tracy::client ALIAS tracy_client)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Include source code
|
||||
# ===================
|
||||
|
||||
|
|
|
|||
|
|
@ -114,5 +114,12 @@
|
|||
"QUAZIP_INSTALL OFF",
|
||||
"QUAZIP_ENABLE_QTEXTCODEC OFF"
|
||||
]
|
||||
},
|
||||
"tracy": {
|
||||
"repo": "wolfpld/tracy",
|
||||
"sha": "05cceee",
|
||||
"hash": "fdf8f3eb0f44c17760e9e559ece6907606580da20568b7900e97e40f3ea773b9e6dbac7f0b04ef32e363d779ec013af63c85adbe2a3807db9205ec48887a546c",
|
||||
"version": "0.13.1",
|
||||
"download_only": true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@
|
|||
|
||||
#include <boost/context/detail/fcontext.hpp>
|
||||
|
||||
//#include "common/tracy_instrumentation.h"
|
||||
//#include <sstream>
|
||||
|
||||
namespace Common {
|
||||
|
||||
#ifdef __OPENORBIS__
|
||||
|
|
@ -42,6 +45,13 @@ struct Fiber::FiberImpl {
|
|||
u8* rewind_stack_limit = nullptr;
|
||||
bool is_thread_fiber = false;
|
||||
bool released = false;
|
||||
|
||||
// Support tracy fibers, show them using incrementing counter in profiler
|
||||
// TODO: Commented out because I could not properly test because CPU threads have messed up ghost zones due to jit code failing to support stack traces
|
||||
//#if TRACY_ENABLE
|
||||
// std::string tracy_fiber_name;
|
||||
// static inline int tracy_fiber_next_id = 1;
|
||||
//#endif
|
||||
};
|
||||
|
||||
void Fiber::SetRewindPoint(std::function<void()>&& rewind_func) {
|
||||
|
|
@ -49,12 +59,20 @@ void Fiber::SetRewindPoint(std::function<void()>&& rewind_func) {
|
|||
}
|
||||
|
||||
Fiber::Fiber(std::function<void()>&& entry_point_func) : impl{std::make_unique<FiberImpl>()} {
|
||||
//#if TRACY_ENABLE
|
||||
// std::ostringstream ss;
|
||||
// ss << "fiber #" << impl->tracy_fiber_next_id++;
|
||||
// impl->tracy_fiber_name = std::move(ss).str();
|
||||
//#endif
|
||||
impl->entry_point = std::move(entry_point_func);
|
||||
impl->stack_limit = impl->stack.data();
|
||||
impl->rewind_stack_limit = impl->rewind_stack.data();
|
||||
u8* stack_base = impl->stack_limit + DEFAULT_STACK_SIZE;
|
||||
impl->context = boost::context::detail::make_fcontext(stack_base, impl->stack.size(), [](boost::context::detail::transfer_t transfer) -> void {
|
||||
auto* fiber = static_cast<Fiber*>(transfer.data);
|
||||
//#if TRACY_ENABLE
|
||||
// TracyFiberEnter(fiber->impl->tracy_fiber_name.c_str());
|
||||
//#endif
|
||||
ASSERT(fiber && fiber->impl && fiber->impl->previous_fiber && fiber->impl->previous_fiber->impl);
|
||||
ASSERT(fiber->impl->canary_1 == CANARY_VALUE);
|
||||
ASSERT(fiber->impl->canary_2 == CANARY_VALUE);
|
||||
|
|
@ -91,7 +109,16 @@ void Fiber::YieldTo(std::weak_ptr<Fiber> weak_from, Fiber& to) {
|
|||
to.impl->guard.lock();
|
||||
to.impl->previous_fiber = weak_from.lock();
|
||||
|
||||
//#if TRACY_ENABLE
|
||||
// // Is this correct?
|
||||
// TracyFiberLeave;
|
||||
//#endif
|
||||
|
||||
auto transfer = boost::context::detail::jump_fcontext(to.impl->context, &to);
|
||||
//#if TRACY_ENABLE
|
||||
// // Switched to executing "to" fiber, inform tracy
|
||||
// TracyFiberEnter(to.impl->tracy_fiber_name.c_str());
|
||||
//#endif
|
||||
// "from" might no longer be valid if the thread was killed
|
||||
if (auto from = weak_from.lock()) {
|
||||
if (from->impl->previous_fiber == nullptr) {
|
||||
|
|
|
|||
22
src/common/tracy_instrumentation.h
Normal file
22
src/common/tracy_instrumentation.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
// Add our own tracy instrumentation macros which compile to nothing without TRACY_ENABLE
|
||||
// tracys macros alread do that but do require you to always include the full tracy code even without TRACY_ENABLE
|
||||
// Doing this means any instrumentation in the project keeps compiling even with ENABLE_TRACY=0 in cmake, meaning most devs can compile without even pulling tracy at all
|
||||
// Additionally These macros may be more readable than the badly named "ZoneScoped", and we could easily add levels or categories of instrumentation that can be made selectable
|
||||
// Unless there is already a tracing framework that is configurable...?
|
||||
#if TRACY_ENABLE
|
||||
#include <tracy/Tracy.hpp>
|
||||
|
||||
#define TRACY_ZONE_SCOPED ZoneScoped;
|
||||
#define TRACY_ZONE_SCOPEDN(name) ZoneScopedN(name);
|
||||
#define TRACY_ZONE_SCOPEDVN(var, name) ZoneScopedVN(var, name);
|
||||
#define TRACY_ZONE_NAMEDN(var, name) ZoneNamedN(var, name, true);
|
||||
#define TRACY_MSG_C(text, col) TracyMessageC(text, strlen(text), col);
|
||||
#else
|
||||
#define TRACY_ZONE_SCOPED
|
||||
#define TRACY_ZONE_SCOPEDN(name)
|
||||
#define TRACY_ZONE_SCOPEDVN(var, name)
|
||||
#define TRACY_ZONE_NAMEDN(var, name)
|
||||
#define TRACY_MSG_C(text, col)
|
||||
#endif
|
||||
|
|
@ -19,6 +19,8 @@
|
|||
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
||||
#include "vulkan/vulkan_core.h"
|
||||
|
||||
#include "common/tracy_instrumentation.h"
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
namespace {
|
||||
|
|
@ -226,6 +228,10 @@ void Swapchain::Present(VkSemaphore render_semaphore) {
|
|||
if (frame_index >= image_count) {
|
||||
frame_index = 0;
|
||||
}
|
||||
|
||||
#if TRACY_ENABLE
|
||||
FrameMark;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities) {
|
||||
|
|
|
|||
|
|
@ -401,6 +401,10 @@ target_link_libraries(yuzu PRIVATE common core input_common frontend_common netw
|
|||
target_link_libraries(yuzu PRIVATE Boost::headers glad Qt6::Widgets Qt6::Charts Qt6::Concurrent)
|
||||
target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
|
||||
|
||||
if (ENABLE_TRACY)
|
||||
target_link_libraries(yuzu PRIVATE Tracy::client)
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
target_link_libraries(yuzu PRIVATE Qt6::DBus)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
#ifdef _WIN32
|
||||
#include <QScreen>
|
||||
|
||||
#include "common/tracy_instrumentation.h"
|
||||
|
||||
static void OverrideWindowsFont() {
|
||||
// Qt5 chooses these fonts on Windows and they have fairly ugly alphanumeric/cyrillic characters
|
||||
// Asking to use "MS Shell Dlg 2" gives better other chars while leaving the Chinese Characters.
|
||||
|
|
@ -91,6 +93,17 @@ int main(int argc, char* argv[]) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if TRACY_ENABLE
|
||||
// Avoid cmake static library for tracy being optimized away by "helpful" linker if when not referenced (no manual instrumentation, but still want sample-based mode)
|
||||
//TracyNoop; // This would be needed if not for tracy::BeginSamplingProfiling
|
||||
|
||||
// have to use TRACY_SAMPLING_PROFILER_MANUAL_START because program is started a second time as child process for vulkan check
|
||||
// this messes with tracy sample profiling as windows event tracing in child process stops it for parent process
|
||||
if (!is_child) {
|
||||
tracy::BeginSamplingProfiling();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (StartupChecks(argv[0], &has_broken_vulkan,
|
||||
Settings::values.perform_vulkan_check.GetValue())) {
|
||||
return 0;
|
||||
|
|
@ -177,5 +190,11 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
int result = app.exec();
|
||||
detached_tasks.WaitForAllTasks();
|
||||
|
||||
#if TRACY_ENABLE
|
||||
if (!is_child) {
|
||||
tracy::EndSamplingProfiling();
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,10 @@ if(WIN32)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if (ENABLE_TRACY)
|
||||
target_link_libraries(yuzu-cmd PRIVATE Tracy::client)
|
||||
endif()
|
||||
|
||||
create_target_directory_groups(yuzu-cmd)
|
||||
|
||||
# needed for vma
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@ if(UNIX AND NOT APPLE)
|
|||
install(TARGETS yuzu_room_standalone RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
|
||||
endif()
|
||||
|
||||
if (ENABLE_TRACY)
|
||||
target_link_libraries(yuzu_room_standalone PRIVATE Tracy::client)
|
||||
endif()
|
||||
|
||||
if (YUZU_STATIC_ROOM)
|
||||
target_link_options(yuzu_room_standalone PRIVATE "-static")
|
||||
endif()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue