Browse Source

basic tracy support via cmake and some fixes in code (allows sample based-profiling, no instrumentation included)

pull/3759/head
Hexcoder 6 days ago
parent
commit
0b2e265d6d
  1. 25
      CMakeLists.txt
  2. 7
      cpmfile.json
  3. 27
      src/common/fiber.cpp
  4. 22
      src/common/tracy_instrumentation.h
  5. 6
      src/video_core/renderer_vulkan/vk_swapchain.cpp
  6. 4
      src/yuzu/CMakeLists.txt
  7. 19
      src/yuzu/main.cpp
  8. 4
      src/yuzu_cmd/CMakeLists.txt
  9. 4
      src/yuzu_room_standalone/CMakeLists.txt

25
CMakeLists.txt

@ -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
# ===================

7
cpmfile.json

@ -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
}
}

27
src/common/fiber.cpp

@ -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

@ -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

6
src/video_core/renderer_vulkan/vk_swapchain.cpp

@ -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) {

4
src/yuzu/CMakeLists.txt

@ -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()

19
src/yuzu/main.cpp

@ -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;
}

4
src/yuzu_cmd/CMakeLists.txt

@ -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

4
src/yuzu_room_standalone/CMakeLists.txt

@ -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…
Cancel
Save