wip: convert from include style to module import style :D
Some checks reported errors
continuous-integration/drone/push Build was killed

This commit is contained in:
light7734 2025-11-15 20:59:52 +03:30
parent 90c0147660
commit 7d6ec52830
14 changed files with 331 additions and 203 deletions

View file

@ -1,12 +1,14 @@
add_library_module(NAME logger INTERFACES logger.cppm) add_module(
add_library_module(NAME bitwise INTERFACES operations.cppm) NAME logger INTERFACES logger.cppm TESTS logger.test.cpp
add_library_module(NAME env INTERFACES constants.cppm) )
add_library_module( 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 NAME memory INTERFACES null_on_move.cppm reference.cppm scope.cppm
) )
add_library_module(NAME time INTERFACES timer.cppm) add_module(NAME time INTERFACES timer.cppm)
add_library_module( add_module(
NAME NAME
test test
INTERFACES INTERFACES
@ -19,7 +21,7 @@ add_library_module(
logger logger
) )
add_library_module( add_module(
NAME NAME
lt_debug lt_debug
ROOT_DIR ROOT_DIR
@ -31,7 +33,7 @@ add_library_module(
logger logger
) )
add_library_module( add_module(
NAME NAME
math math
INTERFACES INTERFACES
@ -44,7 +46,7 @@ add_library_module(
components.cppm components.cppm
) )
add_library_module( add_module(
NAME NAME
assets assets
INTERFACES INTERFACES
@ -55,7 +57,7 @@ add_library_module(
lt_debug lt_debug
) )
add_library_module( add_module(
NAME NAME
libasset_baker libasset_baker
ROOT_DIR ROOT_DIR
@ -71,23 +73,21 @@ add_library_module(
# add_executable(asset_baker entrypoint.cpp) target_link_libraries(asset_baker # add_executable(asset_baker entrypoint.cpp) target_link_libraries(asset_baker
# PRIVATE libasset_baker) # PRIVATE libasset_baker)
add_library_module(NAME camera INTERFACES components.cppm DEPENDENCIES math) add_module(NAME camera INTERFACES components.cppm DEPENDENCIES math)
add_library_module( add_module(
NAME NAME
app app
INTERFACES INTERFACES
application.cppm application.cppm
system.cppm system.cppm
SOURCES
entrypoint.cpp
DEPENDENCIES DEPENDENCIES
memory memory
PRIVATE_DEPENDENCIES PRIVATE_DEPENDENCIES
lt_debug lt_debug
) )
add_library_module( add_module(
NAME NAME
ecs ecs
INTERFACES INTERFACES
@ -101,7 +101,7 @@ add_library_module(
) )
if(WIN32) if(WIN32)
add_library_module( add_module(
NAME NAME
surface surface
INTERFACES INTERFACES
@ -117,7 +117,6 @@ if(WIN32)
app app
math math
memory memory
tbb
PRIVATE_DEPENDENCIES PRIVATE_DEPENDENCIES
logger logger
lt_debug lt_debug
@ -125,7 +124,7 @@ if(WIN32)
) )
elseif(UNIX) elseif(UNIX)
add_library_module( add_module(
NAME NAME
surface surface
INTERFACES INTERFACES
@ -141,7 +140,6 @@ elseif(UNIX)
app app
math math
memory memory
tbb
PRIVATE_DEPENDENCIES PRIVATE_DEPENDENCIES
X11 X11
logger logger
@ -154,7 +152,7 @@ else()
endif() endif()
add_library_module( add_module(
NAME NAME
input input
INTERFACES INTERFACES
@ -168,7 +166,9 @@ add_library_module(
logger logger
) )
add_library_module( find_package(Vulkan REQUIRED)
message("Vulkan Libraries are: ${Vulkan_LIBRARIES}")
add_module(
NAME NAME
renderer renderer
INTERFACES INTERFACES
@ -195,15 +195,15 @@ add_library_module(
time time
bitwise bitwise
camera camera
${Vulkan_LIBRARIES}
Vulkan::Vulkan
PRIVATE_DEPENDENCIES PRIVATE_DEPENDENCIES
surface surface
) )
return() add_module(
add_library_module(
NAME NAME
libmirror mirror
ROOT_DIR ROOT_DIR
${CMAKE_CURRENT_SOURCE_DIR}/mirror ${CMAKE_CURRENT_SOURCE_DIR}/mirror
INTERFACES INTERFACES
@ -215,6 +215,22 @@ add_library_module(
surface surface
renderer renderer
camera camera
# TESTS
# system.test.cpp
)
add_executable(exectest ${CMAKE_CURRENT_SOURCE_DIR}/mirror/entrypoint.cpp
)
target_link_libraries(exectest PRIVATE
mirror
app
time
input
surface
renderer
camera
) )
# add_executable_module(mirror entrypoint/mirror.cpp) # add_executable_module(mirror entrypoint/mirror.cpp)

View file

@ -40,8 +40,6 @@ private:
std::vector<memory::Ref<app::ISystem>> m_systems_to_be_registered; std::vector<memory::Ref<app::ISystem>> m_systems_to_be_registered;
}; };
export extern memory::Scope<class Application> create_application();
} // namespace lt::app } // namespace lt::app
module :private; module :private;
@ -56,13 +54,11 @@ void Application::game_loop()
const auto &last_tick = system->get_last_tick_result(); const auto &last_tick = system->get_last_tick_result();
const auto now = std::chrono::steady_clock::now(); const auto now = std::chrono::steady_clock::now();
system->tick( system->tick(TickInfo {
TickInfo {
.delta_time = now - last_tick.end_time, .delta_time = now - last_tick.end_time,
.budget = std::chrono::milliseconds { 10 }, .budget = std::chrono::milliseconds { 10 },
.start_time = now, .start_time = now,
} });
);
} }
for (auto &system : m_systems_to_be_registered) for (auto &system : m_systems_to_be_registered)

View file

@ -1,31 +0,0 @@
import memory.scope;
import logger;
import app;
import std;
/** The ultimate entrypoint. */
auto main(int argc, char *argv[]) -> std::int32_t
{
try
{
std::ignore = argc;
std::ignore = argv;
auto application = lt::memory::Scope<lt::app::Application> {};
application = lt::app::create_application();
if (!application)
{
throw std::runtime_error { "Failed to create application\n" };
}
application->game_loop();
return 0;
}
catch (const std::exception &exp)
{
lt::log::critical("Terminating due to uncaught exception:");
lt::log::critical("\texception.what(): {}", exp.what());
return 1;
}
}

View file

@ -1,5 +1,5 @@
import logger; import logger;
import test; import test.test;
using ::lt::test::Case; using ::lt::test::Case;
using ::lt::test::Suite; using ::lt::test::Suite;

View file

@ -0,0 +1,34 @@
import app;
import app.system;
import std;
import logger;
import memory.scope;
import mirror.system;
import renderer.factory;
/** The ultimate entrypoint. */
auto main(int argc, char *argv[]) -> std::int32_t
{
try
{
std::ignore = argc;
std::ignore = argv;
auto application = lt::memory::create_scope<lt::Mirror>();
if (!application)
{
throw std::runtime_error { "Failed to create application\n" };
}
application->game_loop();
return 0;
}
catch (const std::exception &exp)
{
lt::log::critical("Terminating due to uncaught exception:");
lt::log::critical("\texception.what(): {}", exp.what());
return 1;
}
}

View file

@ -37,7 +37,7 @@ void renderer_callback(
std::ignore = message_type; std::ignore = message_type;
std::ignore = user_data; std::ignore = user_data;
log::debug("RENDERER CALLBACK: {}", data.message); log::debug("RENDERER CALLBACK: {}", std::string { data.message });
} }
class MirrorSystem: public lt::app::ISystem class MirrorSystem: public lt::app::ISystem
@ -135,7 +135,7 @@ private:
app::TickResult m_last_tick_result {}; app::TickResult m_last_tick_result {};
}; };
class Mirror: public app::Application export class Mirror: public app::Application
{ {
public: public:
Mirror() Mirror()
@ -176,41 +176,31 @@ public:
); );
auto &input = m_editor_registry->add<InputComponent>(m_window, {}); auto &input = m_editor_registry->add<InputComponent>(m_window, {});
auto quit_action_key = input.add_action( auto quit_action_key = input.add_action(input::InputAction {
input::InputAction {
.name = "quit", .name = "quit",
.trigger = input::Trigger { .mapped_keycode = Key::Q }, .trigger = input::Trigger { .mapped_keycode = Key::Q },
} });
);
auto debug_action_keys = std::array<std::size_t, 4ul> {}; auto debug_action_keys = std::array<std::size_t, 4ul> {};
debug_action_keys[0] = input.add_action( debug_action_keys[0] = input.add_action(input::InputAction {
input::InputAction {
.name = "debug_1", .name = "debug_1",
.trigger = input::Trigger { .mapped_keycode = Key::D1 }, .trigger = input::Trigger { .mapped_keycode = Key::D1 },
} });
);
debug_action_keys[1] = input.add_action( debug_action_keys[1] = input.add_action(input::InputAction {
input::InputAction {
.name = "debug_2", .name = "debug_2",
.trigger = input::Trigger { .mapped_keycode = Key::D2 }, .trigger = input::Trigger { .mapped_keycode = Key::D2 },
} });
);
debug_action_keys[2] = input.add_action( debug_action_keys[2] = input.add_action(input::InputAction {
input::InputAction {
.name = "debug_3", .name = "debug_3",
.trigger = input::Trigger { .mapped_keycode = Key::D3 }, .trigger = input::Trigger { .mapped_keycode = Key::D3 },
} });
);
debug_action_keys[3] = input.add_action( debug_action_keys[3] = input.add_action(input::InputAction {
input::InputAction {
.name = "debug_4", .name = "debug_4",
.trigger = input::Trigger { .mapped_keycode = Key::D4 }, .trigger = input::Trigger { .mapped_keycode = Key::D4 },
} });
);
m_input_system = memory::create_ref<input::System>(m_editor_registry); m_input_system = memory::create_ref<input::System>(m_editor_registry);
m_mirror_system = memory::create_ref<MirrorSystem>( m_mirror_system = memory::create_ref<MirrorSystem>(
@ -294,9 +284,4 @@ private:
lt::ecs::EntityId m_sprite_id = lt::ecs::null_entity; lt::ecs::EntityId m_sprite_id = lt::ecs::null_entity;
}; };
auto app::create_application() -> memory::Scope<app::Application>
{
return memory::create_scope<Mirror>();
}
} // namespace lt } // namespace lt

View file

View file

@ -1,19 +1,19 @@
export module renderer.factory; export module renderer.factory;
import renderer.frontend; export import renderer.frontend;
import assets.shader; export import assets.shader;
import renderer.vk.device; export import renderer.vk.device;
import renderer.vk.pass; export import renderer.vk.pass;
import renderer.vk.instance; export import renderer.vk.instance;
import renderer.vk.swapchain; export import renderer.vk.swapchain;
import renderer.vk.renderer; export import renderer.vk.renderer;
import renderer.vk.buffer; export import renderer.vk.buffer;
import renderer.vk.gpu; export import renderer.vk.gpu;
import renderer.vk.debugger; export import renderer.vk.debugger;
import renderer.vk.surface; export import renderer.vk.surface;
import memory.scope; export import memory.scope;
import debug.assertions; export import debug.assertions;
import ecs.entity; export import ecs.entity;
import std; export import std;
export namespace lt::renderer { export namespace lt::renderer {
@ -66,6 +66,8 @@ using namespace lt::renderer;
case Api::metal: case Api::metal:
case Api::direct_x: throw std::runtime_error { "Invalid API" }; case Api::direct_x: throw std::runtime_error { "Invalid API" };
} }
std::unreachable();
} }
[[nodiscard]] auto create_surface( [[nodiscard]] auto create_surface(
@ -83,6 +85,8 @@ using namespace lt::renderer;
case Api::metal: case Api::metal:
case Api::direct_x: throw std::runtime_error { "Invalid API" }; case Api::direct_x: throw std::runtime_error { "Invalid API" };
} }
std::unreachable();
} }
[[nodiscard]] auto create_gpu(Api target_api, IInstance *instance) -> memory::Scope<IGpu> [[nodiscard]] auto create_gpu(Api target_api, IInstance *instance) -> memory::Scope<IGpu>
@ -94,6 +98,8 @@ using namespace lt::renderer;
case Api::metal: case Api::metal:
case Api::direct_x: throw std::runtime_error { "Invalid API" }; case Api::direct_x: throw std::runtime_error { "Invalid API" };
} }
std::unreachable();
} }
[[nodiscard]] auto create_device(Api target_api, IGpu *gpu, ISurface *surface) [[nodiscard]] auto create_device(Api target_api, IGpu *gpu, ISurface *surface)
@ -109,6 +115,8 @@ using namespace lt::renderer;
case Api::metal: case Api::metal:
case Api::direct_x: throw std::runtime_error { "Invalid API" }; case Api::direct_x: throw std::runtime_error { "Invalid API" };
} }
std::unreachable();
} }
[[nodiscard]] auto create_swapchain(Api target_api, ISurface *surface, IGpu *gpu, IDevice *device) [[nodiscard]] auto create_swapchain(Api target_api, ISurface *surface, IGpu *gpu, IDevice *device)
@ -121,6 +129,8 @@ using namespace lt::renderer;
case Api::metal: case Api::metal:
case Api::direct_x: throw std::runtime_error { "Invalid API" }; case Api::direct_x: throw std::runtime_error { "Invalid API" };
} }
std::unreachable();
} }
[[nodiscard]] auto create_buffer( [[nodiscard]] auto create_buffer(
@ -141,6 +151,8 @@ using namespace lt::renderer;
case Api::metal: case Api::metal:
case Api::direct_x: throw std::runtime_error { "Invalid API" }; case Api::direct_x: throw std::runtime_error { "Invalid API" };
} }
std::unreachable();
} }
@ -161,6 +173,8 @@ using namespace lt::renderer;
case Api::metal: case Api::metal:
case Api::direct_x: throw std::runtime_error { "Invalid API" }; case Api::direct_x: throw std::runtime_error { "Invalid API" };
} }
std::unreachable();
} }
[[nodiscard]] auto create_renderer( [[nodiscard]] auto create_renderer(
@ -196,6 +210,8 @@ using namespace lt::renderer;
case Api::metal: case Api::metal:
case Api::direct_x: throw std::runtime_error { "Invalid API" }; case Api::direct_x: throw std::runtime_error { "Invalid API" };
} }
std::unreachable();
} }
[[nodiscard]] auto create_debugger(Api target_api, IInstance *instance, IDebugger::CreateInfo info) [[nodiscard]] auto create_debugger(Api target_api, IInstance *instance, IDebugger::CreateInfo info)
@ -220,4 +236,6 @@ using namespace lt::renderer;
case Api::metal: case Api::metal:
case Api::direct_x: throw std::runtime_error { "Invalid API" }; case Api::direct_x: throw std::runtime_error { "Invalid API" };
} }
std::unreachable();
} }

