From 1d20af25ef752b838339f1888e92f2845327735a Mon Sep 17 00:00:00 2001 From: Tom Atkinson Date: Mon, 17 Jul 2023 18:25:55 +0100 Subject: [PATCH 1/5] Add Tracy Profiler Support Android fixes document tracy --- .gitignore | 3 +- .gitmodules | 3 + bldsys/cmake/global_options.cmake | 5 +- components/core/CMakeLists.txt | 3 + components/core/include/core/util/error.hpp | 16 +- .../core/include/core/util/profiling.hpp | 123 +++++++++++++++ components/core/src/profiling.cpp | 33 ++++ docs/build.adoc | 13 ++ framework/CMakeLists.txt | 1 + framework/common/error.h | 44 ++---- framework/gltf_loader.cpp | 12 ++ .../scene_graph/components/image/astc.cpp | 3 + framework/stats/stats.cpp | 145 +++++++++++++++++- framework/stats/stats.h | 7 +- third_party/CMakeLists.txt | 26 ++-- third_party/tracy | 1 + 16 files changed, 386 insertions(+), 52 deletions(-) create mode 100644 components/core/include/core/util/profiling.hpp create mode 100644 components/core/src/profiling.cpp create mode 160000 third_party/tracy diff --git a/.gitignore b/.gitignore index 4fa0b48cbd..19099eeb43 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,5 @@ tags # vim backup and temp files *~ .*.sw* -.sw* \ No newline at end of file +.sw* +.tracy diff --git a/.gitmodules b/.gitmodules index 9325918c8c..375b9368a9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -59,3 +59,6 @@ [submodule "third_party/fmt"] path = third_party/fmt url = https://github.com/fmtlib/fmt +[submodule "third_party/tracy"] + path = third_party/tracy + url = https://github.com/wolfpld/tracy.git diff --git a/bldsys/cmake/global_options.cmake b/bldsys/cmake/global_options.cmake index 9eac0ae5e5..27ca7da06c 100644 --- a/bldsys/cmake/global_options.cmake +++ b/bldsys/cmake/global_options.cmake @@ -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_PROFILING 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}") @@ -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() \ No newline at end of file +endif() + +set(TRACY_ENABLE ${VKB_PROFILING}) diff --git a/components/core/CMakeLists.txt b/components/core/CMakeLists.txt index 8178320605..a5e61e9d34 100644 --- a/components/core/CMakeLists.txt +++ b/components/core/CMakeLists.txt @@ -24,11 +24,14 @@ vkb__register_component( include/core/util/error.hpp include/core/util/hash.hpp include/core/util/logging.hpp + include/core/util/profiling.hpp SRC src/strings.cpp src/logging.cpp + src/profiling.cpp LINK_LIBS spdlog::spdlog + TracyClient ) vkb__register_tests( diff --git a/components/core/include/core/util/error.hpp b/components/core/include/core/util/error.hpp index 780b88f1a5..eadf723a9d 100644 --- a/components/core/include/core/util/error.hpp +++ b/components/core/include/core/util/error.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2024, Thomas Atkinson +/* Copyright (c) 2023-2024, Thomas Atkinson * * SPDX-License-Identifier: Apache-2.0 * @@ -23,12 +23,12 @@ #if defined(__clang__) // CLANG ENABLE/DISABLE WARNING DEFINITION -# define VKBP_DISABLE_WARNINGS() \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic ignored \"-Wall\"") \ - _Pragma("clang diagnostic ignored \"-Wextra\"") \ - _Pragma("clang diagnostic ignored \"-Wtautological-compare\"") - +# define VKBP_DISABLE_WARNINGS() \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wall\"") \ + _Pragma("clang diagnostic ignored \"-Wextra\"") \ + _Pragma("clang diagnostic ignored \"-Wtautological-compare\"") \ + _Pragma("clang diagnostic ignored \"-Wnullability-completeness\"") # define VKBP_ENABLE_WARNINGS() \ _Pragma("clang diagnostic pop") #elif defined(__GNUC__) || defined(__GNUG__) @@ -66,4 +66,4 @@ inline void ERRORF(const std::string &message) throw std::runtime_error(message); } -#define NOT_IMPLEMENTED() ERRORF("not implemented") \ No newline at end of file +#define NOT_IMPLEMENTED() ERRORF("not implemented") diff --git a/components/core/include/core/util/profiling.hpp b/components/core/include/core/util/profiling.hpp new file mode 100644 index 0000000000..cd83a077b2 --- /dev/null +++ b/components/core/include/core/util/profiling.hpp @@ -0,0 +1,123 @@ +/* Copyright (c) 2023-2024, 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 +#include + +#include + +#include "core/util/error.hpp" + +VKBP_DISABLE_WARNINGS() +#include +VKBP_ENABLE_WARNINGS() + +// 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 +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::value || std::is_same::value || std::is_same::value), "PlotStore only supports int64_t, double and float"); + static Plot instance; + return &instance; + } + + std::unordered_map plots; +}; diff --git a/components/core/src/profiling.cpp b/components/core/src/profiling.cpp new file mode 100644 index 0000000000..b2ad001a29 --- /dev/null +++ b/components/core/src/profiling.cpp @@ -0,0 +1,33 @@ +/* Copyright (c) 2023-2024, 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" + +#include + +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); +} diff --git a/docs/build.adoc b/docs/build.adoc index 062bd51687..af2b21bc63 100644 --- a/docs/build.adoc +++ b/docs/build.adoc @@ -92,6 +92,19 @@ Treat all warnings as errors *Default:* `ON` +=== VKB_PROFILING + +Enable profiling using the xref:https://github.com/wolfpld/tracy[Tracy profiler]. + +We currently use Tracy v0.10.0 if you do not use the correct Tracy Profiler version as the Tracy Client version used in Sample you will get a protocol mismatch error. + +Windows users can download the profiler from the xref:https://github.com/wolfpld/tracy/releases/tag/v0.10[Tracy v0.10.0 release page] +Other platforms require the user to build the profiler from source see the xref:https://github.com/wolfpld/tracy/releases/tag/v0.10[Tracy.pdf documentation] for more information on how to build for your platform. + +Tracy is not currently enabled for Android builds. In the future, we may add support for this. + +*Default:* `OFF` + == Quality Assurance We use a small set of tools to provide a level of quality to the project. diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index 76b26c407e..374b940b57 100644 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt @@ -530,6 +530,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC glslang SPIRV vma + hwcpipe spirv-cross-glsl glslang-default-resource-limits spdlog diff --git a/framework/common/error.h b/framework/common/error.h index b1549bba33..036f8e8630 100644 --- a/framework/common/error.h +++ b/framework/common/error.h @@ -21,39 +21,12 @@ #include #include +#include "core/util/error.hpp" + #include "common/strings.h" #include "core/util/logging.hpp" #include "vk_common.h" -#if defined(__clang__) -// CLANG ENABLE/DISABLE WARNING DEFINITION -# define VKBP_DISABLE_WARNINGS() \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic ignored \"-Wall\"") \ - _Pragma("clang diagnostic ignored \"-Wextra\"") \ - _Pragma("clang diagnostic ignored \"-Wtautological-compare\"") - -# define VKBP_ENABLE_WARNINGS() \ - _Pragma("clang diagnostic pop") -#elif defined(__GNUC__) || defined(__GNUG__) -// GCC ENABLE/DISABLE WARNING DEFINITION -# define VKBP_DISABLE_WARNINGS() \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wall\"") \ - _Pragma("GCC diagnostic ignored \"-Wextra\"") \ - _Pragma("GCC diagnostic ignored \"-Wtautological-compare\"") - -# define VKBP_ENABLE_WARNINGS() \ - _Pragma("GCC diagnostic pop") -#elif defined(_MSC_VER) -// MSVC ENABLE/DISABLE WARNING DEFINITION -# define VKBP_DISABLE_WARNINGS() \ - __pragma(warning(push, 0)) - -# define VKBP_ENABLE_WARNINGS() \ - __pragma(warning(pop)) -#endif - namespace vkb { /** @@ -101,3 +74,16 @@ class VulkanException : public std::runtime_error abort(); \ } \ } while (0) + +template +inline void ERRORF(const std::string &format, Args &&...args) +{ + throw std::runtime_error(fmt::format(format, std::forward(args)...)); +} + +inline void ERRORF(const std::string &message) +{ + throw std::runtime_error(message); +} + +#define NOT_IMPLEMENTED() ERRORF("not implemented") \ No newline at end of file diff --git a/framework/gltf_loader.cpp b/framework/gltf_loader.cpp index c3fceb729f..3264ce1b38 100644 --- a/framework/gltf_loader.cpp +++ b/framework/gltf_loader.cpp @@ -27,6 +27,8 @@ #include "common/glm_common.h" #include +#include + #include "api_vulkan_sample.h" #include "common/utils.h" #include "common/vk_common.h" @@ -408,6 +410,8 @@ GLTFLoader::GLTFLoader(Device &device) : std::unique_ptr GLTFLoader::read_scene_from_file(const std::string &file_name, int scene_index) { + PROFILE_SCOPE("Load GLTF Scene"); + std::string err; std::string warn; @@ -450,6 +454,8 @@ std::unique_ptr GLTFLoader::read_scene_from_file(const std::string &f std::unique_ptr 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; @@ -492,6 +498,8 @@ std::unique_ptr GLTFLoader::read_model_from_file(const std::string sg::Scene GLTFLoader::load_scene(int scene_index) { + PROFILE_SCOPE("Process Scene"); + auto scene = sg::Scene(); scene.set_name("gltf_scene"); @@ -727,6 +735,8 @@ sg::Scene GLTFLoader::load_scene(int scene_index) for (auto &gltf_mesh : model.meshes) { + PROFILE_SCOPE("Processing Mesh"); + auto mesh = parse_mesh(gltf_mesh); for (size_t i_primitive = 0; i_primitive < gltf_mesh.primitives.size(); i_primitive++) @@ -1087,6 +1097,8 @@ sg::Scene GLTFLoader::load_scene(int scene_index) std::unique_ptr GLTFLoader::load_model(uint32_t index, bool storage_buffer) { + PROFILE_SCOPE("Process Model"); + auto submesh = std::make_unique(); std::vector transient_buffers; diff --git a/framework/scene_graph/components/image/astc.cpp b/framework/scene_graph/components/image/astc.cpp index 6bcb487f91..26ad11b7e0 100644 --- a/framework/scene_graph/components/image/astc.cpp +++ b/framework/scene_graph/components/image/astc.cpp @@ -20,6 +20,7 @@ #include #include "common/error.h" +#include "core/util/profiling.hpp" #include "common/glm_common.h" #if defined(_WIN32) || defined(_WIN64) @@ -102,6 +103,8 @@ void Astc::init() void Astc::decode(BlockDim blockdim, VkExtent3D extent, const uint8_t *compressed_data, uint32_t compressed_size) { + PROFILE_SCOPE("Decode ASTC Image"); + // Actual decoding astcenc_swizzle swizzle = {ASTCENC_SWZ_R, ASTCENC_SWZ_G, ASTCENC_SWZ_B, ASTCENC_SWZ_A}; // Configure the compressor run diff --git a/framework/stats/stats.cpp b/framework/stats/stats.cpp index 071a2b81b6..4af23cf47d 100644 --- a/framework/stats/stats.cpp +++ b/framework/stats/stats.cpp @@ -17,8 +17,12 @@ */ #include "stats/stats.h" -#include "core/device.h" +#include +#include +#include + +#include "core/device.h" #include "frame_time_stats_provider.h" #ifdef VK_USE_PLATFORM_ANDROID_KHR # include "hwcpipe_stats_provider.h" @@ -221,6 +225,8 @@ void Stats::update(float delta_time) break; } } + + profile_counters(); } void Stats::continuous_sampling_worker(std::future should_terminate) @@ -283,6 +289,143 @@ void Stats::push_sample(const StatsProvider::Counters &sample) } } +namespace +{ +// For now names are taken from the stats_provider.cpp file +const char *to_string(StatIndex index) +{ + switch (index) + { + case StatIndex::frame_times: + return "Frame Times (ms)"; + case StatIndex::cpu_cycles: + return "CPU Cycles (M/s)"; + case StatIndex::cpu_instructions: + return "CPU Instructions (M/s)"; + case StatIndex::cpu_cache_miss_ratio: + return "Cache Miss Ratio (%)"; + case StatIndex::cpu_branch_miss_ratio: + return "Branch Miss Ratio (%)"; + case StatIndex::cpu_l1_accesses: + return "CPU L1 Accesses (M/s)"; + case StatIndex::cpu_instr_retired: + return "CPU Instructions Retired (M/s)"; + case StatIndex::cpu_l2_accesses: + return "CPU L2 Accesses (M/s)"; + case StatIndex::cpu_l3_accesses: + return "CPU L3 Accesses (M/s)"; + case StatIndex::cpu_bus_reads: + return "CPU Bus Read Beats (M/s)"; + case StatIndex::cpu_bus_writes: + return "CPU Bus Write Beats (M/s)"; + case StatIndex::cpu_mem_reads: + return "CPU Memory Read Instructions (M/s)"; + case StatIndex::cpu_mem_writes: + return "CPU Memory Write Instructions (M/s)"; + case StatIndex::cpu_ase_spec: + return "CPU Speculatively Exec. SIMD Instructions (M/s)"; + case StatIndex::cpu_vfp_spec: + return "CPU Speculatively Exec. FP Instructions (M/s)"; + case StatIndex::cpu_crypto_spec: + return "CPU Speculatively Exec. Crypto Instructions (M/s)"; + case StatIndex::gpu_cycles: + return "GPU Cycles (M/s)"; + case StatIndex::gpu_vertex_cycles: + return "Vertex Cycles (M/s)"; + case StatIndex::gpu_load_store_cycles: + return "Load Store Cycles (k/s)"; + case StatIndex::gpu_tiles: + return "Tiles (k/s)"; + case StatIndex::gpu_killed_tiles: + return "Tiles killed by CRC match (k/s)"; + case StatIndex::gpu_fragment_jobs: + return "Fragment Jobs (s)"; + case StatIndex::gpu_fragment_cycles: + return "Fragment Cycles (M/s)"; + case StatIndex::gpu_tex_cycles: + return "Shader Texture Cycles (k/s)"; + case StatIndex::gpu_ext_reads: + return "External Reads (M/s)"; + case StatIndex::gpu_ext_writes: + return "External Writes (M/s)"; + case StatIndex::gpu_ext_read_stalls: + return "External Read Stalls (M/s)"; + case StatIndex::gpu_ext_write_stalls: + return "External Write Stalls (M/s)"; + case StatIndex::gpu_ext_read_bytes: + return "External Read Bytes (MiB/s)"; + case StatIndex::gpu_ext_write_bytes: + return "External Write Bytes (MiB/s)"; + default: + return nullptr; + } +} +} // namespace + +void Stats::profile_counters() const +{ + static std::chrono::high_resolution_clock::time_point last_time = std::chrono::high_resolution_clock::now(); + std::chrono::high_resolution_clock::time_point now = std::chrono::high_resolution_clock::now(); + + if (now - last_time < std::chrono::milliseconds(100)) + { + return; + } + + last_time = now; + + for (auto &c : counters) + { + StatIndex idx = c.first; + auto &graph_data = get_graph_data(idx); + + if (c.second.empty()) + { + continue; + } + + float average = 0.0f; + for (auto &v : c.second) + { + average += v; + } + average /= c.second.size(); + + if (auto *index_name = to_string(idx)) + { + Plot::plot(index_name, average * graph_data.scale_factor); + } + } + + static std::vector labels; + + auto &device = render_context.get_device(); + VmaAllocator allocator = device.get_memory_allocator(); + + VmaBudget heap_budgets[VK_MAX_MEMORY_HEAPS]; + vmaGetHeapBudgets(allocator, heap_budgets); + + // We know that we will only ever have one device in the system, so we can cache the labels + if (labels.size() == 0) + { + VkPhysicalDeviceMemoryProperties memory_properties; + vkGetPhysicalDeviceMemoryProperties(device.get_gpu().get_handle(), &memory_properties); + + labels.reserve(memory_properties.memoryHeapCount); + + for (size_t heap = 0; heap < memory_properties.memoryHeapCount; heap++) + { + VkMemoryPropertyFlags flags = memory_properties.memoryHeaps[heap].flags; + labels.push_back("Heap " + std::to_string(heap) + " " + vk::to_string(vk::MemoryPropertyFlags{flags})); + } + } + + for (size_t heap = 0; heap < labels.size(); heap++) + { + Plot::plot(labels[heap].c_str(), heap_budgets[heap].usage / (1024.0f * 1024.0f)); + } +} + void Stats::begin_sampling(CommandBuffer &cb) { // Inform the providers diff --git a/framework/stats/stats.h b/framework/stats/stats.h index b0813f90f7..5db9f337c2 100644 --- a/framework/stats/stats.h +++ b/framework/stats/stats.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2018-2022, Arm Limited and Contributors - * Copyright (c) 2020-2022, Broadcom Inc. +/* Copyright (c) 2018-2024, Arm Limited and Contributors + * Copyright (c) 2020-2024, Broadcom Inc. * * SPDX-License-Identifier: Apache-2.0 * @@ -191,6 +191,9 @@ class Stats /// Updates circular buffers for CPU and GPU counters void push_sample(const StatsProvider::Counters &sample); + + // Push counters to external profilers + void profile_counters() const; }; } // namespace vkb diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt index 0562aea6bc..1052c17525 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -47,15 +47,15 @@ set(VULKAN_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vulkan/include) target_sources(vulkan INTERFACE ${VULKAN_INCLUDE_DIR}/vulkan/vulkan.h) target_include_directories(vulkan SYSTEM INTERFACE ${VULKAN_INCLUDE_DIR}) -target_compile_definitions(vulkan INTERFACE VK_NO_PROTOTYPES) +target_compile_definitions(Vulkan-Headers INTERFACE VK_NO_PROTOTYPES) if(ANDROID) - target_compile_definitions(vulkan INTERFACE VK_USE_PLATFORM_ANDROID_KHR) + target_compile_definitions(Vulkan-Headers INTERFACE VK_USE_PLATFORM_ANDROID_KHR) elseif(WIN32) - target_compile_definitions(vulkan INTERFACE VK_USE_PLATFORM_WIN32_KHR) + target_compile_definitions(Vulkan-Headers INTERFACE VK_USE_PLATFORM_WIN32_KHR) elseif(APPLE) - target_compile_definitions(vulkan INTERFACE VK_USE_PLATFORM_METAL_EXT) + target_compile_definitions(Vulkan-Headers INTERFACE VK_USE_PLATFORM_METAL_EXT) elseif(UNIX) # Choose WSI based on VKB_WSI_SELECTION if (VKB_WSI_SELECTION STREQUAL XCB OR VKB_WSI_SELECTION STREQUAL XLIB OR VKB_WSI_SELECTION STREQUAL WAYLAND) @@ -64,22 +64,22 @@ elseif(UNIX) if (VKB_WSI_SELECTION STREQUAL XCB) pkg_check_modules(XCB xcb REQUIRED) if (XCB_FOUND) - target_compile_definitions(vulkan INTERFACE VK_USE_PLATFORM_XCB_KHR) + target_compile_definitions(Vulkan-Headers INTERFACE VK_USE_PLATFORM_XCB_KHR) endif() elseif (VKB_WSI_SELECTION STREQUAL XLIB) pkg_check_modules(X11 x11 REQUIRED) if (X11_FOUND) - target_compile_definitions(vulkan INTERFACE VK_USE_PLATFORM_XLIB_KHR) + target_compile_definitions(Vulkan-Headers INTERFACE VK_USE_PLATFORM_XLIB_KHR) endif() elseif (VKB_WSI_SELECTION STREQUAL WAYLAND) pkg_check_modules(WAYLAND wayland-client REQUIRED) if (WAYLAND_FOUND) - target_compile_definitions(vulkan INTERFACE VK_USE_PLATFORM_WAYLAND_KHR) + target_compile_definitions(Vulkan-Headers INTERFACE VK_USE_PLATFORM_WAYLAND_KHR) endif() elseif (VKB_WSI_SELECTION STREQUAL D2D) set(DIRECT_TO_DISPLAY TRUE) set(DIRECT_TO_DISPLAY TRUE PARENT_SCOPE) - target_compile_definitions(vulkan INTERFACE VK_USE_PLATFORM_DISPLAY_KHR) + target_compile_definitions(Vulkan-Headers INTERFACE VK_USE_PLATFORM_DISPLAY_KHR) else() message(FATAL_ERROR "Unknown WSI") endif() @@ -175,7 +175,7 @@ target_compile_definitions(ktx PUBLIC BASISU_NO_ITERATOR_DEBUG_LEVEL) target_include_directories(ktx SYSTEM PUBLIC ${KTX_INCLUDE_DIRS}) -target_link_libraries(ktx PUBLIC vulkan) +target_link_libraries(ktx PUBLIC Vulkan-Headers) set_target_properties(ktx PROPERTIES FOLDER "ThirdParty" POSITION_INDEPENDENT_CODE ON) @@ -188,7 +188,7 @@ set(VOLK_FILES add_library(volk STATIC ${VOLK_FILES}) set_target_properties(volk PROPERTIES POSITION_INDEPENDENT_CODE ON) -target_link_libraries(volk PUBLIC vulkan) +target_link_libraries(volk PUBLIC Vulkan-Headers) target_include_directories(volk SYSTEM PUBLIC ${VOLK_DIR}) if (VKB_WSI_SELECTION STREQUAL XCB) @@ -440,3 +440,9 @@ target_include_directories(opencl SYSTEM INTERFACE ${OPENCL_INCLUDE_DIR}) add_subdirectory(catch2) set_property(TARGET Catch2 PROPERTY FOLDER "ThirdParty") set_property(TARGET Catch2WithMain PROPERTY FOLDER "ThirdParty") + +# Tracy +set(TRACY_ENABLE ${VKB_ENABLE_TRACY}) +set(TRACY_TIMER_FALLBACK ON) +add_subdirectory(tracy) +set_property(TARGET TracyClient PROPERTY FOLDER "ThirdParty") \ No newline at end of file diff --git a/third_party/tracy b/third_party/tracy new file mode 160000 index 0000000000..37aff70dfa --- /dev/null +++ b/third_party/tracy @@ -0,0 +1 @@ +Subproject commit 37aff70dfa50cf6307b3fee6074d627dc2929143 From f16e9c0508542bfdc18e429b93693b32baa39547 Mon Sep 17 00:00:00 2001 From: Tom Atkinson Date: Mon, 11 Mar 2024 21:01:49 +0000 Subject: [PATCH 2/5] add VKB_PROFILING --- framework/CMakeLists.txt | 11 +++++++++-- framework/common/error.h | 13 ------------- framework/stats/stats.cpp | 6 +++++- third_party/CMakeLists.txt | 22 +++++++++++----------- 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index 374b940b57..d0dc886f26 100644 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt @@ -530,7 +530,6 @@ target_link_libraries(${PROJECT_NAME} PUBLIC glslang SPIRV vma - hwcpipe spirv-cross-glsl glslang-default-resource-limits spdlog @@ -559,4 +558,12 @@ endif() if(VKB_DO_CLANG_TIDY) set_target_properties(framework PROPERTIES CXX_CLANG_TIDY "${VKB_DO_CLANG_TIDY}") -endif() \ No newline at end of file +endif() + +if (VKB_PROFILING) + ## Enable profling + target_compile_definitions(${PROJECT_NAME} PUBLIC VKB_PROFILING=1) +else() + ## Disable profiling + target_compile_definitions(${PROJECT_NAME} PUBLIC VKB_PROFILING=0) +endif() diff --git a/framework/common/error.h b/framework/common/error.h index 036f8e8630..58d7a5e043 100644 --- a/framework/common/error.h +++ b/framework/common/error.h @@ -74,16 +74,3 @@ class VulkanException : public std::runtime_error abort(); \ } \ } while (0) - -template -inline void ERRORF(const std::string &format, Args &&...args) -{ - throw std::runtime_error(fmt::format(format, std::forward(args)...)); -} - -inline void ERRORF(const std::string &message) -{ - throw std::runtime_error(message); -} - -#define NOT_IMPLEMENTED() ERRORF("not implemented") \ No newline at end of file diff --git a/framework/stats/stats.cpp b/framework/stats/stats.cpp index 4af23cf47d..1bcd70e6e5 100644 --- a/framework/stats/stats.cpp +++ b/framework/stats/stats.cpp @@ -27,6 +27,8 @@ #ifdef VK_USE_PLATFORM_ANDROID_KHR # include "hwcpipe_stats_provider.h" #endif +#include "core/allocated.h" +#include "rendering/render_context.h" #include "vulkan_stats_provider.h" namespace vkb @@ -364,6 +366,7 @@ const char *to_string(StatIndex index) void Stats::profile_counters() const { +#if VKB_PROFILING static std::chrono::high_resolution_clock::time_point last_time = std::chrono::high_resolution_clock::now(); std::chrono::high_resolution_clock::time_point now = std::chrono::high_resolution_clock::now(); @@ -400,7 +403,7 @@ void Stats::profile_counters() const static std::vector labels; auto &device = render_context.get_device(); - VmaAllocator allocator = device.get_memory_allocator(); + VmaAllocator allocator = allocated::get_memory_allocator(); VmaBudget heap_budgets[VK_MAX_MEMORY_HEAPS]; vmaGetHeapBudgets(allocator, heap_budgets); @@ -424,6 +427,7 @@ void Stats::profile_counters() const { Plot::plot(labels[heap].c_str(), heap_budgets[heap].usage / (1024.0f * 1024.0f)); } +#endif } void Stats::begin_sampling(CommandBuffer &cb) diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt index 1052c17525..47b1d1e416 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -47,15 +47,15 @@ set(VULKAN_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vulkan/include) target_sources(vulkan INTERFACE ${VULKAN_INCLUDE_DIR}/vulkan/vulkan.h) target_include_directories(vulkan SYSTEM INTERFACE ${VULKAN_INCLUDE_DIR}) -target_compile_definitions(Vulkan-Headers INTERFACE VK_NO_PROTOTYPES) +target_compile_definitions(vulkan INTERFACE VK_NO_PROTOTYPES) if(ANDROID) - target_compile_definitions(Vulkan-Headers INTERFACE VK_USE_PLATFORM_ANDROID_KHR) + target_compile_definitions(vulkan INTERFACE VK_USE_PLATFORM_ANDROID_KHR) elseif(WIN32) - target_compile_definitions(Vulkan-Headers INTERFACE VK_USE_PLATFORM_WIN32_KHR) + target_compile_definitions(vulkan INTERFACE VK_USE_PLATFORM_WIN32_KHR) elseif(APPLE) - target_compile_definitions(Vulkan-Headers INTERFACE VK_USE_PLATFORM_METAL_EXT) + target_compile_definitions(vulkan INTERFACE VK_USE_PLATFORM_METAL_EXT) elseif(UNIX) # Choose WSI based on VKB_WSI_SELECTION if (VKB_WSI_SELECTION STREQUAL XCB OR VKB_WSI_SELECTION STREQUAL XLIB OR VKB_WSI_SELECTION STREQUAL WAYLAND) @@ -64,22 +64,22 @@ elseif(UNIX) if (VKB_WSI_SELECTION STREQUAL XCB) pkg_check_modules(XCB xcb REQUIRED) if (XCB_FOUND) - target_compile_definitions(Vulkan-Headers INTERFACE VK_USE_PLATFORM_XCB_KHR) + target_compile_definitions(vulkan INTERFACE VK_USE_PLATFORM_XCB_KHR) endif() elseif (VKB_WSI_SELECTION STREQUAL XLIB) pkg_check_modules(X11 x11 REQUIRED) if (X11_FOUND) - target_compile_definitions(Vulkan-Headers INTERFACE VK_USE_PLATFORM_XLIB_KHR) + target_compile_definitions(vulkan INTERFACE VK_USE_PLATFORM_XLIB_KHR) endif() elseif (VKB_WSI_SELECTION STREQUAL WAYLAND) pkg_check_modules(WAYLAND wayland-client REQUIRED) if (WAYLAND_FOUND) - target_compile_definitions(Vulkan-Headers INTERFACE VK_USE_PLATFORM_WAYLAND_KHR) + target_compile_definitions(vulkan INTERFACE VK_USE_PLATFORM_WAYLAND_KHR) endif() elseif (VKB_WSI_SELECTION STREQUAL D2D) set(DIRECT_TO_DISPLAY TRUE) set(DIRECT_TO_DISPLAY TRUE PARENT_SCOPE) - target_compile_definitions(Vulkan-Headers INTERFACE VK_USE_PLATFORM_DISPLAY_KHR) + target_compile_definitions(vulkan INTERFACE VK_USE_PLATFORM_DISPLAY_KHR) else() message(FATAL_ERROR "Unknown WSI") endif() @@ -175,7 +175,7 @@ target_compile_definitions(ktx PUBLIC BASISU_NO_ITERATOR_DEBUG_LEVEL) target_include_directories(ktx SYSTEM PUBLIC ${KTX_INCLUDE_DIRS}) -target_link_libraries(ktx PUBLIC Vulkan-Headers) +target_link_libraries(ktx PUBLIC vulkan) set_target_properties(ktx PROPERTIES FOLDER "ThirdParty" POSITION_INDEPENDENT_CODE ON) @@ -188,7 +188,7 @@ set(VOLK_FILES add_library(volk STATIC ${VOLK_FILES}) set_target_properties(volk PROPERTIES POSITION_INDEPENDENT_CODE ON) -target_link_libraries(volk PUBLIC Vulkan-Headers) +target_link_libraries(volk PUBLIC vulkan) target_include_directories(volk SYSTEM PUBLIC ${VOLK_DIR}) if (VKB_WSI_SELECTION STREQUAL XCB) @@ -445,4 +445,4 @@ set_property(TARGET Catch2WithMain PROPERTY FOLDER "ThirdParty") set(TRACY_ENABLE ${VKB_ENABLE_TRACY}) set(TRACY_TIMER_FALLBACK ON) add_subdirectory(tracy) -set_property(TARGET TracyClient PROPERTY FOLDER "ThirdParty") \ No newline at end of file +set_property(TARGET TracyClient PROPERTY FOLDER "ThirdParty") From 10123f26376661fc92024f36e7c0181da80f2aa5 Mon Sep 17 00:00:00 2001 From: Tom Atkinson Date: Mon, 11 Mar 2024 21:16:58 +0000 Subject: [PATCH 3/5] do not enable on android --- bldsys/cmake/global_options.cmake | 5 +++++ third_party/CMakeLists.txt | 1 + 2 files changed, 6 insertions(+) diff --git a/bldsys/cmake/global_options.cmake b/bldsys/cmake/global_options.cmake index 27ca7da06c..562f208a74 100644 --- a/bldsys/cmake/global_options.cmake +++ b/bldsys/cmake/global_options.cmake @@ -76,4 +76,9 @@ if (VKB_CLANG_TIDY) set(VKB_DO_CLANG_TIDY ${CLANG_TIDY} ${VKB_CLANG_TIDY_EXTRAS}) endif() +if (ANDROID AND VKB_PROFILING) + message(WARNING "Tracy Profiling is not supported on android yet") + set(VKB_PROFILING OFF) +endif() + set(TRACY_ENABLE ${VKB_PROFILING}) diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt index 47b1d1e416..f8c8d208c8 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -445,4 +445,5 @@ set_property(TARGET Catch2WithMain PROPERTY FOLDER "ThirdParty") set(TRACY_ENABLE ${VKB_ENABLE_TRACY}) set(TRACY_TIMER_FALLBACK ON) add_subdirectory(tracy) +add_compile_definitions(TRACY_NO_INVARIANT_CHECK=1) set_property(TARGET TracyClient PROPERTY FOLDER "ThirdParty") From 7afbca4de11994d6b746687fe81764dd55015c2b Mon Sep 17 00:00:00 2001 From: Tom Atkinson Date: Mon, 11 Mar 2024 21:43:24 +0000 Subject: [PATCH 4/5] remove implementation when VKB_PROFILING is off --- components/core/CMakeLists.txt | 7 ++++++- .../core/include/core/util/profiling.hpp | 18 ++++++++++++++---- components/core/src/profiling.cpp | 2 ++ third_party/CMakeLists.txt | 12 +++++++----- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/components/core/CMakeLists.txt b/components/core/CMakeLists.txt index a5e61e9d34..43f7ac91e5 100644 --- a/components/core/CMakeLists.txt +++ b/components/core/CMakeLists.txt @@ -31,9 +31,14 @@ vkb__register_component( src/profiling.cpp LINK_LIBS spdlog::spdlog - TracyClient ) +if (VKB_PROFILING) + target_link_libraries(vkb__core PUBLIC TracyClient) + target_compile_definitions(vkb__core PUBLIC TRACY_ENABLE) +endif() + + vkb__register_tests( COMPONENT core NAME utils diff --git a/components/core/include/core/util/profiling.hpp b/components/core/include/core/util/profiling.hpp index cd83a077b2..e9a45a7f64 100644 --- a/components/core/include/core/util/profiling.hpp +++ b/components/core/include/core/util/profiling.hpp @@ -24,10 +24,14 @@ #include "core/util/error.hpp" -VKBP_DISABLE_WARNINGS() +#ifdef TRACY_ENABLE #include -VKBP_ENABLE_WARNINGS() +#endif + + + +#ifdef TRACY_ENABLE // malloc and free are used by Tracy to provide memory profiling void *operator new(size_t count); void operator delete(void *ptr) noexcept; @@ -37,6 +41,10 @@ void operator delete(void *ptr) noexcept; // Trace a function #define PROFILE_FUNCTION() ZoneScoped +#else +#define PROFILE_SCOPE(name) +#define PROFILE_FUNCTION() +#endif // The type of plot to use enum class PlotType @@ -108,8 +116,10 @@ class Plot private: static void update_tracy_plot(const char *name, T value) { - TracyPlot(name, value); - TracyPlotConfig(name, TO_TRACY_PLOT_FORMAT(PT), true, true, 0); + #ifdef TRACY_ENABLE + TracyPlot(name, value); + TracyPlotConfig(name, TO_TRACY_PLOT_FORMAT(PT), true, true, 0); + #endif } static Plot *get_instance() diff --git a/components/core/src/profiling.cpp b/components/core/src/profiling.cpp index b2ad001a29..7baf12f44f 100644 --- a/components/core/src/profiling.cpp +++ b/components/core/src/profiling.cpp @@ -19,6 +19,7 @@ #include +#ifdef TRACY_ENABLE void *operator new(size_t count) { auto ptr = malloc(count); @@ -31,3 +32,4 @@ void operator delete(void *ptr) noexcept TracyFree(ptr); free(ptr); } +#endif diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt index f8c8d208c8..4e623fffe3 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -442,8 +442,10 @@ set_property(TARGET Catch2 PROPERTY FOLDER "ThirdParty") set_property(TARGET Catch2WithMain PROPERTY FOLDER "ThirdParty") # Tracy -set(TRACY_ENABLE ${VKB_ENABLE_TRACY}) -set(TRACY_TIMER_FALLBACK ON) -add_subdirectory(tracy) -add_compile_definitions(TRACY_NO_INVARIANT_CHECK=1) -set_property(TARGET TracyClient PROPERTY FOLDER "ThirdParty") +if (VKB_PROFILING) + set(TRACY_ENABLE ${VKB_PROFILING}) + set(TRACY_TIMER_FALLBACK ON) + add_subdirectory(tracy) + add_compile_definitions(TRACY_NO_INVARIANT_CHECK=1) + set_property(TARGET TracyClient PROPERTY FOLDER "ThirdParty") +endif() From 1e16cb9fa24c2e51a8f4ab63d51c1cfecdcaede9 Mon Sep 17 00:00:00 2001 From: Tom Atkinson Date: Mon, 11 Mar 2024 21:45:13 +0000 Subject: [PATCH 5/5] qa --- .../core/include/core/util/profiling.hpp | 21 ++++++++----------- framework/hpp_gui.h | 2 +- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/components/core/include/core/util/profiling.hpp b/components/core/include/core/util/profiling.hpp index e9a45a7f64..4262cb8117 100644 --- a/components/core/include/core/util/profiling.hpp +++ b/components/core/include/core/util/profiling.hpp @@ -25,25 +25,22 @@ #include "core/util/error.hpp" #ifdef TRACY_ENABLE -#include +# include #endif - - - #ifdef TRACY_ENABLE // 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) +# define PROFILE_SCOPE(name) ZoneScopedN(name) // Trace a function -#define PROFILE_FUNCTION() ZoneScoped +# define PROFILE_FUNCTION() ZoneScoped #else -#define PROFILE_SCOPE(name) -#define PROFILE_FUNCTION() +# define PROFILE_SCOPE(name) +# define PROFILE_FUNCTION() #endif // The type of plot to use @@ -116,10 +113,10 @@ class Plot private: static void update_tracy_plot(const char *name, T value) { - #ifdef TRACY_ENABLE - TracyPlot(name, value); - TracyPlotConfig(name, TO_TRACY_PLOT_FORMAT(PT), true, true, 0); - #endif +#ifdef TRACY_ENABLE + TracyPlot(name, value); + TracyPlotConfig(name, TO_TRACY_PLOT_FORMAT(PT), true, true, 0); +#endif } static Plot *get_instance() diff --git a/framework/hpp_gui.h b/framework/hpp_gui.h index d33c9bb20b..2f309467ea 100644 --- a/framework/hpp_gui.h +++ b/framework/hpp_gui.h @@ -62,7 +62,7 @@ struct HPPFont } std::vector data; - ImFont *handle = nullptr; + ImFont *handle = nullptr; std::string name; float size = 0.0f; };