Skip to content

Commit

Permalink
Add Tracy Profiler Support
Browse files Browse the repository at this point in the history
  • Loading branch information
tomadamatkinson committed Aug 1, 2023
1 parent 7333a2b commit b66167a
Show file tree
Hide file tree
Showing 17 changed files with 518 additions and 39 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ output/*
*~
.*.sw*
.sw*
.tracy
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,6 @@
[submodule "third_party/catch2"]
path = third_party/catch2
url = https://github.com/catchorg/Catch2.git
[submodule "third_party/tracy"]
path = third_party/tracy
url = https://github.com/wolfpld/tracy.git
5 changes: 4 additions & 1 deletion bldsys/cmake/global_options.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ set(VKB_BUILD_TESTS OFF CACHE BOOL "Enable generation and building of Vulkan bes
set(VKB_WSI_SELECTION "XCB" CACHE STRING "Select WSI target (XCB, XLIB, WAYLAND, D2D)")
set(VKB_CLANG_TIDY OFF CACHE STRING "Use CMake Clang Tidy integration")
set(VKB_CLANG_TIDY_EXTRAS "-header-filter=framework,samples,app;-checks=-*,google-*,-google-runtime-references;--fix;--fix-errors" CACHE STRING "Clang Tidy Parameters")
set(VKB_ENABLE_TRACY OFF CACHE BOOL "Enable Tracy profiling")

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "bin/${CMAKE_BUILD_TYPE}/${TARGET_ARCH}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "lib/${CMAKE_BUILD_TYPE}/${TARGET_ARCH}")
Expand All @@ -73,4 +74,6 @@ set(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG=0 ${CMAKE_CXX_FLAGS_DEBUG}")
if (VKB_CLANG_TIDY)
find_program(CLANG_TIDY "clang-tidy" "clang-tidy-15" REQUIRED)
set(VKB_DO_CLANG_TIDY ${CLANG_TIDY} ${VKB_CLANG_TIDY_EXTRAS})
endif()
endif()

set(TRACY_ENABLE ${VKB_ENABLE_TRACY})
8 changes: 7 additions & 1 deletion components/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,19 @@
vkb__register_component(
NAME core
HEADERS
include/core/util/strings.hpp
include/core/platform/context.hpp
include/core/platform/entrypoint.hpp

include/core/util/error.hpp
include/core/util/hash.hpp
include/core/util/profiling.hpp
include/core/util/strings.hpp
SRC
src/strings.cpp
src/profiling.cpp
LINK_LIBS
spdlog::spdlog
TracyClient
)

vkb__register_tests(
Expand Down
118 changes: 118 additions & 0 deletions components/core/include/core/util/profiling.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/* Copyright (c) 2023, Thomas Atkinson
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include <stdint.h>

#include <unordered_map>

#include <tracy/Tracy.hpp>

// malloc and free are used by Tracy to provide memory profiling
void *operator new(size_t count);
void operator delete(void *ptr) noexcept;

// Tracy a scope
#define PROFILE_SCOPE(name) ZoneScopedN(name)

// Trace a function
#define PROFILE_FUNCTION() ZoneScoped

// The type of plot to use
enum class PlotType
{
Number,
Percentage,
Memory,
};

// tracy::PlotFormatType is not defined if TRACY_ENABLE is not defined
// so we need to define a function to convert our enum to the tracy enum
#ifdef TRACY_ENABLE
namespace
{
inline tracy::PlotFormatType to_tracy_plot_format(PlotType type)
{
switch (type)
{
case PlotType::Number:
return tracy::PlotFormatType::Number;
case PlotType::Percentage:
return tracy::PlotFormatType::Percentage;
case PlotType::Memory:
return tracy::PlotFormatType::Memory;
default:
return tracy::PlotFormatType::Number;
}
}
} // namespace

# define TO_TRACY_PLOT_FORMAT(name) to_tracy_plot_format(name)
#else
# define TO_TRACY_PLOT_FORMAT(name)
#endif

// Create plots
template <typename T, PlotType PT = PlotType::Number>
class Plot
{
public:
static void plot(const char *name, T value)
{
auto *p = get_instance();
p->plots[name] = value;
update_tracy_plot(name, value);
}

static void increment(const char *name, T amount)
{
auto *p = get_instance();
p->plots[name] += amount;
update_tracy_plot(name, p->plots[name]);
}

static void decrement(const char *name, T amount)
{
auto *p = get_instance();
p->plots[name] -= amount;
update_tracy_plot(name, p->plots[name]);
}

static void reset(const char *name)
{
auto *p = get_instance();
p->plots[name] = T{};
update_tracy_plot(name, p->plots[name]);
}

private:
static void update_tracy_plot(const char *name, T value)
{
TracyPlot(name, value);
TracyPlotConfig(name, TO_TRACY_PLOT_FORMAT(PT), true, true, 0);
}

static Plot *get_instance()
{
static_assert((std::is_same<T, int64_t>::value || std::is_same<T, double>::value || std::is_same<T, float>::value), "PlotStore only supports int64_t, double and float");
static Plot instance;
return &instance;
}

std::unordered_map<const char *, T> plots;
};
31 changes: 31 additions & 0 deletions components/core/src/profiling.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* Copyright (c) 2023, Thomas Atkinson
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "core/util/profiling.hpp"

void *operator new(size_t count)
{
auto ptr = malloc(count);
TracyAlloc(ptr, count);
return ptr;
}

void operator delete(void *ptr) noexcept
{
TracyFree(ptr);
free(ptr);
}
2 changes: 1 addition & 1 deletion framework/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
glm
glslang
SPIRV
vma
VulkanMemoryAllocator
hwcpipe
spirv-cross-glsl
glslang-default-resource-limits
Expand Down
23 changes: 14 additions & 9 deletions framework/core/device.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Copyright (c) 2019-2022, Arm Limited and Contributors
* Copyright (c) 2019-2022, Sascha Willems
/* Copyright (c) 2019-2023, Arm Limited and Contributors
* Copyright (c) 2019-2023, Sascha Willems
*
* SPDX-License-Identifier: Apache-2.0
*
Expand All @@ -25,9 +25,9 @@ VKBP_ENABLE_WARNINGS()

namespace vkb
{
Device::Device(PhysicalDevice & gpu,
Device::Device(PhysicalDevice &gpu,
VkSurfaceKHR surface,
std::unique_ptr<DebugUtils> && debug_utils,
std::unique_ptr<DebugUtils> &&debug_utils,
std::unordered_map<const char *, bool> requested_extensions) :
VulkanResource{VK_NULL_HANDLE, this}, // Recursive, but valid
debug_utils{std::move(debug_utils)},
Expand Down Expand Up @@ -198,6 +198,9 @@ Device::Device(PhysicalDevice & gpu,
}

VmaVulkanFunctions vma_vulkan_func{};
vma_vulkan_func.vkGetDeviceProcAddr = vkGetDeviceProcAddr;
vma_vulkan_func.vkGetInstanceProcAddr = vkGetInstanceProcAddr;

vma_vulkan_func.vkAllocateMemory = vkAllocateMemory;
vma_vulkan_func.vkBindBufferMemory = vkBindBufferMemory;
vma_vulkan_func.vkBindImageMemory = vkBindImageMemory;
Expand Down Expand Up @@ -263,10 +266,10 @@ Device::~Device()

if (memory_allocator != VK_NULL_HANDLE)
{
VmaStats stats;
vmaCalculateStats(memory_allocator, &stats);
VmaTotalStatistics stats;
vmaCalculateStatistics(memory_allocator, &stats);

LOGI("Total device memory leaked: {} bytes.", stats.total.usedBytes);
LOGI("Total device memory leaked: {} bytes.", stats.total.statistics.allocationBytes);

vmaDestroyAllocator(memory_allocator);
}
Expand Down Expand Up @@ -306,15 +309,17 @@ DriverVersion Device::get_driver_version() const

switch (gpu.get_properties().vendorID)
{
case 0x10DE: {
case 0x10DE:
{
// Nvidia
version.major = (gpu.get_properties().driverVersion >> 22) & 0x3ff;
version.minor = (gpu.get_properties().driverVersion >> 14) & 0x0ff;
version.patch = (gpu.get_properties().driverVersion >> 6) & 0x0ff;
// Ignoring optional tertiary info in lower 6 bits
break;
}
default: {
default:
{
version.major = VK_VERSION_MAJOR(gpu.get_properties().driverVersion);
version.minor = VK_VERSION_MINOR(gpu.get_properties().driverVersion);
version.patch = VK_VERSION_PATCH(gpu.get_properties().driverVersion);
Expand Down
9 changes: 6 additions & 3 deletions framework/core/hpp_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,9 @@ HPPDevice::HPPDevice(vkb::core::HPPPhysicalDevice &gpu,
}

VmaVulkanFunctions vma_vulkan_func{};
vma_vulkan_func.vkGetDeviceProcAddr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(get_handle().getProcAddr("vkGetDeviceProcAddr"));
vma_vulkan_func.vkGetInstanceProcAddr = reinterpret_cast<PFN_vkGetInstanceProcAddr>(get_handle().getProcAddr("vkGetInstanceProcAddr"));

vma_vulkan_func.vkAllocateMemory = reinterpret_cast<PFN_vkAllocateMemory>(get_handle().getProcAddr("vkAllocateMemory"));
vma_vulkan_func.vkBindBufferMemory = reinterpret_cast<PFN_vkBindBufferMemory>(get_handle().getProcAddr("vkBindBufferMemory"));
vma_vulkan_func.vkBindImageMemory = reinterpret_cast<PFN_vkBindImageMemory>(get_handle().getProcAddr("vkBindImageMemory"));
Expand Down Expand Up @@ -239,10 +242,10 @@ HPPDevice::~HPPDevice()

if (memory_allocator != VK_NULL_HANDLE)
{
VmaStats stats;
vmaCalculateStats(memory_allocator, &stats);
VmaTotalStatistics stats;
vmaCalculateStatistics(memory_allocator, &stats);

LOGI("Total device memory leaked: {} bytes.", stats.total.usedBytes);
LOGI("Total device memory leaked: {} bytes.", stats.total.statistics.allocationBytes);

vmaDestroyAllocator(memory_allocator);
}
Expand Down
6 changes: 6 additions & 0 deletions framework/gltf_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ VKBP_DISABLE_WARNINGS()
#include <glm/gtc/type_ptr.hpp>
VKBP_ENABLE_WARNINGS()

#include <core/util/profiling.hpp>

#include "api_vulkan_sample.h"
#include "common/logging.h"
#include "common/utils.h"
Expand Down Expand Up @@ -406,6 +408,8 @@ GLTFLoader::GLTFLoader(Device const &device) :

std::unique_ptr<sg::Scene> GLTFLoader::read_scene_from_file(const std::string &file_name, int scene_index)
{
PROFILE_SCOPE("Load GLTF Scene");

std::string err;
std::string warn;

Expand Down Expand Up @@ -448,6 +452,8 @@ std::unique_ptr<sg::Scene> GLTFLoader::read_scene_from_file(const std::string &f

std::unique_ptr<sg::SubMesh> GLTFLoader::read_model_from_file(const std::string &file_name, uint32_t index, bool storage_buffer)
{
PROFILE_SCOPE("Load GLTF Model");

std::string err;
std::string warn;

Expand Down
Loading

0 comments on commit b66167a

Please sign in to comment.