View file

@ -8,16 +8,33 @@
* In the long run, it should pay off... * In the long run, it should pay off...
*/ */
module; module;
#define VK_NO_PROTOTYPES #define VK_NO_PROTOTYPES
#if defined(LIGHT_PLATFORM_LINUX)
#define VK_USE_PLATFORM_XLIB_KHR #define VK_USE_PLATFORM_XLIB_KHR
#elif defined(LIGHT_PLATFORM_WINDOWS)
#define VK_USE_PLATFORM_WIN32_KHR
#else
#error "Unsupported platform"
#endif
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
#include <vulkan/vulkan_xlib.h>
#if defined(_WIN32)
#error "Unsupported platform" #if defined(LIGHT_PLATFORM_LINUX)
#elif defined(__unix__) #include <vulkan/vulkan_xlib.h>
#endif
#if defined(LIGHT_PLATFORM_WINDOWS)
#include <Windows.h>
#undef max
#undef min
#undef MIN
#undef MAX
#elif defined(LIGHT_PLATFORM_LINUX)
#include <dlfcn.h> #include <dlfcn.h>
#else
#error "Unsupported platform"
#endif #endif
export module renderer.vk.api_wrapper; export module renderer.vk.api_wrapper;
@ -65,7 +82,14 @@ namespace instance_extension_names {
constexpr auto debug_utils = VK_EXT_DEBUG_UTILS_EXTENSION_NAME; constexpr auto debug_utils = VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
constexpr auto surface = VK_KHR_SURFACE_EXTENSION_NAME; constexpr auto surface = VK_KHR_SURFACE_EXTENSION_NAME;
constexpr auto xlib_surface = VK_KHR_XLIB_SURFACE_EXTENSION_NAME; #if defined(LIGHT_PLATFORM_LINUX)
constexpr auto platform_surface = VK_KHR_XLIB_SURFACE_EXTENSION_NAME;
#elif defined(LIGHT_PLATFORM_WINDOWS)
constexpr auto platform_surface = VK_KHR_WIN32_SURFACE_EXTENSION_NAME;
#else
#error "Unsupported platform"
#endif
constexpr auto physical_device_properties_2 constexpr auto physical_device_properties_2
= VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; = VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME;
@ -718,7 +742,7 @@ public:
} }
private: private:
[[nodiscard]] auto get_vk_handle() -> VkInstance [[nodiscard]] auto get_vk_handle() const -> VkInstance
{ {
return m_instance; return m_instance;
} }
@ -754,13 +778,6 @@ public:
ColorSpace color_space; ColorSpace color_space;
}; };
struct XlibCreateInfo
{
Display *display;
Window window;
};
struct Capabilities struct Capabilities
{ {
std::uint32_t min_image_count; std::uint32_t min_image_count;
@ -784,9 +801,22 @@ public:
VkImageUsageFlags supported_usage_flags; VkImageUsageFlags supported_usage_flags;
}; };
struct CreateInfo
{
#if defined(LIGHT_PLATFORM_LINUX)
Display *display;
Window window;
#elif defined(LIGHT_PLATFORM_WINDOWS)
HWND window;
#else
#error "Unsupported platform"
#endif
};
Surface() = default; Surface() = default;
Surface(const Instance &instance, const XlibCreateInfo &info); Surface(const Instance &instance, const CreateInfo &info);
Surface(Surface &&) = default; Surface(Surface &&) = default;
@ -1242,10 +1272,8 @@ public:
/** de-allocation functions */ /** de-allocation functions */
void free_memory(VkDeviceMemory memory) const; void free_memory(VkDeviceMemory memory) const;
void free_descriptor_set( void free_descriptor_set(VkDescriptorPool descriptor_pool, VkDescriptorSet descriptor_set)
VkDescriptorPool descriptor_pool, const;
VkDescriptorSet descriptor_set
) const;
/** destroy functions */ /** destroy functions */
void destroy_swapchain(VkSwapchainKHR swapchain) const; void destroy_swapchain(VkSwapchainKHR swapchain) const;
@ -2613,7 +2641,14 @@ PFN_vkResetCommandBuffer reset_command_buffer {};
PFN_vkCmdBeginRendering cmd_begin_rendering {}; PFN_vkCmdBeginRendering cmd_begin_rendering {};
PFN_vkCmdEndRendering cmd_end_rendering {}; PFN_vkCmdEndRendering cmd_end_rendering {};
#if defined(LIGHT_PLATFORM_LINUX)
PFN_vkCreateXlibSurfaceKHR create_xlib_surface_khr {}; PFN_vkCreateXlibSurfaceKHR create_xlib_surface_khr {};
#elif defined(LIGHT_PLATFORM_WINDOWS)
PFN_vkCreateWin32SurfaceKHR create_win32_surface_khr {};
#else
#error "Unsupported platform"
#endif
PFN_vkDestroySurfaceKHR destroy_surface_khr {}; PFN_vkDestroySurfaceKHR destroy_surface_khr {};
} // namespace api } // namespace api
@ -2621,13 +2656,14 @@ void *library = nullptr; // NOLINT
void load_library() void load_library()
{ {
#if defined(LIGHT_PLATFORM_LINUX)
constexpr auto runtime_loader_flags = RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE; constexpr auto runtime_loader_flags = RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE;
library = dlopen("libvulkan.so.1", runtime_loader_flags); library = dlopen("libvulkan.so.1", runtime_loader_flags);
if (!library) if (!library)
{ {
library = dlopen("libvulkan.so", runtime_loader_flags); library = dlopen("libvulkan.so", runtime_loader_flags);
} }
lt::debug::ensure(library, "Failed to dlopen vulkan library"); lt::debug::ensure(library, "Failed to dlopen the libvulkan.so");
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
api::get_instance_proc_address = reinterpret_cast<PFN_vkGetInstanceProcAddr>( api::get_instance_proc_address = reinterpret_cast<PFN_vkGetInstanceProcAddr>(
@ -2637,6 +2673,21 @@ void load_library()
api::get_instance_proc_address, api::get_instance_proc_address,
"Failed to load vulkan function: vkGetInstanceProcAddr" "Failed to load vulkan function: vkGetInstanceProcAddr"
); );
#elif defined(LIGHT_PLATFORM_WINDOWS)
auto library = LoadLibraryA("vulkan-1.dll");
lt::debug::ensure(library, "Failed to LoadLibraryA the vulkan-1.dll");
api::get_instance_proc_address = std::bit_cast<PFN_vkGetInstanceProcAddr>(
GetProcAddress(library, "vkGetInstanceProcAddr")
);
lt::debug::ensure(
api::get_instance_proc_address,
"Failed to get vkGetInstanceProcAddr function pointer from vulkan-1.dll"
);
#else
#error "Unsupported platform"
#endif
} }
@ -2708,7 +2759,14 @@ void Instance::load_functions()
"vkGetPhysicalDeviceSurfaceCapabilitiesKHR" "vkGetPhysicalDeviceSurfaceCapabilitiesKHR"
); );
load_fn(api::get_physical_device_surface_formats, "vkGetPhysicalDeviceSurfaceFormatsKHR"); load_fn(api::get_physical_device_surface_formats, "vkGetPhysicalDeviceSurfaceFormatsKHR");
#if defined(LIGHT_PLATFORM_LINUX)
load_fn(api::create_xlib_surface_khr, "vkCreateXlibSurfaceKHR"); load_fn(api::create_xlib_surface_khr, "vkCreateXlibSurfaceKHR");
#elif defined(LIGHT_PLATFORM_WINDOWS)
load_fn(api::create_win32_surface_khr, "vkCreateWin32SurfaceKHR");
#else
#error "Unsupported platform"
#endif
load_fn(api::destroy_surface_khr, "vkDestroySurfaceKHR"); load_fn(api::destroy_surface_khr, "vkDestroySurfaceKHR");
} }
@ -2805,15 +2863,13 @@ Instance::Instance(CreateInfo info)
layer_names.emplace_back(layer.name.c_str()); layer_names.emplace_back(layer.name.c_str());
for (const auto &setting : layer.settings) for (const auto &setting : layer.settings)
{ {
layer_settings.emplace_back( layer_settings.emplace_back(VkLayerSettingEXT {
VkLayerSettingEXT {
.pLayerName = layer.name.c_str(), .pLayerName = layer.name.c_str(),
.pSettingName = setting.name.c_str(), .pSettingName = setting.name.c_str(),
.type = std::visit(layer_setting_type_visitor, setting.values), .type = std::visit(layer_setting_type_visitor, setting.values),
.valueCount = 1u, .valueCount = 1u,
.pValues = std::visit(layer_setting_value_visitor, setting.values), .pValues = std::visit(layer_setting_value_visitor, setting.values),
} });
);
} }
} }
@ -2837,9 +2893,9 @@ Instance::Instance(CreateInfo info)
debug::ensure(m_instance, "Failed to create vulkan instance"); debug::ensure(m_instance, "Failed to create vulkan instance");
} }
Surface::Surface(const Instance &instance, const XlibCreateInfo &info) Surface::Surface(const Instance &instance, const CreateInfo &info): m_instance(instance.m_instance)
: m_instance(instance.m_instance)
{ {
#if defined(LIGHT_PLATFORM_LINUX)
const auto vk_info = VkXlibSurfaceCreateInfoKHR { const auto vk_info = VkXlibSurfaceCreateInfoKHR {
.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, .sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR,
.pNext = {}, .pNext = {},
@ -2848,7 +2904,22 @@ Surface::Surface(const Instance &instance, const XlibCreateInfo &info)
.window = info.window, .window = info.window,
}; };
vkc(api::create_xlib_surface_khr(instance.m_instance, &vk_info, nullptr, &m_surface)); vkc(api::create_xlib_surface_khr(instance.get_vk_handle(), &vk_info, nullptr, &m_surface));
#elif defined(LIGHT_PLATFORM_WINDOWS)
const auto vk_info = VkWin32SurfaceCreateInfoKHR {
.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
.pNext = {},
.flags = {},
.hinstance = GetModuleHandle(nullptr),
.hwnd = info.window,
};
vkc(api::create_win32_surface_khr(instance.get_vk_handle(), &vk_info, nullptr, &m_surface));
#else
#error "Unsupported platform"
#endif
} }
Surface::~Surface() Surface::~Surface()
@ -3274,12 +3345,10 @@ Surface::~Surface()
auto formats = std::vector<Surface::Format> {}; auto formats = std::vector<Surface::Format> {};
for (auto &vk_format : vk_formats) for (auto &vk_format : vk_formats)
{ {
formats.emplace_back( formats.emplace_back(Surface::Format {
Surface::Format {
.format = static_cast<Format>(vk_format.format), .format = static_cast<Format>(vk_format.format),
.color_space = static_cast<ColorSpace>(vk_format.colorSpace), .color_space = static_cast<ColorSpace>(vk_format.colorSpace),
} });
);
} }
return formats; return formats;
@ -3336,14 +3405,12 @@ Device::Device(const Gpu &gpu, CreateInfo info)
auto vk_queue_infos = std::vector<VkDeviceQueueCreateInfo> {}; auto vk_queue_infos = std::vector<VkDeviceQueueCreateInfo> {};
for (auto queue_family : info.queue_indices) for (auto queue_family : info.queue_indices)
{ {
vk_queue_infos.emplace_back( vk_queue_infos.emplace_back(VkDeviceQueueCreateInfo {
VkDeviceQueueCreateInfo {
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
.queueFamilyIndex = queue_family, .queueFamilyIndex = queue_family,
.queueCount = 1u, .queueCount = 1u,
.pQueuePriorities = &priorities, .pQueuePriorities = &priorities,
} });
);
} }
auto vk_extension_names = std::vector<const char *>(info.extensions.size()); auto vk_extension_names = std::vector<const char *>(info.extensions.size());
@ -3736,10 +3803,8 @@ void Device::free_memory(VkDeviceMemory memory) const
api::free_memory(m_device, memory, nullptr); api::free_memory(m_device, memory, nullptr);
} }
void Device::free_descriptor_set( void Device::free_descriptor_set(VkDescriptorPool descriptor_pool, VkDescriptorSet descriptor_set)
VkDescriptorPool descriptor_pool, const
VkDescriptorSet descriptor_set
) const
{ {
vkc(api::free_descriptor_sets(m_device, descriptor_pool, 1, &descriptor_set)); vkc(api::free_descriptor_sets(m_device, descriptor_pool, 1, &descriptor_set));
} }
@ -4037,14 +4102,12 @@ Pipeline::Pipeline(Device &device, PipelineLayout &layout, CreateInfo info)
auto shader_stages = std::vector<VkPipelineShaderStageCreateInfo> {}; auto shader_stages = std::vector<VkPipelineShaderStageCreateInfo> {};
for (auto &[shader, stage] : info.shaders) for (auto &[shader, stage] : info.shaders)
{ {
shader_stages.emplace_back( shader_stages.emplace_back(VkPipelineShaderStageCreateInfo {
VkPipelineShaderStageCreateInfo {
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.stage = static_cast<VkShaderStageFlagBits>(stage), .stage = static_cast<VkShaderStageFlagBits>(stage),
.module = shader.get_vk_handle(), .module = shader.get_vk_handle(),
.pName = "main", .pName = "main",
} });
);
} }
auto dynamic_states = std::array<VkDynamicState, 2> { auto dynamic_states = std::array<VkDynamicState, 2> {
@ -4127,8 +4190,7 @@ Pipeline::Pipeline(Device &device, PipelineLayout &layout, CreateInfo info)
.colorAttachmentCount = static_cast<uint32_t>(color_attachment_formats.size()), .colorAttachmentCount = static_cast<uint32_t>(color_attachment_formats.size()),
.pColorAttachmentFormats = std::bit_cast<VkFormat *>(color_attachment_formats.data()), .pColorAttachmentFormats = std::bit_cast<VkFormat *>(color_attachment_formats.data()),
.depthAttachmentFormat = info.attachment_state.depth_attachment ? .depthAttachmentFormat = info.attachment_state.depth_attachment ?
static_cast<VkFormat>( static_cast<VkFormat>(*info.attachment_state.depth_attachment
*info.attachment_state.depth_attachment
) : ) :
VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED,

View file

@ -34,10 +34,8 @@ private:
[[nodiscard]] auto to_native_memory_properties(Usage usage) const -> vk::Memory::PropertyFlags; [[nodiscard]] auto to_native_memory_properties(Usage usage) const -> vk::Memory::PropertyFlags;
[[nodiscard]] auto has_correct_memory_type_bit( [[nodiscard]] auto has_correct_memory_type_bit(std::uint32_t type_bits, std::uint32_t type_idx)
std::uint32_t type_bits, const -> bool;
std::uint32_t type_idx
) const -> bool;
[[nodiscard]] auto has_required_memory_properties( [[nodiscard]] auto has_required_memory_properties(
std::uint32_t required_properties, std::uint32_t required_properties,
@ -123,13 +121,12 @@ void Buffer::unmap() /* override */
switch (usage) switch (usage)
{ {
case Usage::vertex: return static_cast<Flags>(vertex_buffer_bit | transfer_dst_bit); case Usage::vertex: return static_cast<Flags>(vertex_buffer_bit | transfer_dst_bit);
case Usage::index: return static_cast<Flags>(index_buffer_bit | transfer_dst_bit); case Usage::index: return static_cast<Flags>(index_buffer_bit | transfer_dst_bit);
case Usage::storage: return static_cast<Flags>(transfer_dst_bit | storage_buffer_bit); case Usage::storage: return static_cast<Flags>(transfer_dst_bit | storage_buffer_bit);
case Usage::staging: return transfer_src_bit; case Usage::staging: return transfer_src_bit;
} }
std::unreachable();
} }
[[nodiscard]] auto Buffer::to_native_memory_properties(Usage usage) const [[nodiscard]] auto Buffer::to_native_memory_properties(Usage usage) const
@ -142,7 +139,6 @@ void Buffer::unmap() /* override */
case Usage::vertex: case Usage::vertex:
case Usage::index: case Usage::index:
case Usage::storage: return device_local_bit; case Usage::storage: return device_local_bit;
case Usage::staging: return static_cast<Flags>(host_visible_bit | host_coherent_bit); case Usage::staging: return static_cast<Flags>(host_visible_bit | host_coherent_bit);
} }

