From f7ada66c5c7a6b79413917e0d1db4ced33fde792 Mon Sep 17 00:00:00 2001 From: light7734 Date: Tue, 20 Jan 2026 10:43:26 +0330 Subject: [PATCH] refactor: split debug module into preliminary and tracer --- modules/CMakeLists.txt | 25 +----- modules/asset_baker/bakers.cppm | 3 +- modules/assets/shader.cppm | 33 +++---- modules/debug/assertions.cppm | 47 ---------- modules/ecs/entity.cppm | 3 +- modules/ecs/registry.cppm | 3 +- modules/ecs/sparse_set.cppm | 3 +- modules/input/system.cppm | 3 +- modules/math/vec4.cppm | 5 +- modules/memory/null_on_move.cppm | 7 +- modules/preliminary/assertions.cppm | 85 +++++++++++++++++++ modules/preliminary/build_constants.cppm | 85 +++++++++++++++++++ modules/preliminary/module.cppm | 3 + modules/renderer/factory.cppm | 29 +++---- modules/renderer/system.cppm | 5 +- modules/renderer/vk/api_wrapper.cppm | 26 +++--- modules/renderer/vk/debugger.cppm | 3 +- modules/renderer/vk/device.cppm | 7 +- modules/renderer/vk/gpu.cppm | 3 +- modules/renderer/vk/instance.cppm | 1 - modules/renderer/vk/renderer.cppm | 3 +- modules/renderer/vk/surface.cppm | 7 +- modules/sandbox/CMakeLists.txt | 2 +- modules/sandbox/sandbox.cpp | 2 +- modules/surface/system.cppm | 42 ++++----- .../instrumentor.cppm => tracer/tracer.cppm} | 56 ++++++------ 26 files changed, 281 insertions(+), 210 deletions(-) delete mode 100644 modules/debug/assertions.cppm create mode 100644 modules/preliminary/assertions.cppm create mode 100644 modules/preliminary/build_constants.cppm rename modules/{debug/instrumentor.cppm => tracer/tracer.cppm} (61%) diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index ae51b8f..171db86 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -1,6 +1,7 @@ -add_module(NAME preliminary INTERFACES module.cppm fundumental_types.cppm) - +add_module(NAME preliminary INTERFACES module.cppm fundumental_types.cppm assertions.cppm build_constants.cppm) add_module(NAME logger INTERFACES logger.cppm TESTS logger.test.cpp DEPENDENCIES preliminary) +add_module(NAME tracer INTERFACES tracer.cppm DEPENDENCIES preliminary logger) + add_module(NAME bitwise INTERFACES operations.cppm DEPENDENCIES preliminary) add_module(NAME env INTERFACES constants.cppm DEPENDENCIES preliminary) add_module(NAME memory INTERFACES null_on_move.cppm reference.cppm scope.cppm @@ -26,19 +27,6 @@ add_module( test.test.cpp ) -add_module( - NAME - lt_debug - ROOT_DIR - ${CMAKE_CURRENT_SOURCE_DIR}/debug - INTERFACES - instrumentor.cppm - assertions.cppm - DEPENDENCIES - preliminary - logger -) - add_module( NAME math @@ -52,7 +40,6 @@ add_module( components.cppm DEPENDENCIES preliminary - lt_debug ) add_module( @@ -64,7 +51,6 @@ add_module( DEPENDENCIES preliminary logger - lt_debug TESTS shader.test.cpp ) @@ -82,7 +68,6 @@ add_module( preliminary assets logger - lt_debug ) # add_executable(asset_baker entrypoint.cpp) target_link_libraries(asset_baker @@ -100,7 +85,6 @@ add_module( preliminary memory PRIVATE_DEPENDENCIES - lt_debug ) add_module( @@ -112,7 +96,6 @@ add_module( entity.cppm DEPENDENCIES logger - lt_debug memory TESTS registry.test.cpp @@ -140,7 +123,6 @@ if(WIN32) input_codes PRIVATE_DEPENDENCIES logger - lt_debug time TESTS system.test.cpp @@ -167,7 +149,6 @@ elseif(UNIX) PRIVATE_DEPENDENCIES X11 logger - lt_debug time TESTS system.test.cpp diff --git a/modules/asset_baker/bakers.cppm b/modules/asset_baker/bakers.cppm index 3e82c73..159e3c5 100644 --- a/modules/asset_baker/bakers.cppm +++ b/modules/asset_baker/bakers.cppm @@ -1,7 +1,6 @@ export module bakers; import preliminary; -import debug.assertions; import assets.metadata; import assets.shader; import logger; @@ -37,7 +36,7 @@ export void bake_shader( ); auto stream = std::ifstream(spv_path, std::ios::binary); - lt::debug::ensure( + ensure( stream.is_open(), "Failed to open compiled {} shader at: {}", type == vertex ? "vert" : "frag", diff --git a/modules/assets/shader.cppm b/modules/assets/shader.cppm index f769098..0421b36 100644 --- a/modules/assets/shader.cppm +++ b/modules/assets/shader.cppm @@ -3,7 +3,6 @@ export module assets.shader; import preliminary; import assets.metadata; import logger; -import debug.assertions; export namespace lt::assets { @@ -55,7 +54,7 @@ public: [[nodiscard]] auto get_blob_metadata(BlobTag tag) const -> const BlobMetadata & { - debug::ensure( + ensure( tag == BlobTag::code, "Invalid blob tag for shader asset: {}", std::to_underlying(tag) @@ -92,14 +91,14 @@ constexpr auto total_metadata_size = // ShaderAsset::ShaderAsset(const std::filesystem::path &path) : m_stream(path, std::ios::beg | std::ios::binary) { - debug::ensure(m_stream.is_open(), "Failed to open shader asset at: {}", path.string()); + ensure(m_stream.is_open(), "Failed to open shader asset at: {}", path.string()); const auto read = [this](auto &field) { m_stream.read(std::bit_cast(&field), sizeof(field)); }; m_stream.seekg(0, std::ifstream::end); const auto file_size = static_cast(m_stream.tellg()); - debug::ensure( + ensure( file_size > total_metadata_size, "Failed to open shader asset at: {}, file smaller than metadata: {} < {}", path.string(), @@ -118,7 +117,7 @@ ShaderAsset::ShaderAsset(const std::filesystem::path &path) read(m_code_blob_metadata.compressed_size); read(m_code_blob_metadata.uncompressed_size); - debug::ensure( + ensure( m_asset_metadata.type == asset_type_identifier, "Failed to open shader asset at: {}, incorrect asset type: {} != {}", path.string(), @@ -126,7 +125,7 @@ ShaderAsset::ShaderAsset(const std::filesystem::path &path) asset_type_identifier ); - debug::ensure( + ensure( m_asset_metadata.version == current_version, "Failed to open shader asset at: {}, version mismatch: {} != {}", path.string(), @@ -134,21 +133,21 @@ ShaderAsset::ShaderAsset(const std::filesystem::path &path) current_version ); - debug::ensure( + ensure( std::to_underlying(m_metadata.type) <= std::to_underlying(Type::compute), "Failed to open shader asset at: {}, invalid shader type: {}", path.string(), std::to_underlying(m_metadata.type) ); - debug::ensure( + ensure( m_code_blob_metadata.tag == std::to_underlying(BlobTag::code), "Failed to open shader asset at: {}, invalid blob tag: {}", path.string(), m_code_blob_metadata.tag ); - debug::ensure( + ensure( m_code_blob_metadata.offset + m_code_blob_metadata.compressed_size <= file_size, "Failed to open shader asset at: {}, file smaller than blob: {} > {} + {}", path.string(), @@ -178,7 +177,7 @@ ShaderAsset::ShaderAsset(const std::filesystem::path &path) .uncompressed_size = code_blob.size(), }; - debug::ensure(stream.is_open(), "Failed to pack shader asset to {}", destination.string()); + ensure(stream.is_open(), "Failed to pack shader asset to {}", destination.string()); const auto write = [&stream](auto &field) { stream.write(std::bit_cast(&field), sizeof(field)); }; @@ -195,13 +194,9 @@ ShaderAsset::ShaderAsset(const std::filesystem::path &path) void ShaderAsset::unpack_to(BlobTag tag, std::span destination) const { - debug::ensure( - tag == BlobTag::code, - "Invalid blob tag for shader asset: {}", - std::to_underlying(tag) - ); + ensure(tag == BlobTag::code, "Invalid blob tag for shader asset: {}", std::to_underlying(tag)); - debug::ensure( + ensure( destination.size() >= m_code_blob_metadata.uncompressed_size, "Failed to unpack shader blob {} to destination ({}) of size {} since it's smaller " "than the blobl's uncompressed size: {}", @@ -220,11 +215,7 @@ void ShaderAsset::unpack_to(BlobTag tag, std::span destination) const [[nodiscard]] auto ShaderAsset::unpack(BlobTag tag) const -> Blob { - debug::ensure( - tag == BlobTag::code, - "Invalid blob tag for shader asset: {}", - std::to_underlying(tag) - ); + ensure(tag == BlobTag::code, "Invalid blob tag for shader asset: {}", std::to_underlying(tag)); auto blob = Blob(m_code_blob_metadata.uncompressed_size); unpack_to(tag, blob); diff --git a/modules/debug/assertions.cppm b/modules/debug/assertions.cppm deleted file mode 100644 index 1666d10..0000000 --- a/modules/debug/assertions.cppm +++ /dev/null @@ -1,47 +0,0 @@ -export module debug.assertions; - -import std; - -namespace lt::debug { - -/////////////////////////////////////// -// ----------* INTERFACE *--------- // -///////////////////////////////////// -export template -struct ensure -{ - ensure( - const Expression_T &expression, - std::format_string fmt, - Args_T &&...args, - const std::source_location &location = std::source_location::current() - ); -}; - -export template -ensure(Expression_T, std::format_string, Args_T &&...) - -> ensure; - -/////////////////////////////////////// -// * IMPLEMENTATION -- TEMPLATES * // -///////////////////////////////////// -template -ensure::ensure( - const Expression_T &expression, - std::format_string fmt, - Args_T &&...args, - const std::source_location &location -) -{ - if (!static_cast(expression)) - { - throw std::runtime_error { std::format( - "exception: {}\nlocation: {}:{}", - std::format(fmt, std::forward(args)...), - location.file_name(), - location.line() - ) }; - } -} - -} // namespace lt::debug diff --git a/modules/ecs/entity.cppm b/modules/ecs/entity.cppm index 970d644..545695d 100644 --- a/modules/ecs/entity.cppm +++ b/modules/ecs/entity.cppm @@ -1,7 +1,6 @@ export module ecs.entity; import preliminary; -import debug.assertions; import memory.reference; import ecs.registry; @@ -15,7 +14,7 @@ public: : m_registry(std::move(registry)) , m_identifier(identifier) { - debug::ensure(m_registry, "Failed to create Entity ({}): null registry", m_identifier); + ensure(m_registry, "Failed to create Entity ({}): null registry", m_identifier); } template diff --git a/modules/ecs/registry.cppm b/modules/ecs/registry.cppm index 93707b1..28474de 100644 --- a/modules/ecs/registry.cppm +++ b/modules/ecs/registry.cppm @@ -1,7 +1,6 @@ export module ecs.registry; import preliminary; -import debug.assertions; import ecs.sparse_set; import memory.scope; @@ -243,7 +242,7 @@ private: auto *base_set = m_sparsed_sets[type_id].get(); auto *derived_set = dynamic_cast *>(base_set); - debug::ensure(derived_set, "Failed to downcast to derived set"); + ensure(derived_set, "Failed to downcast to derived set"); return *derived_set; } diff --git a/modules/ecs/sparse_set.cppm b/modules/ecs/sparse_set.cppm index e8abc25..b94cee8 100644 --- a/modules/ecs/sparse_set.cppm +++ b/modules/ecs/sparse_set.cppm @@ -1,7 +1,6 @@ export module ecs.sparse_set; import preliminary; -import debug.assertions; export namespace lt::ecs { @@ -39,7 +38,7 @@ public: explicit SparseSet(size_t initial_capacity = 1) { - debug::ensure( + ensure( initial_capacity <= max_capacity, "Failed to create SparseSet: capacity too large ({} > {})", initial_capacity, diff --git a/modules/input/system.cppm b/modules/input/system.cppm index 8e2cbda..8a176ba 100644 --- a/modules/input/system.cppm +++ b/modules/input/system.cppm @@ -2,7 +2,6 @@ export module input.system; export import :components; import logger; import app.system; -import debug.assertions; import ecs.registry; import memory.reference; import surface.system; @@ -69,7 +68,7 @@ struct overloads: Ts... System::System(memory::Ref registry): m_registry(std::move(registry)) { - debug::ensure(m_registry, "Failed to initialize input system: null registry"); + ensure(m_registry, "Failed to initialize input system: null registry"); } void System::tick(app::TickInfo tick) diff --git a/modules/math/vec4.cppm b/modules/math/vec4.cppm index 94a9ce9..ee59164 100644 --- a/modules/math/vec4.cppm +++ b/modules/math/vec4.cppm @@ -3,7 +3,6 @@ export module math.vec4; import preliminary; import math.vec2; import math.vec3; -import debug.assertions; namespace lt::math { @@ -47,14 +46,14 @@ struct vec4_impl [[nodiscard]] constexpr auto operator[](u8 idx) -> T & { // TODO(Light): Use contract - debug::ensure(idx <= num_elements, "vec4 out of bound: {}", idx); + ensure(idx <= num_elements, "vec4 out of bound: {}", idx); return ((T *)this)[idx]; } [[nodiscard]] constexpr auto operator[](u8 idx) const -> const T & { // TODO(Light): Use contract - debug::ensure(idx < num_elements, "vec4 out of bound: {}", idx); + ensure(idx < num_elements, "vec4 out of bound: {}", idx); return ((T *)this)[idx]; } diff --git a/modules/memory/null_on_move.cppm b/modules/memory/null_on_move.cppm index a57b33e..b1706f0 100644 --- a/modules/memory/null_on_move.cppm +++ b/modules/memory/null_on_move.cppm @@ -9,7 +9,7 @@ namespace lt::memory { /** Holds an `Underlying_T`, assigns it to `null_value` when this object is moved. * * @note For avoiding the need to explicitly implement the move constructor for objects that hold - * Vulkan handles. But may serve other purposes, hence why I kept the implementation generic. + * non-raii-handles (eg. Vulkan, Wayland). */ export template class NullOnMove @@ -81,11 +81,6 @@ public: return m_value; } - operator u64() const - { - return (u64)m_value; - } - [[nodiscard]] auto get() -> Underlying_T & { return m_value; diff --git a/modules/preliminary/assertions.cppm b/modules/preliminary/assertions.cppm new file mode 100644 index 0000000..64e8e99 --- /dev/null +++ b/modules/preliminary/assertions.cppm @@ -0,0 +1,85 @@ +export module preliminary.assertions; + +import preliminary.build_constants; +import std; + +/////////////////////////////////////// +// ----------* INTERFACE *--------- // +///////////////////////////////////// +/** To be used for ensuring a condition holds true, throws otherwise. */ +export template +struct ensure +{ + ensure( + const Expression_T &expression, + std::format_string fmt, + Args_T &&...args, + const std::source_location &location = std::source_location::current() + ); +}; + +/** To be used for costly checks that should be stripped in release builds. */ +export template +struct debug_check +{ + debug_check( + const Expression_T &expression, + std::format_string fmt, + Args_T &&...args, + const std::source_location &location = std::source_location::current() + ); +}; + +export template +ensure(Expression_T, std::format_string, Args_T &&...) + -> ensure; + +export template +debug_check(Expression_T, std::format_string, Args_T &&...) + -> debug_check; + +/////////////////////////////////////// +// * IMPLEMENTATION -- TEMPLATES * // +///////////////////////////////////// +template +ensure::ensure( + const Expression_T &expression, + std::format_string fmt, + Args_T &&...args, + const std::source_location &location +) +{ + if (!static_cast(expression)) + { + throw std::runtime_error { std::format( + "exception: {}\nlocation: {}:{}", + std::format(fmt, std::forward(args)...), + location.file_name(), + location.line() + ) }; + } +} + +template +debug_check::debug_check( + const Expression_T &expression, + std::format_string fmt, + Args_T &&...args, + const std::source_location &location +) +{ + if constexpr (build_constants::build_type != build_constants::BuildType::debug) + { + return; + } + + if (!static_cast(expression)) + { + throw std::runtime_error { std::format( + "exception: {}\nlocation: {}:{}", + std::format(fmt, std::forward(args)...), + location.file_name(), + location.line() + ) }; + } +} diff --git a/modules/preliminary/build_constants.cppm b/modules/preliminary/build_constants.cppm new file mode 100644 index 0000000..332ebde --- /dev/null +++ b/modules/preliminary/build_constants.cppm @@ -0,0 +1,85 @@ +export module preliminary.build_constants; + +import preliminary.fundumental_types; +import std; + +export namespace build_constants { + +enum class Platform : u8 +{ + /** The GNU/Linux platform. + * Tested on the following distros: arch-x86_64 + * @note: Named like so because `linux` is a built-in identifier. + * */ + gnu_linux, + + /** + * The Microsoft Windows(tm) platform. + * Tested on the following architectures: x86_64 + */ + windows, + + /** + * The apple's macOS platform. + * Currently not supported. + */ + mac, +}; + +/** The compiler that was used for compiling the project. */ +enum class Compiler : u8 +{ + clang, + gcc, + msvc, + apple_clang, +}; + +enum class BuildType +{ + debug, + release, + distribution +}; + +#if defined(LIGHT_PLATFORM_WINDOWS) + #define lt_win(x) +constexpr auto platform = Platform::windows; +constexpr auto platform_name = "windows"; +constexpr auto platform_identifier = platform_name; // TODO(Light) + + #undef LIGHT_PLATFORM_WINDOWS + +#elif defined(LIGHT_PLATFORM_LINUX) +constexpr auto platform = Platform::gnu_linux; +constexpr auto platform_name = "gnu_linux"; +constexpr auto platform_identifier = platform_name; // TODO(Light) + +#elif defined(LIGHT_PLATFORM_MAC) + #define lt_mac(x) x +constexpr auto platform = Platform::mac; +constexpr auto platform_name = "mac"; +constexpr auto platform_identifier = platform_name; // TODO(Light) + +#else + #error "Unsupported platform: Unknown" + +#endif + +/** @TODO(Light): Handle other compilers... */ +#ifdef __clang__ +constexpr auto compiler = Compiler::clang; +constexpr auto compiler_name = "clang"; + +/** @TODO(Light): insert the full identifier, including version information and such */ +constexpr auto compiler_identifier = "clang"; +#endif + +// @TODO(Light): inject build info through CMake using LIGHT_... constant macros +#if defined(_DEBUG) +constexpr auto build_type = BuildType::debug; +#else +constexpr auto build_type = BuildType::release; +#endif + +} // namespace build_constants diff --git a/modules/preliminary/module.cppm b/modules/preliminary/module.cppm index 6d6fe07..6694c07 100644 --- a/modules/preliminary/module.cppm +++ b/modules/preliminary/module.cppm @@ -1,4 +1,7 @@ export module preliminary; export import preliminary.fundumental_types; +export import preliminary.assertions; +export import preliminary.build_constants; + // std should always be available... export import std; diff --git a/modules/renderer/factory.cppm b/modules/renderer/factory.cppm index 9d7af89..b157ae3 100644 --- a/modules/renderer/factory.cppm +++ b/modules/renderer/factory.cppm @@ -11,7 +11,6 @@ export import renderer.vk.gpu; export import renderer.vk.debugger; export import renderer.vk.surface; export import memory.scope; -export import debug.assertions; export import ecs.entity; import preliminary; @@ -83,7 +82,7 @@ namespace lt::renderer { const lt::ecs::Entity &surface_entity ) -> memory::Scope { - debug::ensure(instance, "Failed to create renderer::ISurface: null instance"); + ensure(instance, "Failed to create renderer::ISurface: null instance"); switch (target_api) { @@ -112,8 +111,8 @@ namespace lt::renderer { [[nodiscard]] auto create_device(Api target_api, IGpu *gpu, ISurface *surface) -> memory::Scope { - debug::ensure(gpu, "Failed to create renderer::IDevice: null gpu"); - debug::ensure(surface, "Failed to create renderer::IDevice: null surface"); + ensure(gpu, "Failed to create renderer::IDevice: null gpu"); + ensure(surface, "Failed to create renderer::IDevice: null surface"); switch (target_api) { @@ -147,9 +146,9 @@ namespace lt::renderer { const IBuffer::CreateInfo &info ) -> memory::Scope { - debug::ensure(device, "Failed to create renderer::IBuffer: null device"); - debug::ensure(gpu, "Failed to create renderer::IBuffer: null gpu"); - debug::ensure(info.size > 0, "Failed to create renderer::IBuffer: null size"); + ensure(device, "Failed to create renderer::IBuffer: null device"); + ensure(gpu, "Failed to create renderer::IBuffer: null gpu"); + ensure(info.size > 0, "Failed to create renderer::IBuffer: null size"); switch (target_api) { @@ -170,7 +169,7 @@ namespace lt::renderer { const lt::assets::ShaderAsset &fragment_shader ) -> memory::Scope { - debug::ensure(device, "Failed to create renderer::IPass: null device"); + ensure(device, "Failed to create renderer::IPass: null device"); switch (target_api) { @@ -192,10 +191,10 @@ namespace lt::renderer { u32 max_frames_in_flight ) -> memory::Scope { - debug::ensure(gpu, "Failed to create renderer::IRenderer: null gpu"); - debug::ensure(device, "Failed to create renderer::IRenderer: null device"); - debug::ensure(swapchain, "Failed to create renderer::IRenderer: null swapchain"); - debug::ensure( + ensure(gpu, "Failed to create renderer::IRenderer: null gpu"); + ensure(device, "Failed to create renderer::IRenderer: null device"); + ensure(swapchain, "Failed to create renderer::IRenderer: null swapchain"); + ensure( std::clamp( max_frames_in_flight, IRenderer::frames_in_flight_lower_limit, @@ -224,17 +223,17 @@ namespace lt::renderer { [[nodiscard]] auto create_debugger(Api target_api, IInstance *instance, IDebugger::CreateInfo info) -> memory::Scope { - debug::ensure( + ensure( info.severities != IDebugger::MessageSeverity::none, "Failed to create renderer::IDebugger: severities == none" ); - debug::ensure( + ensure( info.types != IDebugger::MessageType::none, "Failed to create renderer::IDebugger: types == none" ); - debug::ensure(info.callback, "Failed to create vk::Messenger: null callback"); + ensure(info.callback, "Failed to create vk::Messenger: null callback"); switch (target_api) { diff --git a/modules/renderer/system.cppm b/modules/renderer/system.cppm index e8e5aaa..e710526 100644 --- a/modules/renderer/system.cppm +++ b/modules/renderer/system.cppm @@ -2,7 +2,6 @@ export module renderer.system; import preliminary; import logger; -import debug.assertions; import math.mat4; import renderer.factory; import app.system; @@ -126,8 +125,8 @@ System::System(CreateInfo info) , m_instance(get_instance(m_api)) , m_max_frames_in_flight(info.config.max_frames_in_flight) { - debug::ensure(m_registry, "Failed to initialize renderer::System: null registry"); - debug::ensure( + ensure(m_registry, "Failed to initialize renderer::System: null registry"); + ensure( std::clamp( info.config.max_frames_in_flight, frames_in_flight_lower_limit, diff --git a/modules/renderer/vk/api_wrapper.cppm b/modules/renderer/vk/api_wrapper.cppm index c2acc24..b0e392a 100644 --- a/modules/renderer/vk/api_wrapper.cppm +++ b/modules/renderer/vk/api_wrapper.cppm @@ -44,7 +44,6 @@ import preliminary; import memory.null_on_move; import math.vec3; import math.vec2; -import debug.assertions; import logger; template @@ -2930,24 +2929,21 @@ void load_library() { library = dlopen("libvulkan.so", runtime_loader_flags); } - lt::debug::ensure(library, "Failed to dlopen the libvulkan.so"); + ensure(library, "Failed to dlopen the libvulkan.so"); // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) api::get_instance_proc_address = reinterpret_cast( dlsym(library, "vkGetInstanceProcAddr") ); - lt::debug::ensure( - api::get_instance_proc_address, - "Failed to load vulkan function: vkGetInstanceProcAddr" - ); + ensure(api::get_instance_proc_address, "Failed to load vulkan function: vkGetInstanceProcAddr"); #elif defined(LIGHT_PLATFORM_WINDOWS) library = LoadLibraryA("vulkan-1.dll"); - lt::debug::ensure(library, "Failed to LoadLibraryA the vulkan-1.dll"); + ensure(library, "Failed to LoadLibraryA the vulkan-1.dll"); api::get_instance_proc_address = std::bit_cast( GetProcAddress(std::bit_cast(library), "vkGetInstanceProcAddr") ); - lt::debug::ensure( + ensure( api::get_instance_proc_address, "Failed to get vkGetInstanceProcAddr function pointer from vulkan-1.dll" ); @@ -2977,7 +2973,7 @@ void load_global_functions() { constexpr auto load_fn = [](T &pfn, const char *fn_name) { pfn = std::bit_cast(api::get_instance_proc_address(nullptr, fn_name)); - lt::debug::ensure(pfn, "Failed to load vulkan global function: {}", fn_name); + ensure(pfn, "Failed to load vulkan global function: {}", fn_name); }; load_fn(api::create_instance, "vkCreateInstance"); @@ -2989,7 +2985,7 @@ void Instance::load_functions() { const auto load_fn = [this](T &pfn, const char *fn_name) { pfn = std::bit_cast(api::get_instance_proc_address(m_instance, fn_name)); - lt::debug::ensure(pfn, "Failed to load vulkan instance function: {}", fn_name); + ensure(pfn, "Failed to load vulkan instance function: {}", fn_name); }; load_fn(api::destroy_instance, "vkDestroyInstance"); @@ -3039,7 +3035,7 @@ void Device::load_functions() { const auto load_fn = [this](T &pfn, const char *fn_name) { pfn = std::bit_cast(api::get_device_proc_address(m_device, fn_name)); - lt::debug::ensure(pfn, "Failed to load vulkan device function: {}", fn_name); + ensure(pfn, "Failed to load vulkan device function: {}", fn_name); }; load_fn(api::get_device_queue, "vkGetDeviceQueue"); @@ -3149,7 +3145,7 @@ Instance::Instance(CreateInfo info) values = std::bit_cast(&std::get<2>(setting.values)); } - debug::ensure(values, "Failed to get variant from setting.values"); + ensure(values, "Failed to get variant from setting.values"); layer_settings.emplace_back( VkLayerSettingEXT { @@ -3189,7 +3185,7 @@ Instance::Instance(CreateInfo info) }; vkc(api::create_instance(&vk_info, nullptr, &m_instance)); - debug::ensure(m_instance, "Failed to create vulkan instance"); + ensure(m_instance, "Failed to create vulkan instance"); } Surface::Surface(const Instance &instance, const CreateInfo &info) @@ -3235,7 +3231,7 @@ Surface::~Surface() { auto count = 0u; vkc(api::enumerate_physical_devices(instance.m_instance, &count, nullptr)); - debug::ensure(count != 0u, "Failed to find any gpus with Vulkan support"); + ensure(count != 0u, "Failed to find any gpus with Vulkan support"); auto vk_gpus = std::vector(count); vkc(api::enumerate_physical_devices(instance.m_instance, &count, vk_gpus.data())); @@ -3926,7 +3922,7 @@ void Device::wait_for_fences(std::span fences) const { auto count = uint32_t { 0u }; vkc(api::get_swapchain_images_khr(m_device, swapchain, &count, nullptr)); - debug::ensure(count != 0u, "Failed to get swapchain images"); + ensure(count != 0u, "Failed to get swapchain images"); auto images = std::vector(count); vkc(api::get_swapchain_images_khr(m_device, swapchain, &count, images.data())); diff --git a/modules/renderer/vk/debugger.cppm b/modules/renderer/vk/debugger.cppm index 620c091..530f885 100644 --- a/modules/renderer/vk/debugger.cppm +++ b/modules/renderer/vk/debugger.cppm @@ -5,7 +5,6 @@ import renderer.vk.instance; import renderer.frontend; import renderer.vk.api_wrapper; import memory.null_on_move; -import debug.assertions; import logger; export namespace lt::renderer::vkb { @@ -156,7 +155,7 @@ void Debugger::native_callback( { try { - debug::ensure(user_data, "Null vulkan_user_data received in messenger callback"); + ensure(user_data, "Null vulkan_user_data received in messenger callback"); auto *messenger = std::bit_cast(user_data); messenger->m_user_callback( diff --git a/modules/renderer/vk/device.cppm b/modules/renderer/vk/device.cppm index 76a3a52..ae05389 100644 --- a/modules/renderer/vk/device.cppm +++ b/modules/renderer/vk/device.cppm @@ -3,7 +3,6 @@ export module renderer.vk.device; import preliminary; import memory.null_on_move; import logger; -import debug.assertions; import renderer.vk.instance; import renderer.frontend; import renderer.vk.api_wrapper; @@ -71,7 +70,7 @@ Device::Device(IGpu *gpu, ISurface *surface) : m_gpu(static_cast(gpu)) , m_surface(static_cast(surface)) { - debug::ensure(m_surface->vk(), "Failed to initialize vk::Device: null vulkan surface"); + ensure(m_surface->vk(), "Failed to initialize vk::Device: null vulkan surface"); initialize_queue_indices(); initialize_logical_device(); @@ -146,12 +145,12 @@ void Device::initialize_queue_indices() ++idx; } - debug::ensure( + ensure( m_graphics_queue_family_index != vk::constants::queue_family_ignored, "Failed to find graphics queue family" ); - debug::ensure( + ensure( m_present_queue_family_index != vk::constants::queue_family_ignored, "Failed to find presentation queue family" ); diff --git a/modules/renderer/vk/gpu.cppm b/modules/renderer/vk/gpu.cppm index 079f07f..e2df542 100644 --- a/modules/renderer/vk/gpu.cppm +++ b/modules/renderer/vk/gpu.cppm @@ -3,7 +3,6 @@ export module renderer.vk.gpu; import preliminary; import renderer.vk.api_wrapper; import logger; -import debug.assertions; import renderer.frontend; import renderer.vk.instance; import memory.null_on_move; @@ -66,7 +65,7 @@ Gpu::Gpu(IInstance *instance) } // No suitable GPU is fonud... - debug::ensure(m_gpu, "Failed to find any suitable Vulkan physical device"); + ensure(m_gpu, "Failed to find any suitable Vulkan physical device"); m_memory_properties = m_gpu.get_memory_properties(); m_queue_family_properties = m_gpu.get_queue_family_properties(); diff --git a/modules/renderer/vk/instance.cppm b/modules/renderer/vk/instance.cppm index 09c8083..3f1efc9 100644 --- a/modules/renderer/vk/instance.cppm +++ b/modules/renderer/vk/instance.cppm @@ -1,7 +1,6 @@ export module renderer.vk.instance; import preliminary; -import debug.assertions; import renderer.frontend; import renderer.vk.api_wrapper; diff --git a/modules/renderer/vk/renderer.cppm b/modules/renderer/vk/renderer.cppm index 0ab629d..db31fd1 100644 --- a/modules/renderer/vk/renderer.cppm +++ b/modules/renderer/vk/renderer.cppm @@ -3,7 +3,6 @@ export module renderer.vk.renderer; import preliminary; import logger; import assets.shader; -import debug.assertions; import renderer.vk.api_wrapper; import memory.reference; import memory.null_on_move; @@ -171,7 +170,7 @@ Renderer::Renderer(IGpu *gpu, IDevice *device, ISwapchain *swapchain, u32 max_fr [[nodiscard]] auto Renderer::frame(u32 frame_idx, std::function submit_scene) -> Result { - debug::ensure( + ensure( frame_idx < m_max_frames_in_flight, "Failed to draw: frame_idx >= max_frames_in_flight ({} >= {})", frame_idx, diff --git a/modules/renderer/vk/surface.cppm b/modules/renderer/vk/surface.cppm index 92e6af4..bd3196c 100644 --- a/modules/renderer/vk/surface.cppm +++ b/modules/renderer/vk/surface.cppm @@ -1,7 +1,6 @@ export module renderer.vk.surface; import preliminary; -import debug.assertions; import ecs.entity; import ecs.registry; import memory.null_on_move; @@ -43,11 +42,11 @@ Surface::Surface(IInstance *instance, const ecs::Entity &surface_entity) #if defined(LIGHT_PLATFORM_LINUX) - debug::ensure( + ensure( component.get_native_data().display, "Failed to initialize vk::Surface: null Wayland display" ); - debug::ensure( + ensure( component.get_native_data().surface, "Failed to initialize vk::Surface: null Wayland surface" ); @@ -61,7 +60,7 @@ Surface::Surface(IInstance *instance, const ecs::Entity &surface_entity) ); #elif defined(LIGHT_PLATFORM_WINDOWS) - debug::ensure( + ensure( component.get_native_data().window, "Failed to initialize vk::Surface: null win32 window handle" ); diff --git a/modules/sandbox/CMakeLists.txt b/modules/sandbox/CMakeLists.txt index 1a2976c..e13542a 100644 --- a/modules/sandbox/CMakeLists.txt +++ b/modules/sandbox/CMakeLists.txt @@ -1,3 +1,3 @@ add_executable(sandbox sandbox.cpp) -target_link_libraries(sandbox PRIVATE logger bitwise env memory time test lt_debug math assets app ecs surface renderer input mirror) +target_link_libraries(sandbox PRIVATE preliminary logger bitwise env memory time test math assets app ecs surface renderer input mirror) diff --git a/modules/sandbox/sandbox.cpp b/modules/sandbox/sandbox.cpp index 5eaccd2..3e7ea65 100644 --- a/modules/sandbox/sandbox.cpp +++ b/modules/sandbox/sandbox.cpp @@ -18,7 +18,7 @@ constexpr auto height = 600u; constexpr auto vsync = true; constexpr auto visible = false; -auto main() -> int32_t +auto main() -> i32 try { auto registry = lt::memory::create_ref(); diff --git a/modules/surface/system.cppm b/modules/surface/system.cppm index a4daae8..3f1d7bf 100644 --- a/modules/surface/system.cppm +++ b/modules/surface/system.cppm @@ -12,7 +12,6 @@ export module surface.system; export import :components; import preliminary; -import debug.assertions; import app.system; import ecs.registry; import math.vec2; @@ -23,7 +22,6 @@ import memory.null_on_move; import logger; import preliminary; import surface.constants; -import debug.assertions; import memory.reference; import surface.requests; import surface.events; @@ -175,7 +173,7 @@ private: wl_compositor *m_wl_compositor {}; - xdg_wm_base *m_shell = {}; + xdg_wm_base *m_shell {}; wl_seat *m_wl_seat {}; @@ -440,11 +438,11 @@ System::System(memory::Ref registry) { // NOLINTNEXTLINE m_wl_display = wl_display_connect({}); - debug::ensure(m_wl_display, "Failed to connect to Wayland display"); + ensure(m_wl_display, "Failed to connect to Wayland display"); // NOLINTNEXTLINE m_wl_registry = wl_display_get_registry(m_wl_display); - debug::ensure(m_wl_registry, "Failed to get Wayland display's registry"); + ensure(m_wl_registry, "Failed to get Wayland display's registry"); // TODO(Light): "this" could be moved around... replace with a pointer to some heap allocation wl_registry_add_listener(m_wl_registry, &m_wl_registry_listener, this); @@ -454,8 +452,8 @@ System::System(memory::Ref registry) // For reasons beyond my fragile comprehension :( wl_display_roundtrip(m_wl_display); - debug::ensure(m_wl_compositor, "Failed to bind to the Wayland's compositor global"); - debug::ensure(m_shell, "Failed to bind to the Wayland's XDG-shell global"); + ensure(m_wl_compositor, "Failed to bind to the Wayland's compositor global"); + ensure(m_shell, "Failed to bind to the Wayland's XDG-shell global"); } System::~System() @@ -488,14 +486,14 @@ void System::create_surface_component(ecs::EntityId entity, SurfaceComponent::Cr auto *shell_toplevel = (xdg_toplevel *)nullptr; wayland_surface = wl_compositor_create_surface(m_wl_compositor); - debug::ensure(wayland_surface, "Failed to create Wayland surface"); + ensure(wayland_surface, "Failed to create Wayland surface"); shell_surface = xdg_wm_base_get_xdg_surface(m_shell, wayland_surface); - debug::ensure(shell_surface, "Failed to get XDG-shell surface"); + ensure(shell_surface, "Failed to get XDG-shell surface"); xdg_surface_add_listener(shell_surface, &shell_surface_listener, {}); shell_toplevel = xdg_surface_get_toplevel(shell_surface); - debug::ensure(shell_toplevel, "Failed to get XDG-shell toplevel"); + ensure(shell_toplevel, "Failed to get XDG-shell toplevel"); xdg_toplevel_add_listener(shell_toplevel, &toplevel_listener, {}); xdg_toplevel_set_title(shell_toplevel, "Wayland Vulkan Example"); @@ -649,9 +647,9 @@ auto CALLBACK window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -> System::System(memory::Ref registry): m_registry(std::move(registry)) { - debug::ensure(m_registry, "Failed to initialize surface system: null registry"); + ensure(m_registry, "Failed to initialize surface system: null registry"); - debug::ensure( + ensure( m_registry->view().get_size() == 0, "Failed to initialize surface system: registry has surface component(s)" ); @@ -738,7 +736,7 @@ try GetModuleHandle(nullptr), nullptr ); - debug::ensure(surface.m_native_data.window, "Failed to create Windows surface component"); + ensure(surface.m_native_data.window, "Failed to create Windows surface component"); ShowWindow(surface.m_native_data.window, SW_NORMAL); // SetWindowLongPtrA(surface.m_native_data.window, 0, this); @@ -748,10 +746,10 @@ try // TODO(Light): refactor "environment" into standalone module // NOLINTNEXTLINE(concurrency-mt-unsafe) // auto *display_env = std::getenv("DISPLAY"); - // debug::ensure(display_env != nullptr, "DISPLAY env var not found!"); + // ensure(display_env != nullptr, "DISPLAY env var not found!"); // // auto *display = XOpenDisplay(display_env); - // debug::ensure(display, "Failed to open XDisplay with DISPLAY: {}", display_env); + // ensure(display, "Failed to open XDisplay with DISPLAY: {}", display_env); // // auto root_window = XDefaultRootWindow(display); // @@ -1151,29 +1149,25 @@ void ensure_component_sanity(const SurfaceComponent &component) { auto [width, height] = component.get_resolution(); - debug::ensure(width != 0u, "Received bad values for surface component: width({}) == 0", width); + ensure(width != 0u, "Received bad values for surface component: width({}) == 0", width); - debug::ensure( - height != 0u, - "Received bad values for surface component: height({}) == 0", - height - ); + ensure(height != 0u, "Received bad values for surface component: height({}) == 0", height); - debug::ensure( + ensure( width < SurfaceComponent::max_dimension, "Received bad values for surface component: width({}) > max_dimension({})", width, SurfaceComponent::max_dimension ); - debug::ensure( + ensure( height < SurfaceComponent::max_dimension, "Received bad values for surface component: height({}) > max_dimension({})", height, SurfaceComponent::max_dimension ); - debug::ensure( + ensure( component.get_title().size() < SurfaceComponent::max_title_length, "Received bad values for surface component: title.size({}) > max_title_length({})", component.get_title().size(), diff --git a/modules/debug/instrumentor.cppm b/modules/tracer/tracer.cppm similarity index 61% rename from modules/debug/instrumentor.cppm rename to modules/tracer/tracer.cppm index 72425d6..4e80c88 100644 --- a/modules/debug/instrumentor.cppm +++ b/modules/tracer/tracer.cppm @@ -1,23 +1,25 @@ +// @todo(Light): Implement... + export module debug.instrumentor; import preliminary; import logger; -namespace lt::debug { +namespace lt::tracer { -struct ScopeProfileResult +struct ScopeTraceResult { std::string name; u64 start, duration; u32 threadID; }; -class Instrumentor +class Tracer { public: - static auto instance() -> Instrumentor & + static auto instance() -> Tracer & { - static auto instance = Instrumentor {}; + static auto instance = Tracer {}; return instance; } @@ -30,7 +32,7 @@ public: instance().end_session_impl(); } - static void submit_scope_profile(const ScopeProfileResult &profileResult) + static void submit_scope_profile(const ScopeTraceResult &profileResult) { instance().submit_scope_profile_impl(profileResult); } @@ -40,46 +42,46 @@ private: unsigned int m_current_session_count { 0u }; - Instrumentor() = default; + Tracer() = default; void begin_session_impl(const std::string &outputPath); void end_session_impl(); - void submit_scope_profile_impl(const ScopeProfileResult &profileResult); + void submit_scope_profile_impl(const ScopeTraceResult &profileResult); }; -class InstrumentorTimer +class TracerTimer { public: - InstrumentorTimer(const std::string &scopeName); + TracerTimer(const std::string &scopeName); - ~InstrumentorTimer(); + ~TracerTimer(); private: - ScopeProfileResult m_result; + ScopeTraceResult m_result; std::chrono::time_point m_start; }; -} // namespace lt::debug +} // namespace lt::tracer /* scope */ -#define lt_profile_scope(name) lt_profile_scope_no_redifinition(name, __LINE__) -#define lt_profile_scope_no_redifinition(name, line) lt_profile_scope_no_redifinition2(name, line) -#define lt_profile_scope_no_redifinition2(name, line) InstrumentorTimer timer##line(name) +#define lt_trace_scope(name) lt_profile_scope_no_redifinition(name, __LINE__) +#define lt_trace_scope_no_redifinition(name, line) lt_profile_scope_no_redifinition2(name, line) +#define lt_trace_scope_no_redifinition2(name, line) InstrumentorTimer timer##line(name) /* function */ -#define LT_PROFILE_FUNCTION lt_profile_scope(__FUNCSIG__) +#define lt_trace_function lt_profile_scope(__FUNCSIG__) /* session */ -#define lt_profile_begin_session(outputPath) ::lt::Instrumentor::begin_session(outputPath) -#define lt_profile_end_session() ::lt::Instrumentor::end_session() +#define lt_trace_begin_session(outputPath) ::lt::Instrumentor::begin_session(outputPath) +#define lt_trace_end_session() ::lt::Instrumentor::end_session() module :private; -namespace lt::debug { +namespace lt::tracer { -void Instrumentor::begin_session_impl(const std::string &outputPath) +void Tracer::begin_session_impl(const std::string &outputPath) { std::filesystem::create_directory(outputPath.substr(0, outputPath.find_last_of('/') + 1)); @@ -87,7 +89,7 @@ void Instrumentor::begin_session_impl(const std::string &outputPath) m_output_file_stream << "{\"traceEvents\":["; } -void Instrumentor::end_session_impl() +void Tracer::end_session_impl() { if (m_current_session_count == 0u) { @@ -101,7 +103,7 @@ void Instrumentor::end_session_impl() m_output_file_stream.close(); } -void Instrumentor::submit_scope_profile_impl(const ScopeProfileResult &profileResult) +void Tracer::submit_scope_profile_impl(const ScopeTraceResult &profileResult) { if (m_current_session_count++ == 0u) { @@ -122,13 +124,13 @@ void Instrumentor::submit_scope_profile_impl(const ScopeProfileResult &profileRe m_output_file_stream << "}"; } -InstrumentorTimer::InstrumentorTimer(const std::string &scopeName) +TracerTimer::TracerTimer(const std::string &scopeName) : m_result({ .name = scopeName, .start = 0, .duration = 0, .threadID = 0 }) , m_start(std::chrono::steady_clock::now()) { } -InstrumentorTimer::~InstrumentorTimer() +TracerTimer::~TracerTimer() { auto end = std::chrono::steady_clock::now(); @@ -141,6 +143,6 @@ InstrumentorTimer::~InstrumentorTimer() .count() - m_result.start; - Instrumentor::submit_scope_profile(m_result); + Tracer::submit_scope_profile(m_result); } -} // namespace lt::debug +} // namespace lt::tracer