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

View file

View file

@ -156,7 +156,7 @@ void System::on_surface_lost_focus()
void System::on_key_press(const lt::surface::KeyPressedEvent &event) 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 " log::debug("Key code larger than key container size, implement platform-dependant "
"key-code-mapping!"); "key-code-mapping!");
@ -164,12 +164,12 @@ void System::on_key_press(const lt::surface::KeyPressedEvent &event)
return; 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) 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 " log::debug("Key code larger than key container size, implement platform-dependant "
"key-code-mapping!"); "key-code-mapping!");
@ -177,7 +177,7 @@ void System::on_key_release(const lt::surface::KeyReleasedEvent &event)
return; 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) 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) 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) 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 } // namespace lt::input

View file

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

View file

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

View file

@ -1,31 +1,23 @@
#include <renderer/backend/vk/context/surface.hpp> import renderer.frontend;
#include <renderer/backend/vk/debug/messenger.hpp> import renderer.test_utils;
#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;
void noop_callback( void noop_callback(
Messenger::Severity message_severity, lt::renderer::IDebugger::MessageSeverity message_severity,
Messenger::Type message_type, lt::renderer::IDebugger::MessageType message_type,
Messenger::CallbackData_T vulkan_data, const lt::renderer::IDebugger::MessageData &data,
void *user_data std::any &user_data
) )
{ {
} }
Suite raii = "messenger_raii"_suite = [] { Suite raii = "debugger_raii"_suite = [] {
Case { "happy path won't throw" } = [] { Case { "happy path won't throw" } = [] {
Messenger( std::ignore = lt::renderer::create_debugger(
Messenger::CreateInfo { lt::renderer::Api::vulkan,
.severity = all_severity, lt::renderer::get_instance(lt::renderer::Api::vulkan),
.type = all_type, lt::renderer::IDebugger::CreateInfo {
.severities = lt::renderer::IDebugger::MessageSeverity::all,
.types = lt::renderer::IDebugger::MessageType::all,
.callback = &noop_callback, .callback = &noop_callback,
} }
); );
@ -33,116 +25,39 @@ Suite raii = "messenger_raii"_suite = [] {
Case { "unhappy path throws" } = [] { Case { "unhappy path throws" } = [] {
expect_throw([] { expect_throw([] {
Messenger( std::ignore = lt::renderer::create_debugger(
Messenger::CreateInfo { lt::renderer::Api::vulkan,
.severity = all_severity, lt::renderer::get_instance(lt::renderer::Api::vulkan),
.type = all_type, lt::renderer::IDebugger::CreateInfo {
.severities = lt::renderer::IDebugger::MessageSeverity::all,
.types = lt::renderer::IDebugger::MessageType::all,
.callback = {}, .callback = {},
} }
); );
}); });
expect_throw([] { expect_throw([] {
Messenger( std::ignore = lt::renderer::create_debugger(
Messenger::CreateInfo { lt::renderer::Api::vulkan,
.severity = {}, lt::renderer::get_instance(lt::renderer::Api::vulkan),
.type = all_type, lt::renderer::IDebugger::CreateInfo {
.severities = {},
.types = lt::renderer::IDebugger::MessageType::all,
.callback = &noop_callback, .callback = &noop_callback,
} }
); );
}); });
expect_throw([] { expect_throw([] {
Messenger( std::ignore = lt::renderer::create_debugger(
Messenger::CreateInfo { lt::renderer::Api::vulkan,
.severity = all_severity, lt::renderer::get_instance(lt::renderer::Api::vulkan),
.type = {}, lt::renderer::IDebugger::CreateInfo {
.severities = lt::renderer::IDebugger::MessageSeverity::all,
.types = {},
.callback = &noop_callback, .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> import renderer.frontend;
#include <ranges> import renderer.test_utils;
#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>
Suite raii = "device_raii"_suite = [] { Suite raii = "device_raii"_suite = [] {
Case { "happy path won't throw" } = [] { Case { "happy path won't throw" } = [] {
auto fixture = Fixture_SurfaceGpu {}; auto fixture = Fixture_SurfaceGpu {};
std::ignore = lt::renderer::IDevice::create( std::ignore = lt::renderer::create_device(constants::api, fixture.gpu(), fixture.surface());
constants::api,
fixture.gpu(),
fixture.surface()
);
}; };
Case { "unhappy path throws" } = [] { Case { "unhappy path throws" } = [] {
auto fixture = Fixture_SurfaceGpu {}; auto fixture = Fixture_SurfaceGpu {};
expect_throw([&] { expect_throw([&] {
ignore = lt::renderer::IDevice::create(constants::api, nullptr, fixture.surface()); ignore = lt::renderer::create_device(constants::api, nullptr, fixture.surface());
}); });
expect_throw([&] { expect_throw([&] {
ignore = lt::renderer::IDevice::create(constants::api, fixture.gpu(), nullptr); ignore = lt::renderer::create_device(constants::api, fixture.gpu(), nullptr);
}); });
expect_throw([&] { expect_throw([&] {
ignore = lt::renderer::IDevice::create( ignore = lt::renderer::create_device(
lt::renderer::Api::none, lt::renderer::Api::none,
fixture.gpu(), fixture.gpu(),
fixture.surface() fixture.surface()
@ -37,7 +27,7 @@ Suite raii = "device_raii"_suite = [] {
}); });
expect_throw([&] { expect_throw([&] {
ignore = lt::renderer::IDevice::create( ignore = lt::renderer::create_device(
lt::renderer::Api::direct_x, lt::renderer::Api::direct_x,
fixture.gpu(), fixture.gpu(),
fixture.surface() fixture.surface()
@ -45,7 +35,7 @@ Suite raii = "device_raii"_suite = [] {
}); });
expect_throw([&] { expect_throw([&] {
ignore = lt::renderer::IDevice::create( ignore = lt::renderer::create_device(
lt::renderer::Api::metal, lt::renderer::Api::metal,
fixture.gpu(), fixture.gpu(),
fixture.surface() 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> import renderer.frontend;
#include <renderer/frontend/messenger.hpp> import renderer.test_utils;
#include <renderer/frontend/renderer/pass.hpp>
#include <renderer/test/utils.hpp>
using ::lt::renderer::IMessenger;
Suite raii = "pass_raii"_suite = [] { Suite raii = "pass_raii"_suite = [] {
Case { "happy path won't throw" } = [] { Case { "happy path won't throw" } = [] {
Fixture_ auto fixture = Fixture_RendererSystem {}; auto fixture = FixtureDeviceSwapchain {};
auto &system = fixture.renderer_system(); std::ignore = lt::renderer::create_pass(
std::ignore = lt::renderer::IPass::create(
constants::api, constants::api,
system.get_device(), fixture.device(),
system.get_swapchain(),
lt::assets::ShaderAsset { "./data/test_assets/triangle.vert.asset" }, lt::assets::ShaderAsset { "./data/test_assets/triangle.vert.asset" },
lt::assets::ShaderAsset { "./data/test_assets/triangle.frag.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(lt::renderer::IDebugger ::MessageSeverity::error));
expect_false(fixture.has_any_messages_of(IMessenger ::MessageSeverity::warning)); expect_false(
fixture.has_any_messages_of(lt::renderer::IDebugger ::MessageSeverity::warning)
);
}; };
Case { "unhappy path throws" } = [] { Case { "unhappy path throws" } = [] {
auto fixture = Fixture_RendererSystem {}; auto fixture = FixtureDeviceSwapchain {};
auto &system = fixture.renderer_system();
expect_throw([&] { expect_throw([&] {
std::ignore = lt::renderer::IPass::create( std::ignore = lt::renderer::create_pass(
constants::api, constants::api,
nullptr, 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.vert.asset" },
lt::assets::ShaderAsset { "./data/test_assets/triangle.frag.asset" } lt::assets::ShaderAsset { "./data/test_assets/triangle.frag.asset" }
); );
}); });
expect_throw([&] { expect_throw([&] {
std::ignore = lt::renderer::IPass::create( std::ignore = lt::renderer::create_pass(
lt::renderer::Api::none, lt::renderer::Api::none,
system.get_device(), fixture.device(),
system.get_swapchain(),
lt::assets::ShaderAsset { "./data/test_assets/triangle.vert.asset" }, lt::assets::ShaderAsset { "./data/test_assets/triangle.vert.asset" },
lt::assets::ShaderAsset { "./data/test_assets/triangle.frag.asset" } lt::assets::ShaderAsset { "./data/test_assets/triangle.frag.asset" }
); );
}); });
expect_throw([&] { expect_throw([&] {
std::ignore = lt::renderer::IPass::create( std::ignore = lt::renderer::create_pass(
lt::renderer::Api::direct_x, lt::renderer::Api::direct_x,
system.get_device(), fixture.device(),
system.get_swapchain(),
lt::assets::ShaderAsset { "./data/test_assets/triangle.vert.asset" }, lt::assets::ShaderAsset { "./data/test_assets/triangle.vert.asset" },
lt::assets::ShaderAsset { "./data/test_assets/triangle.frag.asset" } lt::assets::ShaderAsset { "./data/test_assets/triangle.frag.asset" }
); );
}); });
expect_throw([&] { expect_throw([&] {
std::ignore = lt::renderer::IPass::create( std::ignore = lt::renderer::create_pass(
lt::renderer::Api::metal, lt::renderer::Api::metal,
system.get_device(), fixture.device(),
system.get_swapchain(),
lt::assets::ShaderAsset { "./data/test_assets/triangle.vert.asset" }, lt::assets::ShaderAsset { "./data/test_assets/triangle.vert.asset" },
lt::assets::ShaderAsset { "./data/test_assets/triangle.frag.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... // I know this makes the tests too verbose...
// but makes it easier to figure out what the problem is when things fail on ci // 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 = data;
std::ignore = type; std::ignore = type;
@ -221,6 +221,10 @@ public:
return m_system; return m_system;
} }
auto device() -> lt::renderer::IDevice &
{
}
[[nodiscard]] auto has_any_messages() const -> bool [[nodiscard]] auto has_any_messages() const -> bool
{ {
return m_user_data->m_has_any_messages; 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 application_version = VK_MAKE_VERSION(1, 0, 0);
constexpr auto engine_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 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_physical_device_name = VK_MAX_PHYSICAL_DEVICE_NAME_SIZE;
constexpr auto max_memory_types = VK_MAX_MEMORY_TYPES; 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 swapchain = VK_KHR_SWAPCHAIN_EXTENSION_NAME;
constexpr auto dynamic_rendering = VK_KHR_DYNAMIC_RENDERING_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 }; // namespace device_extension_names
@ -1170,12 +1165,16 @@ class Device
{ {
public: public:
friend class Queue; friend class Queue;
friend class Memory;
friend class Buffer;
friend class Swapchain; friend class Swapchain;
friend class Image; friend class Image;
friend class ImageView; friend class ImageView;
friend class Pipeline; friend class Pipeline;
friend class Semaphore; friend class Semaphore;
friend class Fence; friend class Fence;
friend class ShaderModule;
friend class DescriptorSetLayout;
struct CreateInfo struct CreateInfo
{ {
@ -1435,6 +1434,11 @@ private:
class Buffer class Buffer
{ {
public: public:
friend class Device;
friend class Memory;
static constexpr auto object_type = VK_OBJECT_TYPE_BUFFER;
enum UsageFlags : VkFlags enum UsageFlags : VkFlags
{ {
transfer_src_bit = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, transfer_src_bit = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
@ -1484,6 +1488,8 @@ public:
SharingMode sharing_mode; SharingMode sharing_mode;
std::vector<uint32_t> queue_family_indices; std::vector<uint32_t> queue_family_indices;
std::string_view name;
}; };
Buffer(Device &device, CreateInfo info); Buffer(Device &device, CreateInfo info);
@ -1518,6 +1524,8 @@ public:
friend class Swapchain; friend class Swapchain;
friend class ImageView;
static constexpr auto object_type = VK_OBJECT_TYPE_IMAGE_VIEW; static constexpr auto object_type = VK_OBJECT_TYPE_IMAGE_VIEW;
enum AspectFlags : VkFlags enum AspectFlags : VkFlags
@ -1649,7 +1657,7 @@ private:
return m_image; return m_image;
} }
VkDevice m_device; memory::NullOnMove<VkDevice> m_device;
VkImage m_image; VkImage m_image;
}; };
@ -1694,7 +1702,7 @@ public:
Image::Range range; Image::Range range;
std::string_view debug_name; std::string_view name;
}; };
ImageView() = default; ImageView() = default;
@ -1709,10 +1717,7 @@ public:
auto operator=(const ImageView &) -> ImageView & = delete; auto operator=(const ImageView &) -> ImageView & = delete;
~ImageView() ~ImageView();
{
// WIP;
}
private: private:
[[nodiscard]] auto get_vk_handle() -> VkImageView [[nodiscard]] auto get_vk_handle() -> VkImageView
@ -1720,7 +1725,7 @@ private:
return m_image_view; return m_image_view;
} }
VkDevice m_device; memory::NullOnMove<VkDevice> m_device;
VkImageView m_image_view; VkImageView m_image_view;
}; };
@ -1728,24 +1733,23 @@ private:
class ShaderModule class ShaderModule
{ {
public: public:
friend class Device;
friend class Pipeline; friend class Pipeline;
static constexpr auto object_type = VK_OBJECT_TYPE_SHADER_MODULE;
struct CreateInfo struct CreateInfo
{ {
std::vector<std::byte> code; std::vector<std::byte> code;
std::string_view name;
}; };
ShaderModule() = default; ShaderModule() = default;
ShaderModule(Device &device, CreateInfo info) ShaderModule(Device &device, CreateInfo info);
{
// WIP
}
~ShaderModule() ~ShaderModule();
{
// WIP
}
ShaderModule(ShaderModule &&) = default; ShaderModule(ShaderModule &&) = default;
@ -1841,14 +1845,13 @@ public:
Flags flags; Flags flags;
std::vector<Binding> bindings; std::vector<Binding> bindings;
std::string_view name;
}; };
DescriptorSetLayout() = default; DescriptorSetLayout() = default;
DescriptorSetLayout(Device &device, CreateInfo info) DescriptorSetLayout(Device &device, CreateInfo info);
{
// WIP
}
DescriptorSetLayout(DescriptorSetLayout &&) = default; DescriptorSetLayout(DescriptorSetLayout &&) = default;
@ -1858,15 +1861,16 @@ public:
auto operator=(const DescriptorSetLayout &) -> DescriptorSetLayout & = delete; auto operator=(const DescriptorSetLayout &) -> DescriptorSetLayout & = delete;
~DescriptorSetLayout() ~DescriptorSetLayout();
{
// WIP
}
private: private:
auto get_vk_handle() -> VkDescriptorSetLayout
{
return m_descriptor_set_layout;
}
memory::NullOnMove<VkDevice> m_device; memory::NullOnMove<VkDevice> m_device;
VkDescriptorSetLayout m_layout; VkDescriptorSetLayout m_descriptor_set_layout;
}; };
class Pipeline class Pipeline
@ -2022,10 +2026,7 @@ public:
PipelineLayout() = default; PipelineLayout() = default;
PipelineLayout(Device &device, CreateInfo info) PipelineLayout(Device &device, CreateInfo info);
{
// WIP
}
PipelineLayout(PipelineLayout &&) = default; PipelineLayout(PipelineLayout &&) = default;
@ -2035,20 +2036,17 @@ public:
auto operator=(const PipelineLayout &) -> PipelineLayout & = delete; auto operator=(const PipelineLayout &) -> PipelineLayout & = delete;
~PipelineLayout() ~PipelineLayout();
{
// WIP
}
private: private:
[[nodiscard]] auto get_vk_handle() -> VkPipelineLayout [[nodiscard]] auto get_vk_handle() -> VkPipelineLayout
{ {
return m_layout; return m_pipeline_layout;
} }
memory::NullOnMove<VkDevice> m_device {}; memory::NullOnMove<VkDevice> m_device {};
VkPipelineLayout m_layout {}; VkPipelineLayout m_pipeline_layout {};
}; };
class CommandBuffer class CommandBuffer
@ -2352,6 +2350,8 @@ public:
PresentMode present_mode; PresentMode present_mode;
Surface::Transform pre_transform; Surface::Transform pre_transform;
std::string_view name;
}; };
Swapchain() = default; Swapchain() = default;
@ -2384,7 +2384,7 @@ private:
return &m_swapchain; return &m_swapchain;
} }
VkDevice m_device; memory::NullOnMove<VkDevice> m_device;
VkSwapchainKHR m_swapchain; VkSwapchainKHR m_swapchain;
}; };
@ -2472,6 +2472,8 @@ public:
std::size_t size; std::size_t size;
std::uint32_t memory_type_idx; std::uint32_t memory_type_idx;
std::string_view name;
}; };
Memory(Device &device, Buffer &buffer, AllocateInfo info); Memory(Device &device, Buffer &buffer, AllocateInfo info);
@ -2791,10 +2793,8 @@ void unload_library()
void load_global_functions() void load_global_functions()
{ {
constexpr auto load_fn = []<typename T>(T &pfn, const char *fn_name) { constexpr auto load_fn = []<typename T>(T &pfn, const char *fn_name) {
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) pfn = std::bit_cast<T>(api::get_instance_proc_address(nullptr, fn_name));
pfn = reinterpret_cast<T>(api::get_instance_proc_address(nullptr, fn_name));
lt::debug::ensure(pfn, "Failed to load vulkan global function: {}", 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"); 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) { 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)); 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); 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::free_memory, "vkFreeMemory");
load_fn(api::get_buffer_memory_requirements, "vkGetBufferMemoryRequirements"); load_fn(api::get_buffer_memory_requirements, "vkGetBufferMemoryRequirements");
load_fn(api::reset_command_buffer, "vkResetCommandBuffer"); load_fn(api::reset_command_buffer, "vkResetCommandBuffer");
load_fn(api::cmd_begin_rendering, "vkCmdBeginRendering"); load_fn(api::cmd_begin_rendering, "vkCmdBeginRendering");
load_fn(api::cmd_end_rendering, "vkCmdEndRendering"); load_fn(api::cmd_end_rendering, "vkCmdEndRendering");
} }
@ -2995,6 +2995,14 @@ Instance::Instance(CreateInfo info)
.pSettings = layer_settings.data(), .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 { auto vk_info = VkInstanceCreateInfo {
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pNext = &layer_settings_create_info, .pNext = &layer_settings_create_info,
@ -3003,6 +3011,7 @@ Instance::Instance(CreateInfo info)
.ppEnabledLayerNames = layer_names.data(), .ppEnabledLayerNames = layer_names.data(),
.enabledExtensionCount = static_cast<uint32_t>(extension_names.size()), .enabledExtensionCount = static_cast<uint32_t>(extension_names.size()),
.ppEnabledExtensionNames = extension_names.data(), .ppEnabledExtensionNames = extension_names.data(),
.pApplicationInfo = &app_info,
}; };
log::debug("Extension names:"); log::debug("Extension names:");
@ -3614,13 +3623,8 @@ Device::Device(const Gpu &gpu, CreateInfo info)
}; };
auto vk_descriptor_indexing_features = VkPhysicalDeviceDescriptorIndexingFeatures {}; auto vk_descriptor_indexing_features = VkPhysicalDeviceDescriptorIndexingFeatures {};
auto vk_dynamic_rendering_features = VkPhysicalDeviceDynamicRenderingFeatures {};
vk_dynamic_rendering_features = VkPhysicalDeviceDynamicRenderingFeatures { // log::debug("Dynamic rendering: {}", vk_dynamic_rendering_features.dynamicRendering);
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES,
.pNext = {},
.dynamicRendering = true,
};
log::debug("Dynamic rendering: {}", vk_dynamic_rendering_features.dynamicRendering);
// void **last_p_next = &vk_features_2.pNext; // void **last_p_next = &vk_features_2.pNext;
if (info.dynamic_rendering_features) 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;
// // last_p_next = &vk_descriptor_indexing_features.pNext; // // 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 { auto vk_info = VkDeviceCreateInfo {
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.pNext = &vk_dynamic_rendering_features, .pNext = &vk_dynamic_rendering_features,
@ -3696,6 +3706,39 @@ Device::Device(const Gpu &gpu, CreateInfo info)
.pEnabledFeatures = &physical_device_features, .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)); 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_device(device.get_vk_handle())
, m_image_view() , 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)); 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) Swapchain::Swapchain(Device &device, Surface &surface, CreateInfo info)
: m_device(device.m_device) : m_device(device.m_device.get())
, m_swapchain() , m_swapchain()
{ {
auto vk_info = VkSwapchainCreateInfoKHR { auto vk_info = VkSwapchainCreateInfoKHR {
@ -4170,11 +4239,20 @@ Swapchain::Swapchain(Device &device, Surface &surface, CreateInfo info)
.oldSwapchain = nullptr, .oldSwapchain = nullptr,
}; };
vkc(api::create_swapchain_khr(m_device, &vk_info, nullptr, &m_swapchain)); 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() Swapchain::~Swapchain()
{ {
api::destroy_swapchain_khr(m_device, m_swapchain, nullptr); if (m_device)
{
api::destroy_swapchain_khr(m_device, m_swapchain, nullptr);
}
} }
[[nodiscard]] auto Swapchain::get_images() -> std::vector<Image> [[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() Buffer::~Buffer()
{ {
api::destroy_buffer(m_device, m_buffer, nullptr);
} }
[[nodiscard]] auto Buffer::get_memory_requirements() const -> MemoryRequirements [[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() 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> [[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); 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) Pipeline::Pipeline(Device &device, PipelineLayout &layout, CreateInfo info)
: m_device(device.m_device.get()) : m_device(device.m_device.get())
@ -4381,6 +4539,16 @@ Pipeline::Pipeline(Device &device, PipelineLayout &layout, CreateInfo info)
} }
Pipeline::~Pipeline() 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 = { .extensions = {
vk::device_extension_names::swapchain, vk::device_extension_names::swapchain,
vk::device_extension_names::dynamic_rendering, 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 = {}, .features = {},

View file

@ -103,10 +103,10 @@ Swapchain::Swapchain(ISurface *surface, IGpu *gpu, IDevice *device)
.queue_family_indices = m_device->get_family_indices(), .queue_family_indices = m_device->get_family_indices(),
.present_mode = vk::Swapchain::PresentMode::immediate, .present_mode = vk::Swapchain::PresentMode::immediate,
.pre_transform = capabilities.current_transform, .pre_transform = capabilities.current_transform,
.name = std::format("swapchain {}", idx++),
} }
); );
m_resolution = capabilities.current_extent; m_resolution = capabilities.current_extent;
m_device->vk().name(m_swapchain, "swapchain {}", idx++);
m_device->vk().wait_idle(); m_device->vk().wait_idle();
m_images = m_swapchain.get_images(); m_images = m_swapchain.get_images();
@ -133,7 +133,7 @@ Swapchain::Swapchain(ISurface *surface, IGpu *gpu, IDevice *device)
.layer_count = 1u, .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; export module surface.events;
import input.codes;
import math.vec2; import math.vec2;
import std; import std;
@ -7,85 +8,85 @@ export namespace lt::surface {
class KeyPressedEvent class KeyPressedEvent
{ {
public: 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; return m_key;
} }
[[nodiscard]] auto to_string() const -> std::string [[nodiscard]] auto to_string() const -> std::string
{ {
return std::format("KeyPressed: {}", m_key); return std::format("KeyPressed: {}", std::to_underlying(m_key));
} }
private: private:
std::uint32_t m_key; Key m_key;
}; };
class KeyRepeatEvent class KeyRepeatEvent
{ {
public: 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; return m_key;
} }
[[nodiscard]] auto to_string() const -> std::string [[nodiscard]] auto to_string() const -> std::string
{ {
return std::format("KeyRepeated: {}", m_key); return std::format("KeyRepeated: {}", std::to_underlying(m_key));
} }
private: private:
std::uint32_t m_key; Key m_key;
}; };
class KeyReleasedEvent class KeyReleasedEvent
{ {
public: 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; return m_key;
} }
[[nodiscard]] auto to_string() const -> std::string [[nodiscard]] auto to_string() const -> std::string
{ {
return std::format("KeyReleased: {}", m_key); return std::format("KeyReleased: {}", std::to_underlying(m_key));
} }
private: private:
std::uint32_t m_key; Key m_key;
}; };
class KeySetCharEvent class KeySetCharEvent
{ {
public: 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; return m_character;
} }
[[nodiscard]] auto to_string() const -> std::string [[nodiscard]] auto to_string() const -> std::string
{ {
return std::format("KeyCharSet: {}", m_character); return std::format("KeyCharSet: {}", std::to_underlying(m_character));
} }
private: private:
std::uint32_t m_character; Key m_character;
}; };
class MouseMovedEvent class MouseMovedEvent
@ -145,43 +146,43 @@ private:
class ButtonPressedEvent class ButtonPressedEvent
{ {
public: 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; return m_button;
} }
[[nodiscard]] auto to_string() const -> std::string [[nodiscard]] auto to_string() const -> std::string
{ {
return std::format("ButtonPressed: {}", m_button); return std::format("ButtonPressed: {}", std::to_underlying(m_button));
} }
private: private:
std::int32_t m_button; Key m_button;
}; };
class ButtonReleasedEvent class ButtonReleasedEvent
{ {
public: 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; return m_button;
} }
[[nodiscard]] auto to_string() const -> std::string [[nodiscard]] auto to_string() const -> std::string
{ {
return std::format("ButtonReleased: {}", m_button); return std::format("ButtonReleased: {}", std::to_underlying(m_button));
} }
private: private:
std::int32_t m_button; Key m_button;
}; };
class ClosedEvent class ClosedEvent
@ -207,9 +208,7 @@ public:
[[nodiscard]] auto to_string() const -> std::string [[nodiscard]] auto to_string() const -> std::string
{ {
auto stream = std::stringstream {}; return std::format("WindowMoved: {}, {}", m_position.x, m_position.y);
stream << "WindwoMoved: " << m_position.x << ", " << m_position.y;
return stream.str();
} }
private: private:
@ -230,9 +229,7 @@ public:
[[nodiscard]] auto to_string() const -> std::string [[nodiscard]] auto to_string() const -> std::string
{ {
auto stream = std::stringstream {}; return std::format("SurfaceResized: {}, {}", m_size.x, m_size.y);
stream << "SurfaceResized: " << m_size.x << ", " << m_size.y;
return stream.str();
} }
private: private:

View file

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

View file

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