View file

@ -101,7 +101,7 @@ Instance::Instance()
.extensions = { .extensions = {
vk::instance_extension_names::debug_utils, vk::instance_extension_names::debug_utils,
vk::instance_extension_names::surface, vk::instance_extension_names::surface,
vk::instance_extension_names::xlib_surface, vk::instance_extension_names::platform_surface,
vk::instance_extension_names::physical_device_properties_2, vk::instance_extension_names::physical_device_properties_2,
}, },
} }

View file

@ -39,6 +39,8 @@ Surface::Surface(IInstance *instance, const ecs::Entity &surface_entity)
{ {
const auto &component = surface_entity.get<surface::SurfaceComponent>(); const auto &component = surface_entity.get<surface::SurfaceComponent>();
#if defined(LIGHT_PLATFORM_LINUX)
debug::ensure( debug::ensure(
component.get_native_data().display, component.get_native_data().display,
"Failed to initialize vk::Surface: null x-display" "Failed to initialize vk::Surface: null x-display"
@ -50,11 +52,29 @@ Surface::Surface(IInstance *instance, const ecs::Entity &surface_entity)
m_surface = vk::Surface( m_surface = vk::Surface(
static_cast<Instance *>(instance)->vk(), static_cast<Instance *>(instance)->vk(),
vk::Surface::XlibCreateInfo { vk::Surface::CreateInfo {
.display = component.get_native_data().display, .display = component.get_native_data().display,
.window = component.get_native_data().window, .window = component.get_native_data().window,
} }
); );
#elif defined(LIGHT_PLATFORM_WINDOWS)
debug::ensure(
component.get_native_data().window,
"Failed to initialize vk::Surface: null win32 window handle"
);
m_surface = vk::Surface(
static_cast<Instance *>(instance)->vk(),
vk::Surface::CreateInfo {
.window = component.get_native_data().window,
}
);
#else
#error "Unsupported platform"
#endif
} }
[[nodiscard]] auto Surface::get_framebuffer_size() const -> math::uvec2 [[nodiscard]] auto Surface::get_framebuffer_size() const -> math::uvec2

View file

@ -290,6 +290,8 @@ auto Registry::run_all_impl() -> std::int32_t
return 0; return 0;
} }
} }
std::unreachable();
} }
void Registry::print_options() void Registry::print_options()

