wip: fix: renderer
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone Build was killed

This commit is contained in:
light7734 2025-12-08 16:41:41 +03:30
parent 9379031ab4
commit 2fd6a199aa
Signed by: light7734
GPG key ID: 8C30176798F1A6BA
17 changed files with 431 additions and 431 deletions

View file

@ -1,12 +1,8 @@
add_module(
NAME logger INTERFACES logger.cppm TESTS logger.test.cpp
)
add_module(NAME logger INTERFACES logger.cppm TESTS logger.test.cpp)
add_module(NAME bitwise INTERFACES operations.cppm)
add_module(NAME env INTERFACES constants.cppm)
add_module(
NAME memory INTERFACES null_on_move.cppm reference.cppm scope.cppm
)
add_module(NAME time INTERFACES timer.cppm)
add_module(NAME memory INTERFACES null_on_move.cppm reference.cppm scope.cppm)
add_module(NAME time INTERFACES timer.cppm TESTS timer.test.cpp)
add_module(
NAME
@ -19,6 +15,8 @@ add_module(
entrypoint.cpp
DEPENDENCIES
logger
TESTS
test.test.cpp
)
add_module(
@ -55,19 +53,25 @@ add_module(
DEPENDENCIES
logger
lt_debug
TESTS
shader.test.cpp
)
add_module(
NAME
libasset_baker
asset_baker
ROOT_DIR
${CMAKE_CURRENT_SOURCE_DIR}/asset_baker
INTERFACES
bakers.cppm
ENTRYPOINT
entrypoint.cpp
DEPENDENCIES
assets
logger
lt_debug
TESTS
bakers.test.cpp
)
# add_executable(asset_baker entrypoint.cpp) target_link_libraries(asset_baker
@ -98,8 +102,13 @@ add_module(
logger
lt_debug
memory
TESTS
registry.test.cpp
sparse_set.test.cpp
)
add_module(NAME input_codes INTERFACES input_codes.cppm)
if(WIN32)
add_module(
NAME
@ -117,6 +126,7 @@ if(WIN32)
app
math
memory
input_codes
PRIVATE_DEPENDENCIES
logger
lt_debug
@ -140,11 +150,14 @@ elseif(UNIX)
app
math
memory
input_codes
PRIVATE_DEPENDENCIES
X11
logger
lt_debug
time
TESTS
system.test.cpp
)
else()
@ -157,13 +170,15 @@ add_module(
input
INTERFACES
system.cppm
codes.cppm
components.cppm
events.cppm
DEPENDENCIES
input_codes
surface
math
logger
TESTS
system.test.cpp
)
find_package(Vulkan REQUIRED)
@ -199,6 +214,14 @@ add_module(
Vulkan::Vulkan
PRIVATE_DEPENDENCIES
surface
TESTS
_tests/buffer.cpp
_tests/debugger.cpp
_tests/device.cpp
_tests/pass.cpp
TEST_INTERFACES
_tests/utils.cppm
# _tests/renderer.cpp _tests/surface.cpp _tests/system.cpp
)
add_module(
@ -216,16 +239,14 @@ add_module(
surface
renderer
camera
# TESTS
# system.test.cpp
# TESTS system.test.cpp
)
add_executable(exectest ${CMAKE_CURRENT_SOURCE_DIR}/mirror/entrypoint.cpp
)
add_executable(exectest ${CMAKE_CURRENT_SOURCE_DIR}/mirror/entrypoint.cpp)
target_link_libraries(exectest PRIVATE
mirror
target_link_libraries(
exectest
PRIVATE mirror
app
time
input

View file

View file

@ -156,7 +156,7 @@ void System::on_surface_lost_focus()
void System::on_key_press(const lt::surface::KeyPressedEvent &event)
{
if (event.get_key() > m_keys.size())
if (std::to_underlying(event.get_key()) > m_keys.size())
{
log::debug("Key code larger than key container size, implement platform-dependant "
"key-code-mapping!");
@ -164,12 +164,12 @@ void System::on_key_press(const lt::surface::KeyPressedEvent &event)
return;
}
m_keys[event.get_key()] = true;
m_keys[std::to_underlying(event.get_key())] = true;
}
void System::on_key_release(const lt::surface::KeyReleasedEvent &event)
{
if (event.get_key() > m_keys.size())
if (std::to_underlying(event.get_key()) > m_keys.size())
{
log::debug("Key code larger than key container size, implement platform-dependant "
"key-code-mapping!");
@ -177,7 +177,7 @@ void System::on_key_release(const lt::surface::KeyReleasedEvent &event)
return;
}
m_keys[event.get_key()] = false;
m_keys[std::to_underlying(event.get_key())] = false;
}
void System::on_pointer_move(const lt::surface::MouseMovedEvent &event)
@ -187,12 +187,12 @@ void System::on_pointer_move(const lt::surface::MouseMovedEvent &event)
void System::on_button_press(const lt::surface::ButtonPressedEvent &event)
{
m_buttons[event.get_button()] = true;
m_buttons[std::to_underlying(event.get_button())] = true;
}
void System::on_button_release(const lt::surface::ButtonReleasedEvent &event)
{
m_buttons[event.get_button()] = false;
m_buttons[std::to_underlying(event.get_button())] = false;
}
} // namespace lt::input

View file

@ -1,11 +1,17 @@
#include <ecs/entity.hpp>
#include <input/components.hpp>
#include <input/system.hpp>
#include <memory/reference.hpp>
#include <memory/scope.hpp>
#include <ranges>
#include <surface/system.hpp>
#include <test/test.hpp>
import std;
import input.system;
import input.codes;
import std;
import test.test;
import test.expects;
import surface.events;
import memory.scope;
import memory.reference;
import app.system;
import ecs.entity;
import ecs.registry;
import surface.system;
// NOLINTBEGIN
using namespace lt;
@ -17,6 +23,7 @@ using test::expect_eq;
using test::expect_false;
using test::expect_ne;
using test::expect_not_nullptr;
using test::operator""_suite;
using test::expect_throw;
using test::Suite;
// NOLINTEND
@ -155,7 +162,7 @@ Suite tick = "tick"_suite = [] {
auto action_key = input.add_action(
{
.name { "test" },
.trigger = { .mapped_keycode = 69 },
.trigger = { .mapped_keycode = Key::A },
}
);
@ -163,7 +170,7 @@ Suite tick = "tick"_suite = [] {
system.tick(tick_info());
expect_eq(input.get_action(action_key).state, input::InputAction::State::inactive);
surface.push_event(surface::KeyPressedEvent(69));
surface.push_event(surface::KeyPressedEvent(Key::A));
system.tick(tick_info());
expect_eq(input.get_action(action_key).state, input::InputAction::State::triggered);
@ -175,7 +182,7 @@ Suite tick = "tick"_suite = [] {
system.tick(tick_info());
expect_eq(input.get_action(action_key).state, input::InputAction::State::active);
surface.push_event(surface::KeyReleasedEvent(69));
surface.push_event(surface::KeyReleasedEvent(Key::A));
system.tick(tick_info());
expect_eq(input.get_action(action_key).state, input::InputAction::State::inactive);
};
@ -195,7 +202,7 @@ Suite tick = "tick"_suite = [] {
auto action_key = input.add_action(
{
.name { "test" },
.trigger = { .mapped_keycode = 69 },
.trigger = { .mapped_keycode = Key::A },
}
);
};

View file

@ -1,4 +1,3 @@
import app;
import app.system;
import std;

View file

@ -1,31 +1,23 @@
#include <renderer/backend/vk/context/surface.hpp>
#include <renderer/backend/vk/debug/messenger.hpp>
#include <surface/components.hpp>
#include <surface/system.hpp>
#include <test/expects.hpp>
#include <test/test.hpp>
using namespace lt;
using renderer::vk::Messenger;
using renderer::vk::Surface;
using enum Messenger::Severity;
using enum Messenger::Type;
import renderer.frontend;
import renderer.test_utils;
void noop_callback(
Messenger::Severity message_severity,
Messenger::Type message_type,
Messenger::CallbackData_T vulkan_data,
void *user_data
lt::renderer::IDebugger::MessageSeverity message_severity,
lt::renderer::IDebugger::MessageType message_type,
const lt::renderer::IDebugger::MessageData &data,
std::any &user_data
)
{
}
Suite raii = "messenger_raii"_suite = [] {
Suite raii = "debugger_raii"_suite = [] {
Case { "happy path won't throw" } = [] {
Messenger(
Messenger::CreateInfo {
.severity = all_severity,
.type = all_type,
std::ignore = lt::renderer::create_debugger(
lt::renderer::Api::vulkan,
lt::renderer::get_instance(lt::renderer::Api::vulkan),
lt::renderer::IDebugger::CreateInfo {
.severities = lt::renderer::IDebugger::MessageSeverity::all,
.types = lt::renderer::IDebugger::MessageType::all,
.callback = &noop_callback,
}
);
@ -33,116 +25,39 @@ Suite raii = "messenger_raii"_suite = [] {
Case { "unhappy path throws" } = [] {
expect_throw([] {
Messenger(
Messenger::CreateInfo {
.severity = all_severity,
.type = all_type,
std::ignore = lt::renderer::create_debugger(
lt::renderer::Api::vulkan,
lt::renderer::get_instance(lt::renderer::Api::vulkan),
lt::renderer::IDebugger::CreateInfo {
.severities = lt::renderer::IDebugger::MessageSeverity::all,
.types = lt::renderer::IDebugger::MessageType::all,
.callback = {},
}
);
});
expect_throw([] {
Messenger(
Messenger::CreateInfo {
.severity = {},
.type = all_type,
std::ignore = lt::renderer::create_debugger(
lt::renderer::Api::vulkan,
lt::renderer::get_instance(lt::renderer::Api::vulkan),
lt::renderer::IDebugger::CreateInfo {
.severities = {},
.types = lt::renderer::IDebugger::MessageType::all,
.callback = &noop_callback,
}
);
});
expect_throw([] {
Messenger(
Messenger::CreateInfo {
.severity = all_severity,
.type = {},
std::ignore = lt::renderer::create_debugger(
lt::renderer::Api::vulkan,
lt::renderer::get_instance(lt::renderer::Api::vulkan),
lt::renderer::IDebugger::CreateInfo {
.severities = lt::renderer::IDebugger::MessageSeverity::all,
.types = {},
.callback = &noop_callback,
}
);
});
};
};
// NOLINTNEXTLINE(cppcoreguidelines-interfaces-global-init)
Suite callback = "messenger_callback"_suite = [] {
Case { "callback gets called with correct arguments" } = [] {
auto total_messages = 0u;
auto first_message_is_severity = false;
auto second_message_is_type = false;
auto third_message_is_user_callback = false;
auto all_messages_are_error = true;
auto all_messages_are_validation = true;
auto user_data_is_always_69 = true;
auto callback = [&](Messenger::Severity message_severity,
Messenger::Type message_type,
Messenger::CallbackData_T vulkan_data,
void *user_data) {
++total_messages;
auto message = std::string_view { vulkan_data->pMessage };
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
user_data_is_always_69 = user_data_is_always_69 && *(size_t *)user_data == 69u;
all_messages_are_validation = all_messages_are_validation && message_type == validation;
all_messages_are_error = all_messages_are_error && message_severity == error;
if (total_messages == 1)
{
first_message_is_severity = message.starts_with(
"vkCreateDebugUtilsMessengerEXT(): pCreateInfo->messageSeverity is zero."
);
return;
}
if (total_messages == 2)
{
second_message_is_type = message.starts_with(
"vkCreateDebugUtilsMessengerEXT(): pCreateInfo->messageType is zero."
);
return;
}
if (total_messages == 3)
{
third_message_is_user_callback = message.starts_with(
"vkCreateDebugUtilsMessengerEXT(): pCreateInfo->pfnUserCallback is NULL."
);
return;
}
};
auto user_data = size_t { 69 };
auto messenger = Messenger(
Messenger::CreateInfo {
.severity = all_severity,
.type = all_type,
.callback = callback,
.user_data = &user_data,
}
);
{
auto *messenger = VkDebugUtilsMessengerEXT {};
auto info = VkDebugUtilsMessengerCreateInfoEXT {
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
};
renderer::vk::vk_create_debug_messenger(
renderer::vk::Instance::get(),
&info,
nullptr,
&messenger
);
}
expect_eq(total_messages, 3u);
expect_true(first_message_is_severity);
expect_true(second_message_is_type);
expect_true(third_message_is_user_callback);
expect_true(all_messages_are_error);
expect_true(all_messages_are_validation);
expect_true(user_data_is_always_69);
};
};

View file

@ -1,35 +1,25 @@
#include <memory/reference.hpp>
#include <ranges>
#include <renderer/frontend/context/device.hpp>
#include <renderer/frontend/context/surface.hpp>
#include <renderer/test/utils.hpp>
#include <surface/components.hpp>
#include <surface/system.hpp>
#include <test/test.hpp>
import renderer.frontend;
import renderer.test_utils;
Suite raii = "device_raii"_suite = [] {
Case { "happy path won't throw" } = [] {
auto fixture = Fixture_SurfaceGpu {};
std::ignore = lt::renderer::IDevice::create(
constants::api,
fixture.gpu(),
fixture.surface()
);
std::ignore = lt::renderer::create_device(constants::api, fixture.gpu(), fixture.surface());
};
Case { "unhappy path throws" } = [] {
auto fixture = Fixture_SurfaceGpu {};
expect_throw([&] {
ignore = lt::renderer::IDevice::create(constants::api, nullptr, fixture.surface());
ignore = lt::renderer::create_device(constants::api, nullptr, fixture.surface());
});
expect_throw([&] {
ignore = lt::renderer::IDevice::create(constants::api, fixture.gpu(), nullptr);
ignore = lt::renderer::create_device(constants::api, fixture.gpu(), nullptr);
});
expect_throw([&] {
ignore = lt::renderer::IDevice::create(
ignore = lt::renderer::create_device(
lt::renderer::Api::none,
fixture.gpu(),
fixture.surface()
@ -37,7 +27,7 @@ Suite raii = "device_raii"_suite = [] {
});
expect_throw([&] {
ignore = lt::renderer::IDevice::create(
ignore = lt::renderer::create_device(
lt::renderer::Api::direct_x,
fixture.gpu(),
fixture.surface()
@ -45,7 +35,7 @@ Suite raii = "device_raii"_suite = [] {
});
expect_throw([&] {
ignore = lt::renderer::IDevice::create(
ignore = lt::renderer::create_device(
lt::renderer::Api::metal,
fixture.gpu(),
fixture.surface()

View file

@ -1,91 +0,0 @@
#include <renderer/backend/vk/context/instance.hpp>
#include <renderer/backend/vk/vulkan.hpp>
#include <test/test.hpp>
using namespace lt;
using renderer::vk::Instance;
using test::Case;
using test::expect_not_nullptr;
using test::Suite;
// NOLINTNEXTLINE
Suite raii = "raii"_suite = [] {
Case { "post singleton insantiation state is correct" } = [] {
expect_not_nullptr(Instance::get());
using namespace renderer::vk;
expect_not_nullptr(vk_get_physical_device_properties);
expect_not_nullptr(vk_get_physical_device_queue_family_properties);
expect_not_nullptr(vk_create_device);
expect_not_nullptr(vk_get_device_proc_address);
expect_not_nullptr(vk_destroy_device);
expect_not_nullptr(vk_get_physical_device_features);
expect_not_nullptr(vk_enumerate_device_extension_properties);
expect_not_nullptr(vk_cmd_begin_debug_label);
expect_not_nullptr(vk_cmd_end_debug_label);
expect_not_nullptr(vk_cmd_insert_debug_label);
expect_not_nullptr(vk_create_debug_messenger);
expect_not_nullptr(vk_destroy_debug_messenger);
expect_not_nullptr(vk_queue_begin_debug_label);
expect_not_nullptr(vk_queue_end_debug_label);
expect_not_nullptr(vk_queue_insert_debug_label);
expect_not_nullptr(vk_set_debug_object_name);
expect_not_nullptr(vk_set_debug_object_tag);
expect_not_nullptr(vk_submit_debug_message);
expect_not_nullptr(vk_get_physical_device_surface_support);
expect_not_nullptr(vk_get_physical_device_surface_capabilities);
expect_not_nullptr(vk_get_physical_device_surface_formats);
// TODO(Light): add test for platform-dependant functions
// expect_not_nullptr(vk_create_xlib_surface_khr);
// expect_not_nullptr(vk_destroy_surface_khr);
};
// TODO(Light): move device function symbols to device.cpp
// Case { "post load device functions state is correct" } = [] {
// using namespace renderer::vk;
// expect_not_nullptr(Instance::get());
//
// expect_not_nullptr(vk_get_device_queue);
// expect_not_nullptr(vk_create_command_pool);
// expect_not_nullptr(vk_destroy_command_pool);
// expect_not_nullptr(vk_allocate_command_buffers);
// expect_not_nullptr(vk_free_command_buffers);
// expect_not_nullptr(vk_begin_command_buffer);
// expect_not_nullptr(vk_end_command_buffer);
// expect_not_nullptr(vk_cmd_pipeline_barrier);
// expect_not_nullptr(vk_queue_submit);
// expect_not_nullptr(vk_queue_wait_idle);
// expect_not_nullptr(vk_device_wait_idle);
// expect_not_nullptr(vk_create_fence);
// expect_not_nullptr(vk_destroy_fence);
// expect_not_nullptr(vk_wait_for_fences);
// expect_not_nullptr(vk_reset_fences);
// expect_not_nullptr(vk_create_semaphore);
// expect_not_nullptr(vk_destroy_semaphore);
// expect_not_nullptr(vk_create_swapchain_khr);
// expect_not_nullptr(vk_destroy_swapchain_khr);
// expect_not_nullptr(vk_get_swapchain_images_khr);
// expect_not_nullptr(vk_acquire_next_image_khr);
// expect_not_nullptr(vk_queue_present_khr);
// expect_not_nullptr(vk_create_image_view);
// expect_not_nullptr(vk_destroy_image_view);
// expect_not_nullptr(vk_create_render_pass);
// expect_not_nullptr(vk_destroy_render_pass);
// expect_not_nullptr(vk_create_frame_buffer);
// expect_not_nullptr(vk_destroy_frame_buffer);
// expect_not_nullptr(vk_create_shader_module);
// expect_not_nullptr(vk_destroy_shader_module);
// expect_not_nullptr(vk_create_pipeline_layout);
// expect_not_nullptr(vk_destroy_pipeline_layout);
// expect_not_nullptr(vk_create_graphics_pipelines);
// expect_not_nullptr(vk_destroy_pipeline);
// expect_not_nullptr(vk_cmd_begin_render_pass);
// expect_not_nullptr(vk_cmd_end_render_pass);
// expect_not_nullptr(vk_cmd_bind_pipeline);
// expect_not_nullptr(vk_cmd_draw);
// expect_not_nullptr(vk_cmd_set_viewport);
// expect_not_nullptr(vk_cmd_set_scissors);
// };
};

View file

@ -1,77 +1,55 @@
#include <assets/shader.hpp>
#include <renderer/frontend/messenger.hpp>
#include <renderer/frontend/renderer/pass.hpp>
#include <renderer/test/utils.hpp>
using ::lt::renderer::IMessenger;
import renderer.frontend;
import renderer.test_utils;
Suite raii = "pass_raii"_suite = [] {
Case { "happy path won't throw" } = [] {
Fixture_ auto fixture = Fixture_RendererSystem {};
auto &system = fixture.renderer_system();
std::ignore = lt::renderer::IPass::create(
auto fixture = FixtureDeviceSwapchain {};
std::ignore = lt::renderer::create_pass(
constants::api,
system.get_device(),
system.get_swapchain(),
fixture.device(),
lt::assets::ShaderAsset { "./data/test_assets/triangle.vert.asset" },
lt::assets::ShaderAsset { "./data/test_assets/triangle.frag.asset" }
);
expect_false(fixture.has_any_messages_of(IMessenger ::MessageSeverity::error));
expect_false(fixture.has_any_messages_of(IMessenger ::MessageSeverity::warning));
expect_false(fixture.has_any_messages_of(lt::renderer::IDebugger ::MessageSeverity::error));
expect_false(
fixture.has_any_messages_of(lt::renderer::IDebugger ::MessageSeverity::warning)
);
};
Case { "unhappy path throws" } = [] {
auto fixture = Fixture_RendererSystem {};
auto &system = fixture.renderer_system();
auto fixture = FixtureDeviceSwapchain {};
expect_throw([&] {
std::ignore = lt::renderer::IPass::create(
std::ignore = lt::renderer::create_pass(
constants::api,
nullptr,
system.get_swapchain(),
lt::assets::ShaderAsset { "./data/test_assets/triangle.vert.asset" },
lt::assets::ShaderAsset { "./data/test_assets/triangle.frag.asset" }
);
});
expect_throw([&] {
std::ignore = lt::renderer::IPass::create(
constants::api,
system.get_device(),
nullptr,
lt::assets::ShaderAsset { "./data/test_assets/triangle.vert.asset" },
lt::assets::ShaderAsset { "./data/test_assets/triangle.frag.asset" }
);
});
expect_throw([&] {
std::ignore = lt::renderer::IPass::create(
std::ignore = lt::renderer::create_pass(
lt::renderer::Api::none,
system.get_device(),
system.get_swapchain(),
fixture.device(),
lt::assets::ShaderAsset { "./data/test_assets/triangle.vert.asset" },
lt::assets::ShaderAsset { "./data/test_assets/triangle.frag.asset" }
);
});
expect_throw([&] {
std::ignore = lt::renderer::IPass::create(
std::ignore = lt::renderer::create_pass(
lt::renderer::Api::direct_x,
system.get_device(),
system.get_swapchain(),
fixture.device(),
lt::assets::ShaderAsset { "./data/test_assets/triangle.vert.asset" },
lt::assets::ShaderAsset { "./data/test_assets/triangle.frag.asset" }
);
});
expect_throw([&] {
std::ignore = lt::renderer::IPass::create(
std::ignore = lt::renderer::create_pass(
lt::renderer::Api::metal,
system.get_device(),
system.get_swapchain(),
fixture.device(),
lt::assets::ShaderAsset { "./data/test_assets/triangle.vert.asset" },
lt::assets::ShaderAsset { "./data/test_assets/triangle.frag.asset" }
);

View file

@ -172,7 +172,7 @@ private:
{
// I know this makes the tests too verbose...
// but makes it easier to figure out what the problem is when things fail on ci
lt::log::error("vulkan: {}", data.message);
lt::log::debug("vulkan: {}", data.message);
std::ignore = data;
std::ignore = type;
@ -221,6 +221,10 @@ public:
return m_system;
}
auto device() -> lt::renderer::IDevice &
{
}
[[nodiscard]] auto has_any_messages() const -> bool
{
return m_user_data->m_has_any_messages;

View file

@ -61,7 +61,8 @@ namespace constants {
constexpr auto application_version = VK_MAKE_VERSION(1, 0, 0);
constexpr auto engine_version = VK_MAKE_VERSION(1, 0, 0);
constexpr auto api_version = VK_API_VERSION_1_4;
constexpr auto engine_name = std::string_view { "light_engine_vulkan_renderer" };
constexpr auto app_name = "load_this_from_envs...";
constexpr auto engine_name = "light_engine_vulkan_renderer";
constexpr auto max_physical_device_name = VK_MAX_PHYSICAL_DEVICE_NAME_SIZE;
constexpr auto max_memory_types = VK_MAX_MEMORY_TYPES;
@ -101,12 +102,6 @@ namespace device_extension_names {
constexpr auto swapchain = VK_KHR_SWAPCHAIN_EXTENSION_NAME;
constexpr auto dynamic_rendering = VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME;
constexpr auto descriptor_indexing = VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME;
constexpr auto depth_stencil_resolve = VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME;
constexpr auto maintenance_3 = VK_KHR_MAINTENANCE3_EXTENSION_NAME;
constexpr auto maintenance_2 = VK_KHR_MAINTENANCE2_EXTENSION_NAME;
constexpr auto create_renderpass_2 = VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME;
constexpr auto multiview = VK_KHR_MULTIVIEW_EXTENSION_NAME;
}; // namespace device_extension_names
@ -1170,12 +1165,16 @@ class Device
{
public:
friend class Queue;
friend class Memory;
friend class Buffer;
friend class Swapchain;
friend class Image;
friend class ImageView;
friend class Pipeline;
friend class Semaphore;
friend class Fence;
friend class ShaderModule;
friend class DescriptorSetLayout;
struct CreateInfo
{
@ -1435,6 +1434,11 @@ private:
class Buffer
{
public:
friend class Device;
friend class Memory;
static constexpr auto object_type = VK_OBJECT_TYPE_BUFFER;
enum UsageFlags : VkFlags
{
transfer_src_bit = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
@ -1484,6 +1488,8 @@ public:
SharingMode sharing_mode;
std::vector<uint32_t> queue_family_indices;
std::string_view name;
};
Buffer(Device &device, CreateInfo info);
@ -1518,6 +1524,8 @@ public:
friend class Swapchain;
friend class ImageView;
static constexpr auto object_type = VK_OBJECT_TYPE_IMAGE_VIEW;
enum AspectFlags : VkFlags
@ -1649,7 +1657,7 @@ private:
return m_image;
}
VkDevice m_device;
memory::NullOnMove<VkDevice> m_device;
VkImage m_image;
};
@ -1694,7 +1702,7 @@ public:
Image::Range range;
std::string_view debug_name;
std::string_view name;
};
ImageView() = default;
@ -1709,10 +1717,7 @@ public:
auto operator=(const ImageView &) -> ImageView & = delete;
~ImageView()
{
// WIP;
}
~ImageView();
private:
[[nodiscard]] auto get_vk_handle() -> VkImageView
@ -1720,7 +1725,7 @@ private:
return m_image_view;
}
VkDevice m_device;
memory::NullOnMove<VkDevice> m_device;
VkImageView m_image_view;
};
@ -1728,24 +1733,23 @@ private:
class ShaderModule
{
public:
friend class Device;
friend class Pipeline;
static constexpr auto object_type = VK_OBJECT_TYPE_SHADER_MODULE;
struct CreateInfo
{
std::vector<std::byte> code;
std::string_view name;
};
ShaderModule() = default;
ShaderModule(Device &device, CreateInfo info)
{
// WIP
}
ShaderModule(Device &device, CreateInfo info);
~ShaderModule()
{
// WIP
}
~ShaderModule();
ShaderModule(ShaderModule &&) = default;
@ -1841,14 +1845,13 @@ public:
Flags flags;
std::vector<Binding> bindings;
std::string_view name;
};
DescriptorSetLayout() = default;
DescriptorSetLayout(Device &device, CreateInfo info)
{
// WIP
}
DescriptorSetLayout(Device &device, CreateInfo info);
DescriptorSetLayout(DescriptorSetLayout &&) = default;
@ -1858,15 +1861,16 @@ public:
auto operator=(const DescriptorSetLayout &) -> DescriptorSetLayout & = delete;
~DescriptorSetLayout()
{
// WIP
}
~DescriptorSetLayout();
private:
auto get_vk_handle() -> VkDescriptorSetLayout
{
return m_descriptor_set_layout;
}
memory::NullOnMove<VkDevice> m_device;
VkDescriptorSetLayout m_layout;
VkDescriptorSetLayout m_descriptor_set_layout;
};
class Pipeline
@ -2022,10 +2026,7 @@ public:
PipelineLayout() = default;
PipelineLayout(Device &device, CreateInfo info)
{
// WIP
}
PipelineLayout(Device &device, CreateInfo info);
PipelineLayout(PipelineLayout &&) = default;
@ -2035,20 +2036,17 @@ public:
auto operator=(const PipelineLayout &) -> PipelineLayout & = delete;
~PipelineLayout()
{
// WIP
}
~PipelineLayout();
private:
[[nodiscard]] auto get_vk_handle() -> VkPipelineLayout
{
return m_layout;
return m_pipeline_layout;
}
memory::NullOnMove<VkDevice> m_device {};
VkPipelineLayout m_layout {};
VkPipelineLayout m_pipeline_layout {};
};
class CommandBuffer
@ -2352,6 +2350,8 @@ public:
PresentMode present_mode;
Surface::Transform pre_transform;
std::string_view name;
};
Swapchain() = default;
@ -2384,7 +2384,7 @@ private:
return &m_swapchain;
}
VkDevice m_device;
memory::NullOnMove<VkDevice> m_device;
VkSwapchainKHR m_swapchain;
};
@ -2472,6 +2472,8 @@ public:
std::size_t size;
std::uint32_t memory_type_idx;
std::string_view name;
};
Memory(Device &device, Buffer &buffer, AllocateInfo info);
@ -2791,10 +2793,8 @@ void unload_library()
void load_global_functions()
{
constexpr auto load_fn = []<typename T>(T &pfn, const char *fn_name) {
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
pfn = reinterpret_cast<T>(api::get_instance_proc_address(nullptr, fn_name));
pfn = std::bit_cast<T>(api::get_instance_proc_address(nullptr, fn_name));
lt::debug::ensure(pfn, "Failed to load vulkan global function: {}", fn_name);
// log::trace("Loaded global function: {}", fn_name);
};
load_fn(api::create_instance, "vkCreateInstance");
@ -2856,7 +2856,6 @@ void Device::load_functions()
{
const auto load_fn = [this]<typename T>(T &pfn, const char *fn_name) {
pfn = std::bit_cast<T>(api::get_device_proc_address(m_device, fn_name));
log::trace("Loading: {}", fn_name);
lt::debug::ensure(pfn, "Failed to load vulkan device function: {}", fn_name);
};
@ -2919,6 +2918,7 @@ void Device::load_functions()
load_fn(api::free_memory, "vkFreeMemory");
load_fn(api::get_buffer_memory_requirements, "vkGetBufferMemoryRequirements");
load_fn(api::reset_command_buffer, "vkResetCommandBuffer");
load_fn(api::cmd_begin_rendering, "vkCmdBeginRendering");
load_fn(api::cmd_end_rendering, "vkCmdEndRendering");
}
@ -2995,6 +2995,14 @@ Instance::Instance(CreateInfo info)
.pSettings = layer_settings.data(),
};
auto app_info = VkApplicationInfo {
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
.applicationVersion = constants::application_version,
.pApplicationName = constants::engine_name,
.pEngineName = constants::app_name,
.apiVersion = constants::api_version,
};
auto vk_info = VkInstanceCreateInfo {
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pNext = &layer_settings_create_info,
@ -3003,6 +3011,7 @@ Instance::Instance(CreateInfo info)
.ppEnabledLayerNames = layer_names.data(),
.enabledExtensionCount = static_cast<uint32_t>(extension_names.size()),
.ppEnabledExtensionNames = extension_names.data(),
.pApplicationInfo = &app_info,
};
log::debug("Extension names:");
@ -3614,13 +3623,8 @@ Device::Device(const Gpu &gpu, CreateInfo info)
};
auto vk_descriptor_indexing_features = VkPhysicalDeviceDescriptorIndexingFeatures {};
auto vk_dynamic_rendering_features = VkPhysicalDeviceDynamicRenderingFeatures {};
vk_dynamic_rendering_features = VkPhysicalDeviceDynamicRenderingFeatures {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES,
.pNext = {},
.dynamicRendering = true,
};
log::debug("Dynamic rendering: {}", vk_dynamic_rendering_features.dynamicRendering);
// log::debug("Dynamic rendering: {}", vk_dynamic_rendering_features.dynamicRendering);
// void **last_p_next = &vk_features_2.pNext;
if (info.dynamic_rendering_features)
@ -3680,12 +3684,18 @@ Device::Device(const Gpu &gpu, CreateInfo info)
// // *last_p_next = &vk_descriptor_indexing_features;
// // last_p_next = &vk_descriptor_indexing_features.pNext;
// }
for (auto name : vk_extension_names)
{
log::debug("Extension name: {}", name);
}
auto physical_device_features = VkPhysicalDeviceFeatures {};
auto physical_device_features = VkPhysicalDeviceFeatures {
.geometryShader = true,
.samplerAnisotropy = true,
.multiDrawIndirect = true,
.drawIndirectFirstInstance = true,
};
auto vk_dynamic_rendering_features = VkPhysicalDeviceDynamicRenderingFeatures {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES,
.pNext = {},
.dynamicRendering = true,
};
auto vk_info = VkDeviceCreateInfo {
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.pNext = &vk_dynamic_rendering_features,
@ -3696,6 +3706,39 @@ Device::Device(const Gpu &gpu, CreateInfo info)
.pEnabledFeatures = &physical_device_features,
};
log::debug("sType: VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO");
log::debug("*pNext (dynamic rendering features):");
log::debug("\tsType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES");
log::debug("\tdynamicRendering = {}", vk_dynamic_rendering_features.dynamicRendering);
log::debug("\tpNext = {}", vk_dynamic_rendering_features.pNext);
log::debug("queueCreateInfoCount: {}", static_cast<uint32_t>(vk_queue_infos.size()));
log::debug("*pQueueCreateInfos:");
for (auto &info : vk_queue_infos)
{
log::debug("\tsType: VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO");
log::debug("\tpNext: {}", info.pNext);
log::debug("\tqueueCount: {}", info.queueCount);
log::debug("\tqueueFamilyIndex: {}", info.queueFamilyIndex);
log::debug("\t*pQueuePriorities: {}", *info.pQueuePriorities);
log::debug("----");
}
log::debug("enabledExtensionCount: {}", vk_info.enabledExtensionCount);
for (const auto *name : vk_extension_names)
{
log::debug("\t{}", name);
}
log::debug("*pEnabledFeatures:");
log::debug("\t.geometryShader = {}", physical_device_features.geometryShader);
log::debug("\t.samplerAnisotropy = {}", physical_device_features.samplerAnisotropy);
log::debug("\t.multiDrawIndirect = {}", physical_device_features.multiDrawIndirect);
log::debug(
"\t.drawIndirectFirstInstance = {}",
physical_device_features.drawIndirectFirstInstance
);
vkc(api::create_device(gpu.m_physical_device, &vk_info, nullptr, &m_device));
}
@ -4136,19 +4179,45 @@ ImageView::ImageView(Device &device, Image &image, CreateInfo info)
: m_device(device.get_vk_handle())
, m_image_view()
{
auto vk_info = VkImageViewCreateInfo {};
auto vk_info = VkImageViewCreateInfo {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.pNext = {},
.image = image.get_vk_handle(),
.viewType = static_cast<VkImageViewType>(info.type),
.format = static_cast<VkFormat>(info.format),
.components = VkComponentMapping{
.r = static_cast<VkComponentSwizzle>(info.components[0]),
.g = static_cast<VkComponentSwizzle>(info.components[1]),
.b = static_cast<VkComponentSwizzle>(info.components[2]),
.a = static_cast<VkComponentSwizzle>(info.components[3]),
},
.subresourceRange = {
.aspectMask = static_cast<VkImageAspectFlags>(info.range.aspect_flags),
.baseMipLevel = info.range.base_mip_level,
.levelCount = info.range.level_count,
.baseArrayLayer = info.range.base_array_layer,
.layerCount = info.range.layer_count,
},
};
vkc(api::create_image_view(m_device, &vk_info, nullptr, &m_image_view));
if (info.debug_name.empty())
if (info.name.empty())
{
info.debug_name = "<unnamed>";
info.name = "<unnamed>";
}
device.name(*this, "{}", info.name);
}
device.name(*this, "{}", info.debug_name);
ImageView::~ImageView()
{
if (m_device)
{
api::destroy_image_view(m_device, m_image_view, nullptr);
}
}
Swapchain::Swapchain(Device &device, Surface &surface, CreateInfo info)
: m_device(device.m_device)
: m_device(device.m_device.get())
, m_swapchain()
{
auto vk_info = VkSwapchainCreateInfoKHR {
@ -4170,12 +4239,21 @@ Swapchain::Swapchain(Device &device, Surface &surface, CreateInfo info)
.oldSwapchain = nullptr,
};
vkc(api::create_swapchain_khr(m_device, &vk_info, nullptr, &m_swapchain));
if (info.name.empty())
{
info.name = "<unnamed>";
}
device.name(*this, "{}", info.name);
}
Swapchain::~Swapchain()
{
if (m_device)
{
api::destroy_swapchain_khr(m_device, m_swapchain, nullptr);
}
}
[[nodiscard]] auto Swapchain::get_images() -> std::vector<Image>
{
@ -4211,10 +4289,27 @@ Swapchain::~Swapchain()
}
Buffer::Buffer(Device &device, CreateInfo info) {};
Buffer::Buffer(Device &device, CreateInfo info): m_device(device.m_device.get())
{
auto vk_info = VkBufferCreateInfo {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.size = info.size,
.usage = info.usage,
.sharingMode = static_cast<VkSharingMode>(info.sharing_mode),
};
vkc(api::create_buffer(m_device, &vk_info, nullptr, &m_buffer));
if (info.name.empty())
{
info.name = "<unnamed>";
}
device.name(*this, "{}", info.name);
};
Buffer::~Buffer()
{
api::destroy_buffer(m_device, m_buffer, nullptr);
}
[[nodiscard]] auto Buffer::get_memory_requirements() const -> MemoryRequirements
@ -4228,12 +4323,28 @@ Buffer::~Buffer()
};
}
Memory::Memory(Device &device, Buffer &buffer, AllocateInfo info)
Memory::Memory(Device &device, Buffer &buffer, AllocateInfo info): m_device(device.m_device.get())
{
auto vk_info = VkMemoryAllocateInfo {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.pNext = {},
.allocationSize = info.size,
.memoryTypeIndex = info.memory_type_idx,
};
api::allocate_memory(m_device, &vk_info, nullptr, &m_memory);
if (info.name.empty())
{
info.name = "<unnamed>";
}
device.name(*this, "{}", info.name);
vkc(api::bind_buffer_memory(m_device, buffer.get_vk_handle(), m_memory, 0u));
}
Memory::~Memory()
{
api::free_memory(m_device, m_memory, nullptr);
}
[[nodiscard]] auto Memory::map(std::size_t size, std::size_t offset) -> std::span<std::byte>
@ -4248,6 +4359,53 @@ void Memory::unmap()
api::unmap_memory(m_device, m_memory);
}
ShaderModule::ShaderModule(Device &device, CreateInfo info): m_device(device.get_vk_handle())
{
auto vk_info = VkShaderModuleCreateInfo {
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
.pNext = {},
.flags = {},
.codeSize = info.code.size() / 4ul,
.pCode = std::bit_cast<std::uint32_t *>(info.code.data()),
};
vkc(api::create_shader_module(m_device, &vk_info, nullptr, &m_shader_module));
if (info.name.empty())
{
info.name = "<unnamed>";
}
device.name(*this, "{}", info.name);
}
ShaderModule::~ShaderModule()
{
api::destroy_shader_module(m_device, m_shader_module, nullptr);
}
DescriptorSetLayout::DescriptorSetLayout(Device &device, CreateInfo info)
: m_device(device.get_vk_handle())
{
auto vk_info = VkDescriptorSetLayoutCreateInfo {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.pNext = {},
.flags = {},
.bindingCount = static_cast<std::uint32_t>(info.bindings.size()),
.pBindings = std::bit_cast<VkDescriptorSetLayoutBinding *>(info.bindings.data()),
};
vkc(api::create_descriptor_set_layout(m_device, &vk_info, nullptr, &m_descriptor_set_layout));
if (info.name.empty())
{
info.name = "<unnamed>";
}
device.name(*this, "{}", info.name);
}
DescriptorSetLayout::~DescriptorSetLayout()
{
api::destroy_descriptor_set_layout(m_device, m_descriptor_set_layout, nullptr);
}
Pipeline::Pipeline(Device &device, PipelineLayout &layout, CreateInfo info)
: m_device(device.m_device.get())
@ -4381,6 +4539,16 @@ Pipeline::Pipeline(Device &device, PipelineLayout &layout, CreateInfo info)
}
Pipeline::~Pipeline()
{
api::destroy_pipeline(m_device, m_pipeline, nullptr);
}
PipelineLayout::PipelineLayout(Device &device, CreateInfo info) {
vkc(api::create_pipeline_layout(m_device, &vk_info, nullptr, &m_layout))
}
PipelineLayout::~PipelineLayout()
{
}

View file

@ -100,12 +100,6 @@ void Device::initialize_logical_device()
.extensions = {
vk::device_extension_names::swapchain,
vk::device_extension_names::dynamic_rendering,
vk::device_extension_names::descriptor_indexing,
vk::device_extension_names::depth_stencil_resolve,
vk::device_extension_names::maintenance_3,
vk::device_extension_names::maintenance_2,
vk::device_extension_names::create_renderpass_2,
vk::device_extension_names::multiview,
},
.features = {},

View file

@ -103,10 +103,10 @@ Swapchain::Swapchain(ISurface *surface, IGpu *gpu, IDevice *device)
.queue_family_indices = m_device->get_family_indices(),
.present_mode = vk::Swapchain::PresentMode::immediate,
.pre_transform = capabilities.current_transform,
.name = std::format("swapchain {}", idx++),
}
);
m_resolution = capabilities.current_extent;
m_device->vk().name(m_swapchain, "swapchain {}", idx++);
m_device->vk().wait_idle();
m_images = m_swapchain.get_images();
@ -133,7 +133,7 @@ Swapchain::Swapchain(ISurface *surface, IGpu *gpu, IDevice *device)
.layer_count = 1u,
},
.debug_name = std::format("swapchain image {}", idx++),
.name = std::format("swapchain image view {}", idx++),
},
}
);

View file

@ -1,4 +1,5 @@
export module surface.events;
import input.codes;
import math.vec2;
import std;
@ -7,85 +8,85 @@ export namespace lt::surface {
class KeyPressedEvent
{
public:
KeyPressedEvent(std::uint32_t key): m_key(key)
KeyPressedEvent(Key key): m_key(key)
{
}
[[nodiscard]] auto get_key() const -> std::uint32_t
[[nodiscard]] auto get_key() const -> Key
{
return m_key;
}
[[nodiscard]] auto to_string() const -> std::string
{
return std::format("KeyPressed: {}", m_key);
return std::format("KeyPressed: {}", std::to_underlying(m_key));
}
private:
std::uint32_t m_key;
Key m_key;
};
class KeyRepeatEvent
{
public:
KeyRepeatEvent(std::int32_t key): m_key(key)
KeyRepeatEvent(Key key): m_key(key)
{
}
[[nodiscard]] auto get_key() const -> std::uint32_t
[[nodiscard]] auto get_key() const -> Key
{
return m_key;
}
[[nodiscard]] auto to_string() const -> std::string
{
return std::format("KeyRepeated: {}", m_key);
return std::format("KeyRepeated: {}", std::to_underlying(m_key));
}
private:
std::uint32_t m_key;
Key m_key;
};
class KeyReleasedEvent
{
public:
KeyReleasedEvent(std::uint32_t key): m_key(key)
KeyReleasedEvent(Key key): m_key(key)
{
}
[[nodiscard]] auto get_key() const -> std::uint32_t
[[nodiscard]] auto get_key() const -> Key
{
return m_key;
}
[[nodiscard]] auto to_string() const -> std::string
{
return std::format("KeyReleased: {}", m_key);
return std::format("KeyReleased: {}", std::to_underlying(m_key));
}
private:
std::uint32_t m_key;
Key m_key;
};
class KeySetCharEvent
{
public:
KeySetCharEvent(std::uint32_t character): m_character(character)
KeySetCharEvent(Key character): m_character(character)
{
}
[[nodiscard]] auto get_character() const -> std::uint32_t
[[nodiscard]] auto get_character() const -> Key
{
return m_character;
}
[[nodiscard]] auto to_string() const -> std::string
{
return std::format("KeyCharSet: {}", m_character);
return std::format("KeyCharSet: {}", std::to_underlying(m_character));
}
private:
std::uint32_t m_character;
Key m_character;
};
class MouseMovedEvent
@ -145,43 +146,43 @@ private:
class ButtonPressedEvent
{
public:
ButtonPressedEvent(std::int32_t button): m_button(button)
ButtonPressedEvent(Key button): m_button(button)
{
}
[[nodiscard]] auto get_button() const -> std::int32_t
[[nodiscard]] auto get_button() const -> Key
{
return m_button;
}
[[nodiscard]] auto to_string() const -> std::string
{
return std::format("ButtonPressed: {}", m_button);
return std::format("ButtonPressed: {}", std::to_underlying(m_button));
}
private:
std::int32_t m_button;
Key m_button;
};
class ButtonReleasedEvent
{
public:
ButtonReleasedEvent(std::int32_t button): m_button(button)
ButtonReleasedEvent(Key button): m_button(button)
{
}
[[nodiscard]] auto get_button() const -> std::int32_t
[[nodiscard]] auto get_button() const -> Key
{
return m_button;
}
[[nodiscard]] auto to_string() const -> std::string
{
return std::format("ButtonReleased: {}", m_button);
return std::format("ButtonReleased: {}", std::to_underlying(m_button));
}
private:
std::int32_t m_button;
Key m_button;
};
class ClosedEvent
@ -207,9 +208,7 @@ public:
[[nodiscard]] auto to_string() const -> std::string
{
auto stream = std::stringstream {};
stream << "WindwoMoved: " << m_position.x << ", " << m_position.y;
return stream.str();
return std::format("WindowMoved: {}, {}", m_position.x, m_position.y);
}
private:
@ -230,9 +229,7 @@ public:
[[nodiscard]] auto to_string() const -> std::string
{
auto stream = std::stringstream {};
stream << "SurfaceResized: " << m_size.x << ", " << m_size.y;
return stream.str();
return std::format("SurfaceResized: {}, {}", m_size.x, m_size.y);
}
private:

View file

@ -13,6 +13,7 @@ import logger;
import ecs.registry;
import time;
import std;
import input.codes;
namespace lt::surface {
@ -226,26 +227,22 @@ void System::handle_events(SurfaceComponent &surface)
{
case KeyPress:
{
queue.emplace_back<KeyPressedEvent>(
static_cast<std::uint32_t>(XLookupKeysym(&event.xkey, 0))
);
queue.emplace_back<KeyPressedEvent>(static_cast<Key>(XLookupKeysym(&event.xkey, 0)));
break;
}
case KeyRelease:
{
queue.emplace_back<KeyReleasedEvent>(
static_cast<std::uint32_t>(XLookupKeysym(&event.xkey, 0))
);
queue.emplace_back<KeyReleasedEvent>(static_cast<Key>(XLookupKeysym(&event.xkey, 0)));
break;
}
case ButtonPress:
{
queue.emplace_back<ButtonPressedEvent>(static_cast<int>(event.xbutton.button));
queue.emplace_back<ButtonPressedEvent>(static_cast<Key>(event.xbutton.button));
break;
}
case ButtonRelease:
{
queue.emplace_back<ButtonReleasedEvent>(static_cast<int>(event.xbutton.button));
queue.emplace_back<ButtonReleasedEvent>(static_cast<Key>(event.xbutton.button));
break;
}
case FocusIn:

View file

@ -3,7 +3,7 @@ function(add_module)
ARGS
""
"NAME"
"INTERFACES;ROOT_DIR;SOURCES;DEPENDENCIES;PRIVATE_DEPENDENCIES;TESTS;ENTRYPOINT"
"INTERFACES;ROOT_DIR;SOURCES;DEPENDENCIES;PRIVATE_DEPENDENCIES;TESTS;TEST_INTERFACES;ENTRYPOINT;"
${ARGN}
)
@ -19,14 +19,19 @@ function(add_module)
set(module_directory "${ARGS_ROOT_DIR}")
endif()
# In this case, the module is an executable, so we prepend "lib" to the target name.
# And set the "executable_target" name to ARGS_NAME.
# The rationale here is to easily be able to write tests for an executable modules's interfaces...
# by splitting it into two targets: lib"executable_name" for the interface and "executable_name" for the "int main()" defining file (the entrypoint).
# the lib"executable_name" should not be disruptive since an executable module's library will not be dependent upon (except by the tests within the same module)
# In this case, the module is an executable, so we prepend "lib" to the
# target name. And set the "executable_target" name to ARGS_NAME. The
# rationale here is to easily be able to write tests for an executable
# modules's interfaces... by splitting it into two targets:
# lib"executable_name" for the interface and "executable_name" for the "int
# main()" defining file (the entrypoint). the lib"executable_name" should
# not be disruptive since an executable module's library will not be
# dependent upon (except by the tests within the same module)
if(ARGS_ENTRYPOINT)
set(target_library_name "lib_${ARGS_NAME}")
add_executable(${target_executable_name} ${module_directory}/${ARGS_ENTRYPOINT})
add_executable(
${target_executable_name} ${module_directory}/${ARGS_ENTRYPOINT}
)
endif()
add_library(${target_library_name})
@ -53,16 +58,18 @@ function(add_module)
list(APPEND files "${module_directory}/${file}")
endforeach()
target_sources(
${target_library_name} PUBLIC FILE_SET public_cxx_modules TYPE CXX_MODULES
FILES ${files}
${target_library_name} PUBLIC FILE_SET public_cxx_modules TYPE
CXX_MODULES FILES ${files}
)
endif()
target_link_libraries(${target_library_name} PUBLIC ${ARGS_DEPENDENCIES})
target_link_libraries(${target_library_name} PRIVATE ${ARGS_PRIVATE_DEPENDENCIES})
target_link_libraries(
${target_library_name} PRIVATE ${ARGS_PRIVATE_DEPENDENCIES}
)
if(ARGS_TESTS)
message("ADDING TESTS!!!")
message("ADDING TESTS ${target_library_name}!!!")
set(test_files)
foreach(test_file ${ARGS_TESTS})
list(APPEND test_files "${module_directory}/${test_file}")
@ -71,14 +78,28 @@ function(add_module)
add_executable("${target_library_name}_tests" ${test_files})
target_link_libraries(
"${target_library_name}_tests"
PRIVATE ${target_lib_name}
PRIVATE ${target_library_name}
#
test
)
if(ARGS_TEST_INTERFACES)
set(test_interface_files)
foreach(file ${ARGS_TEST_INTERFACES})
list(APPEND test_interface_files "${module_directory}/${file}")
endforeach()
message("TEST INTERFACE FILES: ${test_interface_files}")
target_sources(
"${target_library_name}_tests"
PRIVATE FILE_SET test_cxx_modules TYPE CXX_MODULES FILES
${test_interface_files}
)
endif()
endif()
if(ARGS_ENTRYPOINT)
target_link_libraries(${target_executable_name} PRIVATE ${target_library_name})
target_link_libraries(
${target_executable_name} PRIVATE ${target_library_name}
)
endif()
endfunction()