View file

@ -1,9 +1,9 @@
function(add_library_module) function(add_module)
cmake_parse_arguments( cmake_parse_arguments(
ARGS ARGS
"" ""
"NAME" "NAME"
"INTERFACES;ROOT_DIR;PRIVATE_INTERFACES;SOURCES;DEPENDENCIES;PRIVATE_DEPENDENCIES" "INTERFACES;ROOT_DIR;SOURCES;DEPENDENCIES;PRIVATE_DEPENDENCIES;TESTS;ENTRYPOINT"
${ARGN} ${ARGN}
) )
@ -11,19 +11,40 @@ function(add_library_module)
message(FATAL_ERROR "You must provide a name") message(FATAL_ERROR "You must provide a name")
endif() endif()
add_library(${ARGS_NAME}) set(target_library_name ${ARGS_NAME})
set(target_executable_name ${ARGS_NAME})
set(module_directory "${CMAKE_CURRENT_SOURCE_DIR}/${ARGS_NAME}") set(module_directory "${CMAKE_CURRENT_SOURCE_DIR}/${target_library_name}")
if(ARGS_ROOT_DIR) if(ARGS_ROOT_DIR)
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.
# 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})
endif()
add_library(${target_library_name})
if(ARGS_SOURCES) if(ARGS_SOURCES)
set(files) set(files)
foreach(file ${ARGS_SOURCES}) foreach(file ${ARGS_SOURCES})
list(APPEND files "${module_directory}/${file}") list(APPEND files "${module_directory}/${file}")
endforeach() endforeach()
target_sources(${ARGS_NAME} PRIVATE ${files})
target_sources(${target_library_name} PRIVATE ${files})
endif()
if(ARGS_PUBLIC_SOURECS)
set(files)
foreach(file ${ARGS_PUBLIC_SOURECS})
list(APPEND files "${module_directory}/${file}")
endforeach()
target_sources(${target_library_name} PUBLIC ${files})
endif() endif()
if(ARGS_INTERFACES) if(ARGS_INTERFACES)
@ -32,24 +53,33 @@ function(add_library_module)
list(APPEND files "${module_directory}/${file}") list(APPEND files "${module_directory}/${file}")
endforeach() endforeach()
target_sources( target_sources(
${ARGS_NAME} PUBLIC FILE_SET public_cxx_modules TYPE CXX_MODULES ${target_library_name} PUBLIC FILE_SET public_cxx_modules TYPE CXX_MODULES
FILES ${files} FILES ${files}
) )
endif() endif()
if(ARGS_PRIVATE_INTERFACES) target_link_libraries(${target_library_name} PUBLIC ${ARGS_DEPENDENCIES})
set(files) target_link_libraries(${target_library_name} PRIVATE ${ARGS_PRIVATE_DEPENDENCIES})
foreach(file ${ARGS_PRIVATE_INTERFACES})
list(APPEND files "${module_directory}/${file}") if(ARGS_TESTS)
message("ADDING TESTS!!!")
set(test_files)
foreach(test_file ${ARGS_TESTS})
list(APPEND test_files "${module_directory}/${test_file}")
endforeach() endforeach()
target_sources(
${ARGS_NAME} PRIVATE FILE_SET private_cxx_modules TYPE CXX_MODULES add_executable("${target_library_name}_tests" ${test_files})
FILES ${files} target_link_libraries(
"${target_library_name}_tests"
PRIVATE ${target_lib_name}
#
test
) )
endif() endif()
target_link_libraries(${ARGS_NAME} PUBLIC ${ARGS_DEPENDENCIES}) if(ARGS_ENTRYPOINT)
target_link_libraries(${ARGS_NAME} PRIVATE ${ARGS_PRIVATE_DEPENDENCIES}) target_link_libraries(${target_executable_name} PRIVATE ${target_library_name})
endif()
endfunction() endfunction()
function(add_executable_module exename) function(add_executable_module exename)